Lots of renaming
git-svn-id: svn://svn.cc65.org/cc65/trunk@768 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
9ce1e413e4
commit
f42300ef62
14 changed files with 474 additions and 454 deletions
|
@ -47,7 +47,7 @@
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
|||
CodeMark GetCodePos (void)
|
||||
/* Get a marker pointing to the current output position */
|
||||
{
|
||||
return GetCodeEntryCount (CS->Code);
|
||||
return CS_GetEntryCount (CS->Code);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ CodeMark GetCodePos (void)
|
|||
void RemoveCode (CodeMark M)
|
||||
/* Remove all code after the given code marker */
|
||||
{
|
||||
DelCodeSegAfter (CS->Code, M);
|
||||
CS_DelCodeAfter (CS->Code, M);
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +75,7 @@ void WriteOutput (FILE* F)
|
|||
SymEntry* Entry;
|
||||
|
||||
/* Output the global data segment */
|
||||
CHECK (GetCodeEntryCount (CS->Code) == 0);
|
||||
CHECK (CS_GetEntryCount (CS->Code) == 0);
|
||||
OutputSegments (CS, F);
|
||||
|
||||
/* Output all global or referenced functions */
|
||||
|
@ -83,14 +83,14 @@ void WriteOutput (FILE* F)
|
|||
Entry = SymTab->SymHead;
|
||||
while (Entry) {
|
||||
if (IsTypeFunc (Entry->Type) &&
|
||||
(Entry->Flags & SC_DEF) != 0 &&
|
||||
(Entry->Flags & (SC_REF | SC_EXTERN)) != 0) {
|
||||
/* Function which is defined and referenced or extern */
|
||||
MergeCodeLabels (Entry->V.F.Seg->Code);
|
||||
RunOpt (Entry->V.F.Seg->Code);
|
||||
OutputSegments (Entry->V.F.Seg, F);
|
||||
}
|
||||
Entry = Entry->NextSym;
|
||||
(Entry->Flags & SC_DEF) != 0 &&
|
||||
(Entry->Flags & (SC_REF | SC_EXTERN)) != 0) {
|
||||
/* Function which is defined and referenced or extern */
|
||||
CS_MergeLabels (Entry->V.F.Seg->Code);
|
||||
RunOpt (Entry->V.F.Seg->Code);
|
||||
OutputSegments (Entry->V.F.Seg, F);
|
||||
}
|
||||
Entry = Entry->NextSym;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ void FreeCodeEntry (CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
void ReplaceOPC (CodeEntry* E, opc_t OPC)
|
||||
void CE_ReplaceOPC (CodeEntry* E, opc_t OPC)
|
||||
/* Replace the opcode of the instruction. This will also replace related info,
|
||||
* Size, Use and Chg, but it will NOT update any arguments or labels.
|
||||
*/
|
||||
|
@ -236,7 +236,7 @@ int CodeEntriesAreEqual (const CodeEntry* E1, const CodeEntry* E2)
|
|||
|
||||
|
||||
|
||||
void AttachCodeLabel (CodeEntry* E, CodeLabel* L)
|
||||
void CE_AttachLabel (CodeEntry* E, CodeLabel* L)
|
||||
/* Attach the label to the entry */
|
||||
{
|
||||
/* Add it to the entries label list */
|
||||
|
@ -248,7 +248,7 @@ void AttachCodeLabel (CodeEntry* E, CodeLabel* L)
|
|||
|
||||
|
||||
|
||||
void MoveCodeLabel (CodeLabel* L, CodeEntry* E)
|
||||
void CE_MoveLabel (CodeLabel* L, CodeEntry* E)
|
||||
/* Move the code label L from it's former owner to the code entry E. */
|
||||
{
|
||||
/* Delete the label from the owner */
|
||||
|
@ -261,7 +261,7 @@ void MoveCodeLabel (CodeLabel* L, CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
void CodeEntrySetArg (CodeEntry* E, const char* Arg)
|
||||
void CE_SetArg (CodeEntry* E, const char* Arg)
|
||||
/* Set a new argument for the given code entry. An old string is deleted. */
|
||||
{
|
||||
/* Free the old argument */
|
||||
|
@ -273,7 +273,7 @@ void CodeEntrySetArg (CodeEntry* E, const char* Arg)
|
|||
|
||||
|
||||
|
||||
void OutputCodeEntry (const CodeEntry* E, FILE* F)
|
||||
void CE_Output (const CodeEntry* E, FILE* F)
|
||||
/* Output the code entry to a file */
|
||||
{
|
||||
const OPCDesc* D;
|
||||
|
@ -284,7 +284,7 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F)
|
|||
unsigned LabelCount = CollCount (&E->Labels);
|
||||
unsigned I;
|
||||
for (I = 0; I < LabelCount; ++I) {
|
||||
OutputCodeLabel (CollConstAt (&E->Labels, I), F);
|
||||
CL_Output (CollConstAt (&E->Labels, I), F);
|
||||
}
|
||||
|
||||
/* Get the opcode description */
|
||||
|
@ -375,3 +375,4 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -87,13 +87,13 @@ struct CodeEntry {
|
|||
|
||||
|
||||
CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
|
||||
CodeLabel* JumpTo, LineInfo* LI);
|
||||
CodeLabel* JumpTo, LineInfo* LI);
|
||||
/* Create a new code entry, initialize and return it */
|
||||
|
||||
void FreeCodeEntry (CodeEntry* E);
|
||||
/* Free the given code entry */
|
||||
|
||||
void ReplaceOPC (CodeEntry* E, opc_t OPC);
|
||||
void CE_ReplaceOPC (CodeEntry* E, opc_t OPC);
|
||||
/* Replace the opcode of the instruction. This will also replace related info,
|
||||
* Size, Use and Chg, but it will NOT update any arguments or labels.
|
||||
*/
|
||||
|
@ -101,76 +101,76 @@ void ReplaceOPC (CodeEntry* E, opc_t OPC);
|
|||
int CodeEntriesAreEqual (const CodeEntry* E1, const CodeEntry* E2);
|
||||
/* Check if both code entries are equal */
|
||||
|
||||
void AttachCodeLabel (CodeEntry* E, CodeLabel* L);
|
||||
void CE_AttachLabel (CodeEntry* E, CodeLabel* L);
|
||||
/* Attach the label to the entry */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int CodeEntryHasLabel (const CodeEntry* E)
|
||||
INLINE int CE_HasLabel (const CodeEntry* E)
|
||||
/* Check if the given code entry has labels attached */
|
||||
{
|
||||
return (CollCount (&E->Labels) > 0);
|
||||
}
|
||||
#else
|
||||
# define CodeEntryHasLabel(E) (CollCount (&(E)->Labels) > 0)
|
||||
# define CE_HasLabel(E) (CollCount (&(E)->Labels) > 0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE unsigned GetCodeLabelCount (const CodeEntry* E)
|
||||
INLINE unsigned CE_GetLabelCount (const CodeEntry* E)
|
||||
/* Get the number of labels attached to this entry */
|
||||
{
|
||||
return CollCount (&E->Labels);
|
||||
}
|
||||
#else
|
||||
# define GetCodeLabelCount(E) CollCount (&(E)->Labels)
|
||||
# define CE_GetLabelCount(E) CollCount (&(E)->Labels)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE CodeLabel* GetCodeLabel (CodeEntry* E, unsigned Index)
|
||||
INLINE CodeLabel* CE_GetLabel (CodeEntry* E, unsigned Index)
|
||||
/* Get a label from this code entry */
|
||||
{
|
||||
return CollAt (&E->Labels, Index);
|
||||
}
|
||||
#else
|
||||
# define GetCodeLabel(E, Index) CollAt (&(E)->Labels, (Index))
|
||||
# define CE_GetLabel(E, Index) CollAt (&(E)->Labels, (Index))
|
||||
#endif
|
||||
|
||||
void MoveCodeLabel (CodeLabel* L, CodeEntry* E);
|
||||
void CE_MoveLabel (CodeLabel* L, CodeEntry* E);
|
||||
/* Move the code label L from it's former owner to the code entry E. */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int CodeEntryHasMark (const CodeEntry* E)
|
||||
INLINE int CE_HasMark (const CodeEntry* E)
|
||||
/* Return true if the given code entry has the CEF_USERMARK flag set */
|
||||
{
|
||||
return (E->Flags & CEF_USERMARK) != 0;
|
||||
}
|
||||
#else
|
||||
# define CodeEntryHasMark(E) (((E)->Flags & CEF_USERMARK) != 0)
|
||||
# define CE_HasMark(E) (((E)->Flags & CEF_USERMARK) != 0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void CodeEntrySetMark (CodeEntry* E)
|
||||
INLINE void CE_SetMark (CodeEntry* E)
|
||||
/* Set the CEF_USERMARK flag for the given entry */
|
||||
{
|
||||
E->Flags |= CEF_USERMARK;
|
||||
}
|
||||
#else
|
||||
# define CodeEntrySetMark(E) ((E)->Flags |= CEF_USERMARK)
|
||||
# define CE_SetMark(E) ((E)->Flags |= CEF_USERMARK)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void CodeEntryResetMark (CodeEntry* E)
|
||||
INLINE void CE_ResetMark (CodeEntry* E)
|
||||
/* Reset the CEF_USERMARK flag for the given entry */
|
||||
{
|
||||
E->Flags &= ~CEF_USERMARK;
|
||||
}
|
||||
#else
|
||||
# define CodeEntryResetMark(E) ((E)->Flags &= ~CEF_USERMARK)
|
||||
# define CE_ResetMark(E) ((E)->Flags &= ~CEF_USERMARK)
|
||||
#endif
|
||||
|
||||
void CodeEntrySetArg (CodeEntry* E, const char* Arg);
|
||||
void CE_SetArg (CodeEntry* E, const char* Arg);
|
||||
/* Set a new argument for the given code entry. An old string is deleted. */
|
||||
|
||||
void OutputCodeEntry (const CodeEntry* E, FILE* F);
|
||||
void CE_Output (const CodeEntry* E, FILE* F);
|
||||
/* Output the code entry to a file */
|
||||
|
||||
|
||||
|
@ -180,3 +180,4 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F);
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ static unsigned MakeByteOffs (unsigned Flags, unsigned Offs)
|
|||
void g_defcodelabel (unsigned label)
|
||||
/* Define a local code label */
|
||||
{
|
||||
AddCodeLabel (CS->Code, LocalLabelName (label));
|
||||
CS_AddLabel (CS->Code, LocalLabelName (label));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -256,12 +256,12 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||
/* Check if we have already visited the current code entry. If so,
|
||||
* bail out.
|
||||
*/
|
||||
if (CodeEntryHasMark (E)) {
|
||||
if (CE_HasMark (E)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Mark this entry as already visited */
|
||||
CodeEntrySetMark (E);
|
||||
CE_SetMark (E);
|
||||
CollAppend (Visited, E);
|
||||
|
||||
/* Evaluate the used registers */
|
||||
|
@ -335,9 +335,9 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||
return REG_AXY;
|
||||
}
|
||||
if (Index < 0) {
|
||||
Index = GetCodeEntryIndex (S, E);
|
||||
}
|
||||
if ((E = GetCodeEntry (S, ++Index)) == 0) {
|
||||
Index = CS_GetEntryIndex (S, E);
|
||||
}
|
||||
if ((E = CS_GetEntry (S, ++Index)) == 0) {
|
||||
Internal ("GetRegInfo2: No next entry!");
|
||||
}
|
||||
U2 = GetRegInfo2 (S, E, Index, Visited, Used, Unused);
|
||||
|
@ -352,9 +352,9 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||
|
||||
/* Just go to the next instruction */
|
||||
if (Index < 0) {
|
||||
Index = GetCodeEntryIndex (S, E);
|
||||
Index = CS_GetEntryIndex (S, E);
|
||||
}
|
||||
E = GetCodeEntry (S, ++Index);
|
||||
E = CS_GetEntry (S, ++Index);
|
||||
if (E == 0) {
|
||||
/* No next entry */
|
||||
Internal ("GetRegInfo2: No next entry!");
|
||||
|
@ -371,8 +371,8 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||
|
||||
|
||||
static unsigned char GetRegInfo1 (CodeSeg* S,
|
||||
CodeEntry* E,
|
||||
int Index,
|
||||
CodeEntry* E,
|
||||
int Index,
|
||||
Collection* Visited,
|
||||
unsigned char Used,
|
||||
unsigned char Unused)
|
||||
|
@ -388,7 +388,7 @@ static unsigned char GetRegInfo1 (CodeSeg* S,
|
|||
unsigned NewCount = CollCount (Visited);
|
||||
while (NewCount-- > Count) {
|
||||
CodeEntry* E = CollAt (Visited, NewCount);
|
||||
CodeEntryResetMark (E);
|
||||
CE_ResetMark (E);
|
||||
CollDelete (Visited, NewCount);
|
||||
}
|
||||
|
||||
|
@ -408,11 +408,11 @@ unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index)
|
|||
unsigned char R;
|
||||
|
||||
/* Get the code entry for the given index */
|
||||
if (Index >= GetCodeEntryCount (S)) {
|
||||
if (Index >= CS_GetEntryCount (S)) {
|
||||
/* There is no such code entry */
|
||||
return REG_NONE;
|
||||
}
|
||||
E = GetCodeEntry (S, Index);
|
||||
E = CS_GetEntry (S, Index);
|
||||
|
||||
/* Initialize the data structure used to collection information */
|
||||
InitCollection (&Visited);
|
||||
|
@ -453,3 +453,4 @@ int RegYUsed (struct CodeSeg* S, unsigned Index)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ void FreeCodeLabel (CodeLabel* L)
|
|||
|
||||
|
||||
|
||||
void AddLabelRef (CodeLabel* L, struct CodeEntry* E)
|
||||
void CL_AddRef (CodeLabel* L, struct CodeEntry* E)
|
||||
/* Let the CodeEntry E reference the label L */
|
||||
{
|
||||
/* The insn at E jumps to this label */
|
||||
|
@ -95,7 +95,7 @@ void AddLabelRef (CodeLabel* L, struct CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
void MoveLabelRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
|
||||
void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
|
||||
/* Move all references to OldLabel to point to NewLabel. OldLabel will have no
|
||||
* more references on return.
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ void MoveLabelRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
|
|||
|
||||
/* Change the reference to the new label */
|
||||
CHECK (E->JumpTo == OldLabel);
|
||||
AddLabelRef (NewLabel, E);
|
||||
CL_AddRef (NewLabel, E);
|
||||
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ void MoveLabelRefs (CodeLabel* OldLabel, CodeLabel* NewLabel)
|
|||
|
||||
|
||||
|
||||
void OutputCodeLabel (const CodeLabel* L, FILE* F)
|
||||
void CL_Output (const CodeLabel* L, FILE* F)
|
||||
/* Output the code label to a file */
|
||||
{
|
||||
fprintf (F, "%s:", L->Name);
|
||||
|
|
|
@ -85,15 +85,15 @@ CodeLabel* NewCodeLabel (const char* Name, unsigned Hash);
|
|||
void FreeCodeLabel (CodeLabel* L);
|
||||
/* Free the given code label */
|
||||
|
||||
void AddLabelRef (CodeLabel* L, struct CodeEntry* E);
|
||||
void CL_AddRef (CodeLabel* L, struct CodeEntry* E);
|
||||
/* Let the CodeEntry E reference the label L */
|
||||
|
||||
void MoveLabelRefs (CodeLabel* OldLabel, CodeLabel* NewLabel);
|
||||
void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel);
|
||||
/* Move all references to OldLabel to point to NewLabel. OldLabel will have no
|
||||
* more references on return.
|
||||
*/
|
||||
|
||||
void OutputCodeLabel (const CodeLabel* L, FILE* F);
|
||||
void CL_Output (const CodeLabel* L, FILE* F);
|
||||
/* Output the code label to a file */
|
||||
|
||||
|
||||
|
|
|
@ -161,17 +161,17 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
|||
CodeLabel* L;
|
||||
|
||||
/* Get the entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Replace the conditional branch */
|
||||
switch (Cond) {
|
||||
|
||||
case CMP_EQ:
|
||||
ReplaceOPC (E, OP65_JEQ);
|
||||
CE_ReplaceOPC (E, OP65_JEQ);
|
||||
break;
|
||||
|
||||
case CMP_NE:
|
||||
ReplaceOPC (E, OP65_JNE);
|
||||
CE_ReplaceOPC (E, OP65_JNE);
|
||||
break;
|
||||
|
||||
case CMP_GT:
|
||||
|
@ -180,33 +180,33 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
|||
* jpl Target
|
||||
* @L: ...
|
||||
*/
|
||||
if ((N = GetNextCodeEntry (S, I)) == 0) {
|
||||
if ((N = CS_GetNextEntry (S, I)) == 0) {
|
||||
/* No such entry */
|
||||
Internal ("Invalid program flow");
|
||||
}
|
||||
L = GenCodeLabel (S, N);
|
||||
L = CS_GenLabel (S, N);
|
||||
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I);
|
||||
ReplaceOPC (E, OP65_JPL);
|
||||
CS_InsertEntry (S, N, I);
|
||||
CE_ReplaceOPC (E, OP65_JPL);
|
||||
break;
|
||||
|
||||
case CMP_GE:
|
||||
ReplaceOPC (E, OP65_JPL);
|
||||
CE_ReplaceOPC (E, OP65_JPL);
|
||||
break;
|
||||
|
||||
case CMP_LT:
|
||||
ReplaceOPC (E, OP65_JMI);
|
||||
CE_ReplaceOPC (E, OP65_JMI);
|
||||
break;
|
||||
|
||||
case CMP_LE:
|
||||
/* Replace by
|
||||
* jmi Target
|
||||
* jmi Target
|
||||
* jeq Target
|
||||
*/
|
||||
ReplaceOPC (E, OP65_JMI);
|
||||
CE_ReplaceOPC (E, OP65_JMI);
|
||||
L = E->JumpTo;
|
||||
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I+1);
|
||||
CS_InsertEntry (S, N, I+1);
|
||||
break;
|
||||
|
||||
case CMP_UGT:
|
||||
|
@ -215,33 +215,33 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
|
|||
* jcs Target
|
||||
* @L: ...
|
||||
*/
|
||||
if ((N = GetNextCodeEntry (S, I)) == 0) {
|
||||
/* No such entry */
|
||||
Internal ("Invalid program flow");
|
||||
if ((N = CS_GetNextEntry (S, I)) == 0) {
|
||||
/* No such entry */
|
||||
Internal ("Invalid program flow");
|
||||
}
|
||||
L = GenCodeLabel (S, N);
|
||||
L = CS_GenLabel (S, N);
|
||||
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I);
|
||||
ReplaceOPC (E, OP65_JCS);
|
||||
CS_InsertEntry (S, N, I);
|
||||
CE_ReplaceOPC (E, OP65_JCS);
|
||||
break;
|
||||
|
||||
case CMP_UGE:
|
||||
ReplaceOPC (E, OP65_JCS);
|
||||
CE_ReplaceOPC (E, OP65_JCS);
|
||||
break;
|
||||
|
||||
case CMP_ULT:
|
||||
ReplaceOPC (E, OP65_JCC);
|
||||
CE_ReplaceOPC (E, OP65_JCC);
|
||||
break;
|
||||
|
||||
case CMP_ULE:
|
||||
/* Replace by
|
||||
* jcc Target
|
||||
* jcc Target
|
||||
* jeq Target
|
||||
*/
|
||||
ReplaceOPC (E, OP65_JCC);
|
||||
CE_ReplaceOPC (E, OP65_JCC);
|
||||
L = E->JumpTo;
|
||||
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
|
||||
InsertCodeEntry (S, N, I+1);
|
||||
CS_InsertEntry (S, N, I+1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -281,7 +281,7 @@ static int IsSpLoad (const CodeEntry* E)
|
|||
|
||||
|
||||
static int IsLocalLoad16 (CodeSeg* S, unsigned Index,
|
||||
CodeEntry** L, unsigned Count)
|
||||
CodeEntry** L, unsigned Count)
|
||||
/* Check if a 16 bit load of a local variable follows:
|
||||
*
|
||||
* ldy #$xx
|
||||
|
@ -298,21 +298,21 @@ static int IsLocalLoad16 (CodeSeg* S, unsigned Index,
|
|||
CHECK (Count >= 5);
|
||||
|
||||
/* Read the first entry */
|
||||
L[0] = GetCodeEntry (S, Index);
|
||||
L[0] = CS_GetEntry (S, Index);
|
||||
|
||||
/* Check for the sequence */
|
||||
return (L[0]->OPC == OP65_LDY &&
|
||||
L[0]->AM == AM65_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
GetCodeEntries (S, L+1, Index+1, Count-1) &&
|
||||
IsSpLoad (L[1]) &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
L[2]->OPC == OP65_TAX &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
L[3]->OPC == OP65_DEY &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
IsSpLoad (L[4]) &&
|
||||
!CodeEntryHasLabel (L[4]));
|
||||
return (L[0]->OPC == OP65_LDY &&
|
||||
L[0]->AM == AM65_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
CS_GetEntries (S, L+1, Index+1, Count-1) &&
|
||||
IsSpLoad (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
L[2]->OPC == OP65_TAX &&
|
||||
!CE_HasLabel (L[2]) &&
|
||||
L[3]->OPC == OP65_DEY &&
|
||||
!CE_HasLabel (L[3]) &&
|
||||
IsSpLoad (L[4]) &&
|
||||
!CE_HasLabel (L[4]));
|
||||
}
|
||||
|
||||
|
||||
|
@ -326,12 +326,12 @@ static int IsImmCmp16 (CodeSeg* S, CodeEntry** L)
|
|||
return (L[0]->OPC == OP65_CPX &&
|
||||
L[0]->AM == AM65_IMM &&
|
||||
(L[0]->Flags & CEF_NUMARG) != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
(L[1]->OPC == OP65_JNE || L[1]->OPC == OP65_BNE) &&
|
||||
L[1]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
L[2]->OPC == OP65_CMP &&
|
||||
L[2]->AM == AM65_IMM &&
|
||||
L[2]->AM == AM65_IMM &&
|
||||
(L[2]->Flags & CEF_NUMARG) != 0 &&
|
||||
(L[3]->Info & OF_ZBRA) != 0 &&
|
||||
L[3]->JumpTo != 0 &&
|
||||
|
@ -355,18 +355,18 @@ static unsigned OptBoolTransforms (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* N;
|
||||
cmp_t Cond;
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for a boolean transformer */
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(Cond = FindBoolCmpCond (E->Arg)) != CMP_INV &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(N->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* Make the boolean transformer unnecessary by changing the
|
||||
|
@ -384,7 +384,7 @@ static unsigned OptBoolTransforms (CodeSeg* S)
|
|||
ReplaceCmp (S, I+1, Cond);
|
||||
|
||||
/* Remove the call to the bool transformer */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -423,26 +423,26 @@ static unsigned OptSub1 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[3];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_SBC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
CS_GetEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OP65_BCS || L[0]->OPC == OP65_JCS) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_DEX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
!RegXUsed (S, I+3)) {
|
||||
|
||||
/* Remove the bcs/dex */
|
||||
DelCodeEntries (S, I+1, 2);
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -482,47 +482,47 @@ static unsigned OptSub2 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[5];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
CS_GetEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OP65_SEC &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_STA &&
|
||||
strcmp (L[1]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
L[2]->OPC == OP65_LDA &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
!CE_HasLabel (L[2]) &&
|
||||
L[3]->OPC == OP65_SBC &&
|
||||
strcmp (L[3]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
!CE_HasLabel (L[3]) &&
|
||||
L[4]->OPC == OP65_STA &&
|
||||
strcmp (L[4]->Arg, L[2]->Arg) == 0 &&
|
||||
!CodeEntryHasLabel (L[4])) {
|
||||
!CE_HasLabel (L[4])) {
|
||||
|
||||
/* Remove the store to tmp1 */
|
||||
DelCodeEntry (S, I+2);
|
||||
CS_DelEntry (S, I+2);
|
||||
|
||||
/* Remove the subtraction */
|
||||
DelCodeEntry (S, I+3);
|
||||
CS_DelEntry (S, I+3);
|
||||
|
||||
/* Move the lda to the position of the subtraction and change the
|
||||
* op to SBC.
|
||||
*/
|
||||
MoveCodeEntry (S, I, I+3);
|
||||
ReplaceOPC (E, OP65_SBC);
|
||||
CS_MoveEntry (S, I, I+3);
|
||||
CE_ReplaceOPC (E, OP65_SBC);
|
||||
|
||||
/* If the sequence head had a label, move this label back to the
|
||||
* head.
|
||||
*/
|
||||
if (CodeEntryHasLabel (E)) {
|
||||
MoveCodeLabels (S, E, L[0]);
|
||||
if (CE_HasLabel (E)) {
|
||||
CS_MoveLabels (S, E, L[0]);
|
||||
}
|
||||
|
||||
/* Remember, we had changes */
|
||||
|
@ -562,26 +562,26 @@ static unsigned OptAdd1 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[3];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_ADC &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
CS_GetEntries (S, L, I+1, 3) &&
|
||||
(L[0]->OPC == OP65_BCC || L[0]->OPC == OP65_JCC) &&
|
||||
L[0]->JumpTo != 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_INX &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
L[0]->JumpTo->Owner == L[2] &&
|
||||
!RegXUsed (S, I+3)) {
|
||||
|
||||
/* Remove the bcs/dex */
|
||||
DelCodeEntries (S, I+1, 2);
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -622,28 +622,28 @@ static unsigned OptCmp1 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[2];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_STX &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
CS_GetEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OP65_STX &&
|
||||
strcmp (L[0]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_ORA &&
|
||||
strcmp (L[1]->Arg, "tmp1") == 0 &&
|
||||
!CodeEntryHasLabel (L[1])) {
|
||||
!CE_HasLabel (L[1])) {
|
||||
|
||||
/* Remove the remaining instructions */
|
||||
DelCodeEntries (S, I+1, 2);
|
||||
CS_DelEntries (S, I+1, 2);
|
||||
|
||||
/* Insert the ora instead */
|
||||
InsertCodeEntry (S, NewCodeEntry (OP65_ORA, E->AM, E->Arg, 0, E->LI), I+1);
|
||||
CS_InsertEntry (S, NewCodeEntry (OP65_ORA, E->AM, E->Arg, 0, E->LI), I+1);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -675,23 +675,23 @@ static unsigned OptCmp2 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[2];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if ((E->OPC == OP65_LDA || IsBitOp (E)) &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
CS_GetEntries (S, L, I+1, 2) &&
|
||||
IsCmpToZero (L[0]) &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
(L[1]->Info & OF_FBRA) != 0 &&
|
||||
!CodeEntryHasLabel (L[1])) {
|
||||
!CE_HasLabel (L[1])) {
|
||||
|
||||
/* Remove the compare */
|
||||
DelCodeEntry (S, I+1);
|
||||
CS_DelEntry (S, I+1);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -734,40 +734,40 @@ static unsigned OptCmp3 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[5];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
CS_GetEntries (S, L, I+1, 5) &&
|
||||
L[0]->OPC == OP65_LDX &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
IsImmCmp16 (S, L+1)) {
|
||||
|
||||
if (L[1]->Num == 0 && L[3]->Num == 0) {
|
||||
/* The value is zero, we may use the simple code version. */
|
||||
ReplaceOPC (L[0], OP65_ORA);
|
||||
DelCodeEntries (S, I+2, 3);
|
||||
CE_ReplaceOPC (L[0], OP65_ORA);
|
||||
CS_DelEntries (S, I+2, 3);
|
||||
} else {
|
||||
/* Move the lda instruction after the first branch. This will
|
||||
* improve speed, since the load is delayed after the first
|
||||
* test.
|
||||
*/
|
||||
MoveCodeEntry (S, I, I+4);
|
||||
CS_MoveEntry (S, I, I+4);
|
||||
|
||||
/* We will replace the ldx/cpx by lda/cmp */
|
||||
ReplaceOPC (L[0], OP65_LDA);
|
||||
ReplaceOPC (L[1], OP65_CMP);
|
||||
CE_ReplaceOPC (L[0], OP65_LDA);
|
||||
CE_ReplaceOPC (L[1], OP65_CMP);
|
||||
|
||||
/* Beware: If the first LDA instruction had a label, we have
|
||||
* to move this label to the top of the sequence again.
|
||||
*/
|
||||
if (CodeEntryHasLabel (E)) {
|
||||
MoveCodeLabels (S, E, L[0]);
|
||||
if (CE_HasLabel (E)) {
|
||||
CS_MoveLabels (S, E, L[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ static unsigned OptCmp4 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[9];
|
||||
|
||||
|
@ -820,9 +820,9 @@ static unsigned OptCmp4 (CodeSeg* S)
|
|||
* ora (sp),y
|
||||
* jne/jeq ...
|
||||
*/
|
||||
ReplaceOPC (L[4], OP65_ORA);
|
||||
DelCodeEntries (S, I+5, 3); /* cpx/bne/cmp */
|
||||
DelCodeEntry (S, I+2); /* tax */
|
||||
CE_ReplaceOPC (L[4], OP65_ORA);
|
||||
CS_DelEntries (S, I+5, 3); /* cpx/bne/cmp */
|
||||
CS_DelEntry (S, I+2); /* tax */
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -838,10 +838,10 @@ static unsigned OptCmp4 (CodeSeg* S)
|
|||
* cmp #b
|
||||
* jne/jeq ...
|
||||
*/
|
||||
DelCodeEntry (S, I+2); /* tax */
|
||||
ReplaceOPC (L[5], OP65_CMP); /* cpx -> cmp */
|
||||
MoveCodeEntry (S, I+4, I+2); /* cmp */
|
||||
MoveCodeEntry (S, I+5, I+3); /* bne */
|
||||
CS_DelEntry (S, I+2); /* tax */
|
||||
CE_ReplaceOPC (L[5], OP65_CMP); /* cpx -> cmp */
|
||||
CS_MoveEntry (S, I+4, I+2); /* cmp */
|
||||
CS_MoveEntry (S, I+5, I+3); /* bne */
|
||||
|
||||
}
|
||||
|
||||
|
@ -870,20 +870,20 @@ static unsigned OptCmp5 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* N;
|
||||
cmp_t Cond;
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(Cond = FindTosCmpCond (E->Arg)) != CMP_INV &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(N->Info & OF_ZBRA) != 0 &&
|
||||
!CodeEntryHasLabel (N)) {
|
||||
!CE_HasLabel (N)) {
|
||||
|
||||
/* The tos... functions will return a boolean value in a/x and
|
||||
* the Z flag says if this value is zero or not. We will call
|
||||
|
@ -899,8 +899,8 @@ static unsigned OptCmp5 (CodeSeg* S)
|
|||
|
||||
/* Replace the subroutine call. */
|
||||
E = NewCodeEntry (OP65_JSR, AM65_ABS, "tosicmp", 0, E->LI);
|
||||
InsertCodeEntry (S, E, I+1);
|
||||
DelCodeEntry (S, I);
|
||||
CS_InsertEntry (S, E, I+1);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Replace the conditional branch */
|
||||
ReplaceCmp (S, I+1, Cond);
|
||||
|
@ -941,26 +941,26 @@ static unsigned OptNegA1 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[2];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
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 &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
CS_GetEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OP65_LDA &&
|
||||
(L[0]->Use & REG_X) == 0 &&
|
||||
L[1]->OPC == OP65_JSR &&
|
||||
strcmp (L[1]->Arg, "bnega") == 0) {
|
||||
|
||||
/* Remove the ldx instruction */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -992,26 +992,26 @@ static unsigned OptNegA2 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[2];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
CS_GetEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OP65_JSR &&
|
||||
strcmp (L[0]->Arg, "bnega") == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
(L[1]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||
|
||||
/* Delete the subroutine call */
|
||||
DelCodeEntry (S, I+1);
|
||||
CS_DelEntry (S, I+1);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -1057,39 +1057,39 @@ static unsigned OptNegAX1 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[5];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_LDA &&
|
||||
E->AM == AM65_ZP_INDY &&
|
||||
GetCodeEntries (S, L, I+1, 5) &&
|
||||
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 &&
|
||||
!CodeEntryHasLabel (L[2]) &&
|
||||
!CE_HasLabel (L[2]) &&
|
||||
L[3]->OPC == OP65_JSR &&
|
||||
strcmp (L[3]->Arg, "bnegax") == 0 &&
|
||||
!CodeEntryHasLabel (L[3]) &&
|
||||
!CE_HasLabel (L[3]) &&
|
||||
(L[4]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* lda --> ora */
|
||||
ReplaceOPC (L[2], OP65_ORA);
|
||||
CE_ReplaceOPC (L[2], OP65_ORA);
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
|
||||
CE_ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
|
||||
|
||||
/* Delete the entries no longer needed. Beware: Deleting entries
|
||||
* will change the indices.
|
||||
*/
|
||||
DelCodeEntry (S, I+4); /* jsr bnegax */
|
||||
DelCodeEntry (S, I+1); /* tax */
|
||||
CS_DelEntry (S, I+4); /* jsr bnegax */
|
||||
CS_DelEntry (S, I+1); /* tax */
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -1126,31 +1126,31 @@ static unsigned OptNegAX2 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[3];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_LDA &&
|
||||
GetCodeEntries (S, L, I+1, 3) &&
|
||||
CS_GetEntries (S, L, I+1, 3) &&
|
||||
L[0]->OPC == OP65_LDX &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
L[1]->OPC == OP65_JSR &&
|
||||
strcmp (L[1]->Arg, "bnegax") == 0 &&
|
||||
!CodeEntryHasLabel (L[1]) &&
|
||||
!CE_HasLabel (L[1]) &&
|
||||
(L[2]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
/* ldx --> ora */
|
||||
ReplaceOPC (L[0], OP65_ORA);
|
||||
CE_ReplaceOPC (L[0], OP65_ORA);
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
|
||||
CE_ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
|
||||
|
||||
/* Delete the subroutine call */
|
||||
DelCodeEntry (S, I+2);
|
||||
CS_DelEntry (S, I+2);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -1186,20 +1186,20 @@ static unsigned OptNegAX3 (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* L[2];
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check for the sequence */
|
||||
if (E->OPC == OP65_JSR &&
|
||||
E->Arg[0] == '_' &&
|
||||
GetCodeEntries (S, L, I+1, 2) &&
|
||||
CS_GetEntries (S, L, I+1, 2) &&
|
||||
L[0]->OPC == OP65_JSR &&
|
||||
strncmp (L[0]->Arg,"bnega",5) == 0 &&
|
||||
!CodeEntryHasLabel (L[0]) &&
|
||||
!CE_HasLabel (L[0]) &&
|
||||
(L[1]->Info & OF_ZBRA) != 0) {
|
||||
|
||||
CodeEntry* X;
|
||||
|
@ -1211,20 +1211,20 @@ static unsigned OptNegAX3 (CodeSeg* S)
|
|||
if (ByteSized) {
|
||||
/* Test bytes */
|
||||
X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+2);
|
||||
CS_InsertEntry (S, X, I+2);
|
||||
} else {
|
||||
/* Test words */
|
||||
X = NewCodeEntry (OP65_STX, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+2);
|
||||
CS_InsertEntry (S, X, I+2);
|
||||
X = NewCodeEntry (OP65_ORA, AM65_ZP, "tmp1", 0, L[0]->LI);
|
||||
InsertCodeEntry (S, X, I+3);
|
||||
CS_InsertEntry (S, X, I+3);
|
||||
}
|
||||
|
||||
/* Delete the subroutine call */
|
||||
DelCodeEntry (S, I+1);
|
||||
CS_DelEntry (S, I+1);
|
||||
|
||||
/* Invert the branch */
|
||||
ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||
CE_ReplaceOPC (L[1], GetInverseBranch (L[1]->OPC));
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
|
|
@ -62,12 +62,12 @@
|
|||
|
||||
|
||||
|
||||
static void MoveLabelsToPool (CodeSeg* S, CodeEntry* E)
|
||||
static void CS_MoveLabelsToPool (CodeSeg* S, CodeEntry* E)
|
||||
/* Move the labels of the code entry E to the label pool of the code segment */
|
||||
{
|
||||
unsigned LabelCount = GetCodeLabelCount (E);
|
||||
unsigned LabelCount = CE_GetLabelCount (E);
|
||||
while (LabelCount--) {
|
||||
CodeLabel* L = GetCodeLabel (E, LabelCount);
|
||||
CodeLabel* L = CE_GetLabel (E, LabelCount);
|
||||
L->Owner = 0;
|
||||
CollAppend (&S->Labels, L);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ static void MoveLabelsToPool (CodeSeg* S, CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
static CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
||||
static CodeLabel* CS_FindLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
||||
/* Find the label with the given name. Return the label or NULL if not found */
|
||||
{
|
||||
/* Get the first hash chain entry */
|
||||
|
@ -95,10 +95,10 @@ static CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
|||
|
||||
|
||||
|
||||
static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
||||
static CodeLabel* CS_NewCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
||||
/* Create a new label and insert it into the label hash table */
|
||||
{
|
||||
/* Not found - create a new one */
|
||||
/* Create a new label */
|
||||
CodeLabel* L = NewCodeLabel (Name, Hash);
|
||||
|
||||
/* Enter the label into the hash table */
|
||||
|
@ -111,7 +111,7 @@ static CodeLabel* NewCodeSegLabel (CodeSeg* S, const char* Name, unsigned Hash)
|
|||
|
||||
|
||||
|
||||
static void RemoveLabelFromHash (CodeSeg* S, CodeLabel* L)
|
||||
static void CS_RemoveLabelFromHash (CodeSeg* S, CodeLabel* L)
|
||||
/* Remove the given code label from the hash list */
|
||||
{
|
||||
/* Get the first entry in the hash chain */
|
||||
|
@ -194,9 +194,9 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||
{
|
||||
char Mnemo[16];
|
||||
const OPCDesc* OPC;
|
||||
am_t AM = 0; /* Initialize to keep gcc silent */
|
||||
char Arg[64];
|
||||
char Reg;
|
||||
am_t AM = 0; /* Initialize to keep gcc silent */
|
||||
char Arg[64];
|
||||
char Reg;
|
||||
CodeEntry* E;
|
||||
CodeLabel* Label;
|
||||
|
||||
|
@ -254,7 +254,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||
return 0;
|
||||
}
|
||||
L = SkipSpace (L+1);
|
||||
if (*L != '\0') {
|
||||
if (*L != '\0') {
|
||||
Error ("ASM code error: syntax error");
|
||||
return 0;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||
L = ReadToken (L, ",", Arg, sizeof (Arg));
|
||||
if (*L == '\0') {
|
||||
/* Absolute, zeropage or branch */
|
||||
if ((OPC->Info & OF_BRA) != 0) {
|
||||
if ((OPC->Info & OF_BRA) != 0) {
|
||||
/* Branch */
|
||||
AM = AM65_BRA;
|
||||
} else if (IsZPName (Arg)) {
|
||||
|
@ -344,12 +344,12 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
|||
|
||||
/* Generate the hash over the label, then search for the label */
|
||||
unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE;
|
||||
Label = FindCodeLabel (S, Arg, Hash);
|
||||
Label = CS_FindLabel (S, Arg, Hash);
|
||||
|
||||
/* If we don't have the label, it's a forward ref - create it */
|
||||
if (Label == 0) {
|
||||
/* Generate a new label */
|
||||
Label = NewCodeSegLabel (S, Arg, Hash);
|
||||
Label = CS_NewCodeLabel (S, Arg, Hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,12 +402,36 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func)
|
|||
|
||||
|
||||
|
||||
void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
|
||||
void CS_AddEntry (CodeSeg* S, struct CodeEntry* E, LineInfo* LI)
|
||||
/* Add an entry to the given code segment */
|
||||
{
|
||||
/* Transfer the labels if we have any */
|
||||
unsigned I;
|
||||
unsigned LabelCount = CollCount (&S->Labels);
|
||||
for (I = 0; I < LabelCount; ++I) {
|
||||
|
||||
/* Get the label */
|
||||
CodeLabel* L = CollAt (&S->Labels, I);
|
||||
|
||||
/* Attach it to the entry */
|
||||
CE_AttachLabel (E, L);
|
||||
}
|
||||
|
||||
/* Delete the transfered labels */
|
||||
CollDeleteAll (&S->Labels);
|
||||
|
||||
/* Add the entry to the list of code entries in this segment */
|
||||
CollAppend (&S->Entries, E);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CS_AddEntryLine (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
|
||||
/* Add a line to the given code segment */
|
||||
{
|
||||
const char* L;
|
||||
CodeEntry* E;
|
||||
char Token[64];
|
||||
char Token[64];
|
||||
|
||||
/* Format the line */
|
||||
char Buf [256];
|
||||
|
@ -417,7 +441,7 @@ void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
|
|||
L = SkipSpace (Buf);
|
||||
|
||||
/* Check which type of instruction we have */
|
||||
E = 0; /* Assume no insn created */
|
||||
E = 0; /* Assume no insn created */
|
||||
switch (*L) {
|
||||
|
||||
case '\0':
|
||||
|
@ -441,31 +465,13 @@ void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
|
|||
|
||||
/* If we have a code entry, transfer the labels and insert it */
|
||||
if (E) {
|
||||
|
||||
/* Transfer the labels if we have any */
|
||||
unsigned I;
|
||||
unsigned LabelCount = CollCount (&S->Labels);
|
||||
for (I = 0; I < LabelCount; ++I) {
|
||||
|
||||
/* Get the label */
|
||||
CodeLabel* L = CollAt (&S->Labels, I);
|
||||
|
||||
/* Attach it to the entry */
|
||||
AttachCodeLabel (E, L);
|
||||
}
|
||||
|
||||
/* Delete the transfered labels */
|
||||
CollDeleteAll (&S->Labels);
|
||||
|
||||
/* Add the entry to the list of code entries in this segment */
|
||||
CollAppend (&S->Entries, E);
|
||||
|
||||
CS_AddEntry (S, E, LI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InsertCodeEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index)
|
||||
void CS_InsertEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index)
|
||||
/* Insert the code entry at the index given. Following code entries will be
|
||||
* moved to slots with higher indices.
|
||||
*/
|
||||
|
@ -476,14 +482,14 @@ void InsertCodeEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index)
|
|||
|
||||
|
||||
|
||||
void DelCodeEntry (CodeSeg* S, unsigned Index)
|
||||
void CS_DelEntry (CodeSeg* S, unsigned Index)
|
||||
/* Delete an entry from the code segment. This includes moving any associated
|
||||
* labels, removing references to labels and even removing the referenced labels
|
||||
* if the reference count drops to zero.
|
||||
*/
|
||||
{
|
||||
/* Get the code entry for the given index */
|
||||
CodeEntry* E = GetCodeEntry (S, Index);
|
||||
CodeEntry* E = CS_GetEntry (S, Index);
|
||||
|
||||
/* If the entry has a labels, we have to move this label to the next insn.
|
||||
* If there is no next insn, move the label into the code segement label
|
||||
|
@ -491,24 +497,24 @@ void DelCodeEntry (CodeSeg* S, unsigned Index)
|
|||
* insn may already have a label. In that case change all reference to
|
||||
* this label and delete the label instead of moving it.
|
||||
*/
|
||||
unsigned Count = GetCodeLabelCount (E);
|
||||
unsigned Count = CE_GetLabelCount (E);
|
||||
if (Count > 0) {
|
||||
|
||||
/* The instruction has labels attached. Check if there is a next
|
||||
* instruction.
|
||||
*/
|
||||
if (Index == GetCodeEntryCount (S)-1) {
|
||||
if (Index == CS_GetEntryCount (S)-1) {
|
||||
|
||||
/* No next instruction, move to the codeseg label pool */
|
||||
MoveLabelsToPool (S, E);
|
||||
CS_MoveLabelsToPool (S, E);
|
||||
|
||||
} else {
|
||||
|
||||
/* There is a next insn, get it */
|
||||
CodeEntry* N = GetCodeEntry (S, Index+1);
|
||||
CodeEntry* N = CS_GetEntry (S, Index+1);
|
||||
|
||||
/* Move labels to the next entry */
|
||||
MoveCodeLabels (S, E, N);
|
||||
CS_MoveLabels (S, E, N);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +524,7 @@ void DelCodeEntry (CodeSeg* S, unsigned Index)
|
|||
*/
|
||||
if (E->JumpTo) {
|
||||
/* Remove the reference */
|
||||
RemoveCodeLabelRef (S, E);
|
||||
CS_RemoveLabelRef (S, E);
|
||||
}
|
||||
|
||||
/* Delete the pointer to the insn */
|
||||
|
@ -530,7 +536,7 @@ void DelCodeEntry (CodeSeg* S, unsigned Index)
|
|||
|
||||
|
||||
|
||||
void DelCodeEntries (CodeSeg* S, unsigned Start, unsigned Count)
|
||||
void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count)
|
||||
/* Delete a range of code entries. This includes removing references to labels,
|
||||
* labels attached to the entries and so on.
|
||||
*/
|
||||
|
@ -539,19 +545,19 @@ void DelCodeEntries (CodeSeg* S, unsigned Start, unsigned Count)
|
|||
* memory moving.
|
||||
*/
|
||||
while (Count--) {
|
||||
DelCodeEntry (S, Start + Count);
|
||||
CS_DelEntry (S, Start + Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MoveCodeEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
|
||||
void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
|
||||
/* Move an entry from one position to another. OldPos is the current position
|
||||
* of the entry, NewPos is the new position of the entry.
|
||||
*/
|
||||
{
|
||||
/* Get the code entry and remove it from the collection */
|
||||
CodeEntry* E = GetCodeEntry (S, OldPos);
|
||||
CodeEntry* E = CS_GetEntry (S, OldPos);
|
||||
CollDelete (&S->Entries, OldPos);
|
||||
|
||||
/* Correct NewPos if needed */
|
||||
|
@ -566,7 +572,7 @@ void MoveCodeEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
|
|||
|
||||
|
||||
|
||||
struct CodeEntry* GetNextCodeEntry (CodeSeg* S, unsigned Index)
|
||||
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
|
||||
/* Get the code entry following the one with the index Index. If there is no
|
||||
* following code entry, return NULL.
|
||||
*/
|
||||
|
@ -582,8 +588,8 @@ struct CodeEntry* GetNextCodeEntry (CodeSeg* S, unsigned Index)
|
|||
|
||||
|
||||
|
||||
int GetCodeEntries (CodeSeg* S, struct CodeEntry** List,
|
||||
unsigned Start, unsigned Count)
|
||||
int CS_GetEntries (CodeSeg* S, struct CodeEntry** List,
|
||||
unsigned Start, unsigned Count)
|
||||
/* Get Count code entries into List starting at index start. Return true if
|
||||
* we got the lines, return false if not enough lines were available.
|
||||
*/
|
||||
|
@ -604,7 +610,7 @@ int GetCodeEntries (CodeSeg* S, struct CodeEntry** List,
|
|||
|
||||
|
||||
|
||||
unsigned GetCodeEntryIndex (CodeSeg* S, struct CodeEntry* E)
|
||||
unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E)
|
||||
/* Return the index of a code entry */
|
||||
{
|
||||
int Index = CollIndex (&S->Entries, E);
|
||||
|
@ -614,14 +620,14 @@ unsigned GetCodeEntryIndex (CodeSeg* S, struct CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
void AddCodeLabel (CodeSeg* S, const char* Name)
|
||||
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name)
|
||||
/* Add a code label for the next instruction to follow */
|
||||
{
|
||||
/* Calculate the hash from the name */
|
||||
unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
|
||||
|
||||
/* Try to find the code label if it does already exist */
|
||||
CodeLabel* L = FindCodeLabel (S, Name, Hash);
|
||||
CodeLabel* L = CS_FindLabel (S, Name, Hash);
|
||||
|
||||
/* Did we find it? */
|
||||
if (L) {
|
||||
|
@ -629,7 +635,7 @@ void AddCodeLabel (CodeSeg* S, const char* Name)
|
|||
CHECK (L->Owner == 0);
|
||||
} else {
|
||||
/* Not found - create a new one */
|
||||
L = NewCodeSegLabel (S, Name, Hash);
|
||||
L = CS_NewCodeLabel (S, Name, Hash);
|
||||
}
|
||||
|
||||
/* Safety. This call is quite costly, but safety is better */
|
||||
|
@ -639,21 +645,24 @@ void AddCodeLabel (CodeSeg* S, const char* Name)
|
|||
|
||||
/* We do now have a valid label. Remember it for later */
|
||||
CollAppend (&S->Labels, L);
|
||||
|
||||
/* Return the label */
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CodeLabel* GenCodeLabel (CodeSeg* S, struct CodeEntry* E)
|
||||
CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E)
|
||||
/* If the code entry E does already have a label, return it. Otherwise
|
||||
* create a new label, attach it to E and return it.
|
||||
*/
|
||||
{
|
||||
CodeLabel* L;
|
||||
|
||||
if (CodeEntryHasLabel (E)) {
|
||||
if (CE_HasLabel (E)) {
|
||||
|
||||
/* Get the label from this entry */
|
||||
L = GetCodeLabel (E, 0);
|
||||
L = CE_GetLabel (E, 0);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -664,10 +673,10 @@ CodeLabel* GenCodeLabel (CodeSeg* S, struct CodeEntry* E)
|
|||
unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;
|
||||
|
||||
/* Create a new label */
|
||||
L = NewCodeSegLabel (S, Name, Hash);
|
||||
L = CS_NewCodeLabel (S, Name, Hash);
|
||||
|
||||
/* Attach this label to the code entry */
|
||||
AttachCodeLabel (E, L);
|
||||
CE_AttachLabel (E, L);
|
||||
|
||||
}
|
||||
|
||||
|
@ -677,13 +686,13 @@ CodeLabel* GenCodeLabel (CodeSeg* S, struct CodeEntry* E)
|
|||
|
||||
|
||||
|
||||
void DelCodeLabel (CodeSeg* S, CodeLabel* L)
|
||||
void CS_DelLabel (CodeSeg* S, CodeLabel* L)
|
||||
/* Remove references from this label and delete it. */
|
||||
{
|
||||
unsigned Count, I;
|
||||
|
||||
/* First, remove the label from the hash chain */
|
||||
RemoveLabelFromHash (S, L);
|
||||
CS_RemoveLabelFromHash (S, L);
|
||||
|
||||
/* Remove references from insns jumping to this label */
|
||||
Count = CollCount (&L->JumpFrom);
|
||||
|
@ -701,7 +710,7 @@ void DelCodeLabel (CodeSeg* S, CodeLabel* L)
|
|||
* errors to slip through.
|
||||
*/
|
||||
if (L->Owner) {
|
||||
CollDeleteItem (&L->Owner->Labels, L);
|
||||
CollDeleteItem (&L->Owner->Labels, L);
|
||||
}
|
||||
|
||||
/* All references removed, delete the label itself */
|
||||
|
@ -710,7 +719,7 @@ void DelCodeLabel (CodeSeg* S, CodeLabel* L)
|
|||
|
||||
|
||||
|
||||
void MergeCodeLabels (CodeSeg* S)
|
||||
void CS_MergeLabels (CodeSeg* S)
|
||||
/* Merge code labels. That means: For each instruction, remove all labels but
|
||||
* one and adjust references accordingly.
|
||||
*/
|
||||
|
@ -718,23 +727,22 @@ void MergeCodeLabels (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Walk over all code entries */
|
||||
unsigned EntryCount = GetCodeEntryCount (S);
|
||||
for (I = 0; I < EntryCount; ++I) {
|
||||
for (I = 0; I < CS_GetEntryCount (S); ++I) {
|
||||
|
||||
CodeLabel* RefLab;
|
||||
unsigned J;
|
||||
unsigned J;
|
||||
|
||||
/* Get a pointer to the next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* If this entry has zero labels, continue with the next one */
|
||||
unsigned LabelCount = GetCodeLabelCount (E);
|
||||
unsigned LabelCount = CE_GetLabelCount (E);
|
||||
if (LabelCount == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We have at least one label. Use the first one as reference label. */
|
||||
RefLab = GetCodeLabel (E, 0);
|
||||
RefLab = CE_GetLabel (E, 0);
|
||||
|
||||
/* Walk through the remaining labels and change references to these
|
||||
* labels to a reference to the one and only label. Delete the labels
|
||||
|
@ -744,13 +752,13 @@ void MergeCodeLabels (CodeSeg* S)
|
|||
for (J = LabelCount-1; J >= 1; --J) {
|
||||
|
||||
/* Get the next label */
|
||||
CodeLabel* L = GetCodeLabel (E, J);
|
||||
CodeLabel* L = CE_GetLabel (E, J);
|
||||
|
||||
/* Move all references from this label to the reference label */
|
||||
MoveLabelRefs (L, RefLab);
|
||||
CL_MoveRefs (L, RefLab);
|
||||
|
||||
/* Remove the label completely. */
|
||||
DelCodeLabel (S, L);
|
||||
CS_DelLabel (S, L);
|
||||
}
|
||||
|
||||
/* The reference label is the only remaining label. Check if there
|
||||
|
@ -759,14 +767,14 @@ void MergeCodeLabels (CodeSeg* S)
|
|||
*/
|
||||
if (CollCount (&RefLab->JumpFrom) == 0) {
|
||||
/* Delete the label */
|
||||
DelCodeLabel (S, RefLab);
|
||||
CS_DelLabel (S, RefLab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
|
||||
void CS_MoveLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
|
||||
/* Move all labels from Old to New. The routine will move the labels itself
|
||||
* if New does not have any labels, and move references if there is at least
|
||||
* a label for new. If references are moved, the old label is deleted
|
||||
|
@ -774,23 +782,23 @@ void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
|
|||
*/
|
||||
{
|
||||
/* Get the number of labels to move */
|
||||
unsigned OldLabelCount = GetCodeLabelCount (Old);
|
||||
unsigned OldLabelCount = CE_GetLabelCount (Old);
|
||||
|
||||
/* Does the new entry have itself a label? */
|
||||
if (CodeEntryHasLabel (New)) {
|
||||
if (CE_HasLabel (New)) {
|
||||
|
||||
/* The new entry does already have a label - move references */
|
||||
CodeLabel* NewLabel = GetCodeLabel (New, 0);
|
||||
CodeLabel* NewLabel = CE_GetLabel (New, 0);
|
||||
while (OldLabelCount--) {
|
||||
|
||||
/* Get the next label */
|
||||
CodeLabel* OldLabel = GetCodeLabel (Old, OldLabelCount);
|
||||
CodeLabel* OldLabel = CE_GetLabel (Old, OldLabelCount);
|
||||
|
||||
/* Move references */
|
||||
MoveLabelRefs (OldLabel, NewLabel);
|
||||
CL_MoveRefs (OldLabel, NewLabel);
|
||||
|
||||
/* Delete the label */
|
||||
DelCodeLabel (S, OldLabel);
|
||||
CS_DelLabel (S, OldLabel);
|
||||
|
||||
}
|
||||
|
||||
|
@ -800,7 +808,7 @@ void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
|
|||
while (OldLabelCount--) {
|
||||
|
||||
/* Move the label to the new entry */
|
||||
MoveCodeLabel (GetCodeLabel (Old, OldLabelCount), New);
|
||||
CE_MoveLabel (CE_GetLabel (Old, OldLabelCount), New);
|
||||
|
||||
}
|
||||
|
||||
|
@ -809,7 +817,7 @@ void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New)
|
|||
|
||||
|
||||
|
||||
void RemoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E)
|
||||
void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E)
|
||||
/* Remove the reference between E and the label it jumps to. The reference
|
||||
* will be removed on both sides and E->JumpTo will be 0 after that. If
|
||||
* the reference was the only one for the label, the label will get
|
||||
|
@ -828,13 +836,13 @@ void RemoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E)
|
|||
|
||||
/* If there are no more references, delete the label */
|
||||
if (CollCount (&L->JumpFrom) == 0) {
|
||||
DelCodeLabel (S, L);
|
||||
CS_DelLabel (S, L);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
|
||||
void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
|
||||
/* Change the reference of E to L instead of the current one. If this
|
||||
* was the only reference to the old label, the old label will get
|
||||
* deleted.
|
||||
|
@ -847,19 +855,19 @@ void MoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
|
|||
PRECONDITION (OldLabel != 0);
|
||||
|
||||
/* Remove the reference to our label */
|
||||
RemoveCodeLabelRef (S, E);
|
||||
CS_RemoveLabelRef (S, E);
|
||||
|
||||
/* Use the new label */
|
||||
AddLabelRef (L, E);
|
||||
CL_AddRef (L, E);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DelCodeSegAfter (CodeSeg* S, unsigned Last)
|
||||
void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
|
||||
/* Delete all entries including the given one */
|
||||
{
|
||||
/* Get the number of entries in this segment */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
|
||||
/* First pass: Delete all references to labels. If the reference count
|
||||
* for a label drops to zero, delete it.
|
||||
|
@ -867,23 +875,23 @@ void DelCodeSegAfter (CodeSeg* S, unsigned Last)
|
|||
unsigned C = Count;
|
||||
while (Last < C--) {
|
||||
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, C);
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = CS_GetEntry (S, C);
|
||||
|
||||
/* Check if this entry has a label reference */
|
||||
if (E->JumpTo) {
|
||||
/* If the label is a label in the label pool and this is the last
|
||||
* reference to the label, remove the label from the pool.
|
||||
*/
|
||||
CodeLabel* L = E->JumpTo;
|
||||
int Index = CollIndex (&S->Labels, L);
|
||||
if (Index >= 0 && CollCount (&L->JumpFrom) == 1) {
|
||||
/* Delete it from the pool */
|
||||
CollDelete (&S->Labels, Index);
|
||||
}
|
||||
/* Check if this entry has a label reference */
|
||||
if (E->JumpTo) {
|
||||
/* If the label is a label in the label pool and this is the last
|
||||
* reference to the label, remove the label from the pool.
|
||||
*/
|
||||
CodeLabel* L = E->JumpTo;
|
||||
int Index = CollIndex (&S->Labels, L);
|
||||
if (Index >= 0 && CollCount (&L->JumpFrom) == 1) {
|
||||
/* Delete it from the pool */
|
||||
CollDelete (&S->Labels, Index);
|
||||
}
|
||||
|
||||
/* Remove the reference to the label */
|
||||
RemoveCodeLabelRef (S, E);
|
||||
CS_RemoveLabelRef (S, E);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -897,12 +905,12 @@ void DelCodeSegAfter (CodeSeg* S, unsigned Last)
|
|||
while (Last < C--) {
|
||||
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, C);
|
||||
CodeEntry* E = CS_GetEntry (S, C);
|
||||
|
||||
/* Check if this entry has a label attached */
|
||||
if (CodeEntryHasLabel (E)) {
|
||||
if (CE_HasLabel (E)) {
|
||||
/* Move the labels to the pool and clear the owner pointer */
|
||||
MoveLabelsToPool (S, E);
|
||||
CS_MoveLabelsToPool (S, E);
|
||||
}
|
||||
|
||||
/* Delete the pointer to the entry */
|
||||
|
@ -915,14 +923,14 @@ void DelCodeSegAfter (CodeSeg* S, unsigned Last)
|
|||
|
||||
|
||||
|
||||
void OutputCodeSeg (const CodeSeg* S, FILE* F)
|
||||
void CS_Output (const CodeSeg* S, FILE* F)
|
||||
/* Output the code segment data to a file */
|
||||
{
|
||||
unsigned I;
|
||||
const LineInfo* LI;
|
||||
|
||||
/* Get the number of entries in this segment */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
|
||||
/* If the code segment is empty, bail out here */
|
||||
if (Count == 0) {
|
||||
|
@ -952,17 +960,17 @@ void OutputCodeSeg (const CodeSeg* S, FILE* F)
|
|||
|
||||
/* Add the source line as a comment */
|
||||
if (AddSource) {
|
||||
fprintf (F, ";\n; %s\n;\n", LI->Line);
|
||||
fprintf (F, ";\n; %s\n;\n", LI->Line);
|
||||
}
|
||||
|
||||
/* Add line debug info */
|
||||
if (DebugInfo) {
|
||||
fprintf (F, "\t.dbg\tline, \"%s\", %u\n",
|
||||
GetInputName (LI), GetInputLine (LI));
|
||||
fprintf (F, "\t.dbg\tline, \"%s\", %u\n",
|
||||
GetInputName (LI), GetInputLine (LI));
|
||||
}
|
||||
}
|
||||
/* Output the code */
|
||||
OutputCodeEntry (E, F);
|
||||
CE_Output (E, F);
|
||||
}
|
||||
|
||||
/* If debug info is enabled, terminate the last line number information */
|
||||
|
@ -979,6 +987,3 @@ void OutputCodeSeg (const CodeSeg* S, FILE* F)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -94,104 +94,107 @@ struct CodeSeg {
|
|||
CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func);
|
||||
/* Create a new code segment, initialize and return it */
|
||||
|
||||
void AddCodeEntry (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap) attribute ((format(printf,3,0)));
|
||||
void CS_AddEntry (CodeSeg* S, struct CodeEntry* E, LineInfo* LI);
|
||||
/* Add an entry to the given code segment */
|
||||
|
||||
void CS_AddEntryLine (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap) attribute ((format(printf,3,0)));
|
||||
/* Add a line to the given code segment */
|
||||
|
||||
void InsertCodeEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index);
|
||||
void CS_InsertEntry (CodeSeg* S, struct CodeEntry* E, unsigned Index);
|
||||
/* Insert the code entry at the index given. Following code entries will be
|
||||
* moved to slots with higher indices.
|
||||
*/
|
||||
|
||||
void DelCodeEntry (CodeSeg* S, unsigned Index);
|
||||
void CS_DelEntry (CodeSeg* S, unsigned Index);
|
||||
/* Delete an entry from the code segment. This includes moving any associated
|
||||
* labels, removing references to labels and even removing the referenced labels
|
||||
* if the reference count drops to zero.
|
||||
*/
|
||||
|
||||
void DelCodeEntries (CodeSeg* S, unsigned Start, unsigned Count);
|
||||
void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count);
|
||||
/* Delete a range of code entries. This includes removing references to labels,
|
||||
* labels attached to the entries and so on.
|
||||
*/
|
||||
|
||||
void MoveCodeEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos);
|
||||
void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos);
|
||||
/* Move an entry from one position to another. OldPos is the current position
|
||||
* of the entry, NewPos is the new position of the entry.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE struct CodeEntry* GetCodeEntry (CodeSeg* S, unsigned Index)
|
||||
INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)
|
||||
/* Get an entry from the given code segment */
|
||||
{
|
||||
return CollAt (&S->Entries, Index);
|
||||
}
|
||||
#else
|
||||
# define GetCodeEntry(S, Index) CollAt(&(S)->Entries, (Index))
|
||||
# define CS_GetEntry(S, Index) CollAt(&(S)->Entries, (Index))
|
||||
#endif
|
||||
|
||||
struct CodeEntry* GetNextCodeEntry (CodeSeg* S, unsigned Index);
|
||||
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index);
|
||||
/* Get the code entry following the one with the index Index. If there is no
|
||||
* following code entry, return NULL.
|
||||
*/
|
||||
|
||||
int GetCodeEntries (CodeSeg* S, struct CodeEntry** List,
|
||||
unsigned Start, unsigned Count);
|
||||
int CS_GetEntries (CodeSeg* S, struct CodeEntry** List,
|
||||
unsigned Start, unsigned Count);
|
||||
/* Get Count code entries into List starting at index start. Return true if
|
||||
* we got the lines, return false if not enough lines were available.
|
||||
*/
|
||||
|
||||
unsigned GetCodeEntryIndex (CodeSeg* S, struct CodeEntry* E);
|
||||
unsigned CS_GetEntryIndex (CodeSeg* S, struct CodeEntry* E);
|
||||
/* Return the index of a code entry */
|
||||
|
||||
void AddCodeLabel (CodeSeg* S, const char* Name);
|
||||
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name);
|
||||
/* Add a code label for the next instruction to follow */
|
||||
|
||||
CodeLabel* GenCodeLabel (CodeSeg* S, struct CodeEntry* E);
|
||||
CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E);
|
||||
/* If the code entry E does already have a label, return it. Otherwise
|
||||
* create a new label, attach it to E and return it.
|
||||
*/
|
||||
|
||||
void DelCodeLabel (CodeSeg* S, CodeLabel* L);
|
||||
void CS_DelLabel (CodeSeg* S, CodeLabel* L);
|
||||
/* Remove references from this label and delete it. */
|
||||
|
||||
void MergeCodeLabels (CodeSeg* S);
|
||||
void CS_MergeLabels (CodeSeg* S);
|
||||
/* Merge code labels. That means: For each instruction, remove all labels but
|
||||
* one and adjust references accordingly.
|
||||
*/
|
||||
|
||||
void MoveCodeLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New);
|
||||
void CS_MoveLabels (CodeSeg* S, struct CodeEntry* Old, struct CodeEntry* New);
|
||||
/* Move all labels from Old to New. The routine will move the labels itself
|
||||
* if New does not have any labels, and move references if there is at least
|
||||
* a label for new. If references are moved, the old label is deleted
|
||||
* afterwards.
|
||||
*/
|
||||
|
||||
void RemoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E);
|
||||
void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E);
|
||||
/* Remove the reference between E and the label it jumps to. The reference
|
||||
* will be removed on both sides and E->JumpTo will be 0 after that. If
|
||||
* the reference was the only one for the label, the label will get
|
||||
* deleted.
|
||||
*/
|
||||
|
||||
void MoveCodeLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L);
|
||||
void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L);
|
||||
/* Change the reference of E to L instead of the current one. If this
|
||||
* was the only reference to the old label, the old label will get
|
||||
* deleted.
|
||||
*/
|
||||
|
||||
void DelCodeSegAfter (CodeSeg* S, unsigned Last);
|
||||
void CS_DelCodeAfter (CodeSeg* S, unsigned Last);
|
||||
/* Delete all entries including the given one */
|
||||
|
||||
void OutputCodeSeg (const CodeSeg* S, FILE* F);
|
||||
void CS_Output (const CodeSeg* S, FILE* F);
|
||||
/* Output the code segment data to a file */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE unsigned GetCodeEntryCount (const CodeSeg* S)
|
||||
INLINE unsigned CS_GetEntryCount (const CodeSeg* S)
|
||||
/* Return the number of entries for the given code segment */
|
||||
{
|
||||
return CollCount (&S->Entries);
|
||||
}
|
||||
#else
|
||||
# define GetCodeEntryCount(S) CollCount (&(S)->Entries)
|
||||
# define CS_GetEntryCount(S) CollCount (&(S)->Entries)
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -57,10 +57,10 @@ unsigned OptRTSJumps (CodeSeg* S)
|
|||
|
||||
/* Walk over all entries minus the last one */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
/* Get the next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's an unconditional branch to a local target */
|
||||
if ((E->Info & OF_UBRA) != 0 &&
|
||||
|
@ -69,10 +69,10 @@ unsigned OptRTSJumps (CodeSeg* S)
|
|||
|
||||
/* Insert an RTS instruction */
|
||||
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
|
||||
InsertCodeEntry (S, X, I+1);
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
|
||||
/* Delete the jump */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -104,7 +104,7 @@ unsigned OptDeadJumps (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have less than two entries */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
if (Count < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -114,15 +114,15 @@ unsigned OptDeadJumps (CodeSeg* S)
|
|||
while (I < Count-1) {
|
||||
|
||||
/* Get the next entry */
|
||||
E = GetCodeEntry (S, I);
|
||||
E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a branch, if it has a local target, and if the target
|
||||
* is the next instruction.
|
||||
*/
|
||||
if (E->AM == AM65_BRA && E->JumpTo && E->JumpTo->Owner == GetCodeEntry (S, I+1)) {
|
||||
if (E->AM == AM65_BRA && E->JumpTo && E->JumpTo->Owner == CS_GetEntry (S, I+1)) {
|
||||
|
||||
/* Delete the dead jump */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Keep the number of entries updated */
|
||||
--Count;
|
||||
|
@ -159,7 +159,7 @@ unsigned OptDeadCode (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have less than two entries */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
if (Count < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,17 +171,17 @@ unsigned OptDeadCode (CodeSeg* S)
|
|||
CodeEntry* N;
|
||||
|
||||
/* Get this entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's an unconditional branch, and if the next entry has
|
||||
* no labels attached
|
||||
*/
|
||||
if ((E->Info & OF_DEAD) != 0 &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
!CodeEntryHasLabel (N)) {
|
||||
if ((E->Info & OF_DEAD) != 0 &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
!CE_HasLabel (N)) {
|
||||
|
||||
/* Delete the next entry */
|
||||
DelCodeEntry (S, I+1);
|
||||
CS_DelEntry (S, I+1);
|
||||
|
||||
/* Keep the number of entries updated */
|
||||
--Count;
|
||||
|
@ -221,13 +221,13 @@ unsigned OptJumpCascades (CodeSeg* S)
|
|||
|
||||
/* Walk over all entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* N;
|
||||
CodeLabel* OldLabel;
|
||||
|
||||
/* Get this entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a branch, if it has a jump label, if this jump
|
||||
* label is not attached to the instruction itself, and if the
|
||||
|
@ -244,18 +244,18 @@ unsigned OptJumpCascades (CodeSeg* S)
|
|||
*/
|
||||
if ((N->Info & OF_UBRA) != 0 ||
|
||||
((E->Info & OF_CBRA) != 0 &&
|
||||
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
|
||||
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
|
||||
|
||||
/* This is a jump cascade and we may jump to the final target.
|
||||
* Insert a new instruction, then remove the old one
|
||||
* Insert a new instruction, then remove the old one
|
||||
*/
|
||||
CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI);
|
||||
CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI);
|
||||
|
||||
/* Insert it behind E */
|
||||
InsertCodeEntry (S, X, I+1);
|
||||
/* Insert it behind E */
|
||||
CS_InsertEntry (S, X, I+1);
|
||||
|
||||
/* Remove E */
|
||||
DelCodeEntry (S, I);
|
||||
/* Remove E */
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -272,32 +272,32 @@ unsigned OptJumpCascades (CodeSeg* S)
|
|||
*/
|
||||
if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
|
||||
|
||||
CodeEntry* X; /* Instruction behind N */
|
||||
CodeLabel* LX; /* Label attached to X */
|
||||
CodeEntry* X; /* Instruction behind N */
|
||||
CodeLabel* LX; /* Label attached to X */
|
||||
|
||||
/* Get the branch conditions of both branches */
|
||||
bc_t BC1 = GetBranchCond (E->OPC);
|
||||
bc_t BC2 = GetBranchCond (N->OPC);
|
||||
/* Get the branch conditions of both branches */
|
||||
bc_t BC1 = GetBranchCond (E->OPC);
|
||||
bc_t BC2 = GetBranchCond (N->OPC);
|
||||
|
||||
/* Check the branch conditions */
|
||||
if (BC1 != GetInverseCond (BC2)) {
|
||||
/* Condition not met */
|
||||
goto NextEntry;
|
||||
}
|
||||
/* Check the branch conditions */
|
||||
if (BC1 != GetInverseCond (BC2)) {
|
||||
/* Condition not met */
|
||||
goto NextEntry;
|
||||
}
|
||||
|
||||
/* We may jump behind this conditional branch. Get the
|
||||
* pointer to the next instruction
|
||||
*/
|
||||
if ((X = GetNextCodeEntry (S, GetCodeEntryIndex (S, N))) == 0) {
|
||||
/* N is the last entry, bail out */
|
||||
goto NextEntry;
|
||||
}
|
||||
/* We may jump behind this conditional branch. Get the
|
||||
* pointer to the next instruction
|
||||
*/
|
||||
if ((X = CS_GetNextEntry (S, CS_GetEntryIndex (S, N))) == 0) {
|
||||
/* N is the last entry, bail out */
|
||||
goto NextEntry;
|
||||
}
|
||||
|
||||
/* Get the label attached to X, create a new one if needed */
|
||||
LX = GenCodeLabel (S, X);
|
||||
/* Get the label attached to X, create a new one if needed */
|
||||
LX = CS_GenLabel (S, X);
|
||||
|
||||
/* Move the reference from E to the new label */
|
||||
MoveCodeLabelRef (S, E, LX);
|
||||
/* Move the reference from E to the new label */
|
||||
CS_MoveLabelRef (S, E, LX);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -336,7 +336,7 @@ unsigned OptRTS (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have less than 2 entries */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
if (Count < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -348,16 +348,16 @@ unsigned OptRTS (CodeSeg* S)
|
|||
CodeEntry* N;
|
||||
|
||||
/* Get this entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a subroutine call and if the following insn is RTS */
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
if (E->OPC == OP65_JSR &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
N->OPC == OP65_RTS) {
|
||||
|
||||
/* Change the jsr to a jmp and use the additional info for a jump */
|
||||
E->AM = AM65_BRA;
|
||||
ReplaceOPC (E, OP65_JMP);
|
||||
CE_ReplaceOPC (E, OP65_JMP);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -398,7 +398,7 @@ unsigned OptJumpTarget (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have not enough */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
if (Count < 3) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ unsigned OptJumpTarget (CodeSeg* S)
|
|||
while (I < Count-1) {
|
||||
|
||||
/* Get next entry */
|
||||
E2 = GetCodeEntry (S, I+1);
|
||||
E2 = CS_GetEntry (S, I+1);
|
||||
|
||||
/* Check if we have a jump or branch, and a matching label */
|
||||
if ((E2->Info & OF_UBRA) != 0 && E2->JumpTo) {
|
||||
|
@ -417,15 +417,15 @@ unsigned OptJumpTarget (CodeSeg* S)
|
|||
T2 = E2->JumpTo->Owner;
|
||||
|
||||
/* Get the entry preceeding this one (if possible) */
|
||||
TI = GetCodeEntryIndex (S, T2);
|
||||
TI = CS_GetEntryIndex (S, T2);
|
||||
if (TI == 0) {
|
||||
/* There is no entry before this one */
|
||||
goto NextEntry;
|
||||
}
|
||||
T1 = GetCodeEntry (S, TI-1);
|
||||
T1 = CS_GetEntry (S, TI-1);
|
||||
|
||||
/* Get the entry preceeding the jump */
|
||||
E1 = GetCodeEntry (S, I);
|
||||
E1 = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if both preceeding instructions are identical */
|
||||
if (!CodeEntriesAreEqual (E1, T1)) {
|
||||
|
@ -437,20 +437,20 @@ unsigned OptJumpTarget (CodeSeg* S)
|
|||
* This routine will create a new label if the instruction does
|
||||
* not already have one.
|
||||
*/
|
||||
TL1 = GenCodeLabel (S, T1);
|
||||
TL1 = CS_GenLabel (S, T1);
|
||||
|
||||
/* Change the jump target to point to this new label */
|
||||
MoveCodeLabelRef (S, E2, TL1);
|
||||
CS_MoveLabelRef (S, E2, TL1);
|
||||
|
||||
/* If the instruction preceeding the jump has labels attached,
|
||||
* move references to this label to the new label.
|
||||
*/
|
||||
if (CodeEntryHasLabel (E1)) {
|
||||
MoveCodeLabels (S, E1, T1);
|
||||
if (CE_HasLabel (E1)) {
|
||||
CS_MoveLabels (S, E1, T1);
|
||||
}
|
||||
|
||||
/* Remove the entry preceeding the jump */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
--Count;
|
||||
|
||||
/* Remember, we had changes */
|
||||
|
@ -471,7 +471,7 @@ NextEntry:
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Optimize conditional branches */
|
||||
/* Optimize conditional branches */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -493,7 +493,7 @@ unsigned OptCondBranches (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have not enough */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
if (Count < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -506,39 +506,39 @@ unsigned OptCondBranches (CodeSeg* S)
|
|||
CodeLabel* L;
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a register load */
|
||||
if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */
|
||||
E->AM == AM65_IMM && /* ..with immidiate addressing */
|
||||
(E->Flags & CEF_NUMARG) != 0 && /* ..and a numeric argument. */
|
||||
(N = GetNextCodeEntry (S, I)) != 0 && /* There is a following entry */
|
||||
(N->Info & OF_CBRA) != 0 && /* ..which is a conditional branch */
|
||||
!CodeEntryHasLabel (N)) { /* ..and does not have a label */
|
||||
if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */
|
||||
E->AM == AM65_IMM && /* ..with immidiate addressing */
|
||||
(E->Flags & CEF_NUMARG) != 0 && /* ..and a numeric argument. */
|
||||
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */
|
||||
(N->Info & OF_CBRA) != 0 && /* ..which is a conditional branch */
|
||||
!CE_HasLabel (N)) { /* ..and does not have a label */
|
||||
|
||||
/* Get the branch condition */
|
||||
bc_t BC = GetBranchCond (N->OPC);
|
||||
|
||||
/* Check the argument against the branch condition */
|
||||
if ((BC == BC_EQ && E->Num != 0) ||
|
||||
(BC == BC_NE && E->Num == 0) ||
|
||||
if ((BC == BC_EQ && E->Num != 0) ||
|
||||
(BC == BC_NE && E->Num == 0) ||
|
||||
(BC == BC_PL && (E->Num & 0x80) != 0) ||
|
||||
(BC == BC_MI && (E->Num & 0x80) == 0)) {
|
||||
|
||||
/* Remove the conditional branch */
|
||||
DelCodeEntry (S, I+1);
|
||||
CS_DelEntry (S, I+1);
|
||||
--Count;
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
||||
} else if ((BC == BC_EQ && E->Num == 0) ||
|
||||
(BC == BC_NE && E->Num != 0) ||
|
||||
} else if ((BC == BC_EQ && E->Num == 0) ||
|
||||
(BC == BC_NE && E->Num != 0) ||
|
||||
(BC == BC_PL && (E->Num & 0x80) == 0) ||
|
||||
(BC == BC_MI && (E->Num & 0x80) != 0)) {
|
||||
|
||||
/* The branch is always taken, replace it by a jump */
|
||||
ReplaceOPC (N, OP65_JMP);
|
||||
CE_ReplaceOPC (N, OP65_JMP);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -546,20 +546,20 @@ unsigned OptCondBranches (CodeSeg* S)
|
|||
|
||||
}
|
||||
|
||||
if ((E->Info & OF_CBRA) != 0 && /* It's a conditional branch */
|
||||
(L = E->JumpTo) != 0 && /* ..referencing a local label */
|
||||
(N = GetNextCodeEntry (S, I)) != 0 && /* There is a following entry */
|
||||
(N->Info & OF_UBRA) != 0 && /* ..which is an uncond branch, */
|
||||
!CodeEntryHasLabel (N) && /* ..has no label attached */
|
||||
L->Owner == GetNextCodeEntry (S, I+1)) {/* ..and jump target follows */
|
||||
if ((E->Info & OF_CBRA) != 0 && /* It's a conditional branch */
|
||||
(L = E->JumpTo) != 0 && /* ..referencing a local label */
|
||||
(N = CS_GetNextEntry (S, I)) != 0 && /* There is a following entry */
|
||||
(N->Info & OF_UBRA) != 0 && /* ..which is an uncond branch, */
|
||||
!CE_HasLabel (N) && /* ..has no label attached */
|
||||
L->Owner == CS_GetNextEntry (S, I+1)) {/* ..and jump target follows */
|
||||
|
||||
/* Replace the jump by a conditional branch with the inverse branch
|
||||
* condition than the branch around it.
|
||||
*/
|
||||
ReplaceOPC (N, GetInverseBranch (E->OPC));
|
||||
CE_ReplaceOPC (N, GetInverseBranch (E->OPC));
|
||||
|
||||
/* Remove the conditional branch */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
--Count;
|
||||
|
||||
/* Remember, we had changes */
|
||||
|
@ -579,7 +579,7 @@ unsigned OptCondBranches (CodeSeg* S)
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Remove unused loads */
|
||||
/* Remove unused loads */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -591,16 +591,16 @@ unsigned OptUnusedLoads (CodeSeg* S)
|
|||
|
||||
/* Walk over the entries */
|
||||
unsigned I = 0;
|
||||
while (I < GetCodeEntryCount (S)) {
|
||||
while (I < CS_GetEntryCount (S)) {
|
||||
|
||||
CodeEntry* N;
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a register load or transfer insn */
|
||||
if ((E->Info & (OF_LOAD | OF_XFR)) != 0 &&
|
||||
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
||||
(N->Info & OF_FBRA) == 0) {
|
||||
|
||||
/* Check which sort of load or transfer it is */
|
||||
|
@ -613,14 +613,14 @@ unsigned OptUnusedLoads (CodeSeg* S)
|
|||
case OP65_LDX: R = REG_X; break;
|
||||
case OP65_TAY:
|
||||
case OP65_LDY: R = REG_Y; break;
|
||||
default: goto NextEntry; /* OOPS */
|
||||
default: goto NextEntry; /* OOPS */
|
||||
}
|
||||
|
||||
/* Get register usage and check if the register value is used later */
|
||||
if ((GetRegInfo (S, I+1) & R) == 0) {
|
||||
|
||||
/* Register value is not used, remove the load */
|
||||
DelCodeEntry (S, I);
|
||||
CS_DelEntry (S, I);
|
||||
|
||||
/* Remember, we had changes */
|
||||
++Changes;
|
||||
|
@ -641,7 +641,7 @@ NextEntry:
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Optimize branch types */
|
||||
/* Optimize branch types */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -653,14 +653,14 @@ unsigned OptBranchDist (CodeSeg* S)
|
|||
unsigned I;
|
||||
|
||||
/* Get the number of entries, bail out if we have not enough */
|
||||
unsigned Count = GetCodeEntryCount (S);
|
||||
unsigned Count = CS_GetEntryCount (S);
|
||||
|
||||
/* Walk over the entries */
|
||||
I = 0;
|
||||
while (I < Count) {
|
||||
|
||||
/* Get next entry */
|
||||
CodeEntry* E = GetCodeEntry (S, I);
|
||||
CodeEntry* E = CS_GetEntry (S, I);
|
||||
|
||||
/* Check if it's a conditional branch to a local label. */
|
||||
if ((E->Info & OF_CBRA) != 0) {
|
||||
|
@ -669,7 +669,7 @@ unsigned OptBranchDist (CodeSeg* S)
|
|||
if (E->JumpTo != 0) {
|
||||
|
||||
/* Get the index of the branch target */
|
||||
unsigned TI = GetCodeEntryIndex (S, E->JumpTo->Owner);
|
||||
unsigned TI = CS_GetEntryIndex (S, E->JumpTo->Owner);
|
||||
|
||||
/* Determine the branch distance */
|
||||
int Distance = 0;
|
||||
|
@ -677,14 +677,14 @@ unsigned OptBranchDist (CodeSeg* S)
|
|||
/* Forward branch */
|
||||
unsigned J = I;
|
||||
while (J < TI) {
|
||||
CodeEntry* N = GetCodeEntry (S, J++);
|
||||
CodeEntry* N = CS_GetEntry (S, J++);
|
||||
Distance += N->Size;
|
||||
}
|
||||
} else {
|
||||
/* Backward branch */
|
||||
unsigned J = TI;
|
||||
while (J < I) {
|
||||
CodeEntry* N = GetCodeEntry (S, J++);
|
||||
CodeEntry* N = CS_GetEntry (S, J++);
|
||||
Distance += N->Size;
|
||||
}
|
||||
}
|
||||
|
@ -692,18 +692,18 @@ unsigned OptBranchDist (CodeSeg* S)
|
|||
/* Make the branch short/long according to distance */
|
||||
if ((E->Info & OF_LBRA) == 0 && Distance > 120) {
|
||||
/* Short branch but long distance */
|
||||
ReplaceOPC (E, MakeLongBranch (E->OPC));
|
||||
CE_ReplaceOPC (E, MakeLongBranch (E->OPC));
|
||||
++Changes;
|
||||
} else if ((E->Info & OF_LBRA) != 0 && Distance < 120) {
|
||||
/* Long branch but short distance */
|
||||
ReplaceOPC (E, MakeShortBranch (E->OPC));
|
||||
CE_ReplaceOPC (E, MakeShortBranch (E->OPC));
|
||||
++Changes;
|
||||
}
|
||||
|
||||
} else if ((E->Info & OF_LBRA) == 0) {
|
||||
|
||||
/* Short branch to external symbol - make it long */
|
||||
ReplaceOPC (E, MakeLongBranch (E->OPC));
|
||||
CE_ReplaceOPC (E, MakeLongBranch (E->OPC));
|
||||
++Changes;
|
||||
|
||||
}
|
||||
|
@ -720,7 +720,3 @@ unsigned OptBranchDist (CodeSeg* S)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -80,21 +80,21 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
|
|||
OF_CPU_VM | OF_UBRA /* flags */
|
||||
},
|
||||
{ OPC_LDA, /* opcode */
|
||||
"loada", /* mnemonic */
|
||||
"lda", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_NONE, /* use */
|
||||
REG_A, /* chg */
|
||||
OF_CPU_VM | OF_LOAD /* flags */
|
||||
},
|
||||
{ OPC_LDAX, /* opcode */
|
||||
"loadax", /* mnemonic */
|
||||
"ldax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_NONE, /* use */
|
||||
REG_AX, /* chg */
|
||||
OF_CPU_VM | OF_LOAD /* flags */
|
||||
},
|
||||
{ OPC_LDEAX, /* opcode */
|
||||
"loadeax", /* mnemonic */
|
||||
"ldeax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_NONE, /* use */
|
||||
REG_EAX, /* chg */
|
||||
|
@ -115,21 +115,21 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
|
|||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_PHA, /* opcode */
|
||||
"pusha", /* mnemonic */
|
||||
"pha", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_A, /* use */
|
||||
REG_NONE, /* chg */
|
||||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_PHAX, /* opcode */
|
||||
"pushax", /* mnemonic */
|
||||
"phax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_AX, /* use */
|
||||
REG_NONE, /* chg */
|
||||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_PHEAX, /* opcode */
|
||||
"pusheax", /* mnemonic */
|
||||
"pheax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_EAX, /* use */
|
||||
REG_NONE, /* chg */
|
||||
|
@ -143,21 +143,21 @@ const OPCDesc OPCTable[OPCODE_COUNT] = {
|
|||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_STA, /* opcode */
|
||||
"storea", /* mnemonic */
|
||||
"sta", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_A, /* use */
|
||||
REG_NONE, /* chg */
|
||||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_STAX, /* opcode */
|
||||
"storeax", /* mnemonic */
|
||||
"stax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_AX, /* use */
|
||||
REG_NONE, /* chg */
|
||||
OF_CPU_VM /* flags */
|
||||
},
|
||||
{ OPC_STEAX, /* opcode */
|
||||
"storeeax", /* mnemonic */
|
||||
"steax", /* mnemonic */
|
||||
0, /* size */
|
||||
REG_EAX, /* use */
|
||||
REG_NONE, /* chg */
|
||||
|
|
|
@ -187,7 +187,7 @@ struct DataSeg* GetDataSeg (void)
|
|||
case SEG_BSS: return CS->BSS;
|
||||
case SEG_DATA: return CS->Data;
|
||||
case SEG_RODATA: return CS->ROData;
|
||||
default:
|
||||
default:
|
||||
FAIL ("Invalid data segment");
|
||||
return 0;
|
||||
}
|
||||
|
@ -213,12 +213,21 @@ void AddCodeLine (const char* Format, ...)
|
|||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
CHECK (CS != 0);
|
||||
AddCodeEntry (CS->Code, CurTok.LI, Format, ap);
|
||||
CS_AddEntryLine (CS->Code, CurTok.LI, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddCode (struct CodeEntry* E)
|
||||
/* Add a code entry to the current code segment */
|
||||
{
|
||||
CHECK (CS != 0);
|
||||
CS_AddEntry (CS->Code, E, CurTok.LI);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddDataLine (const char* Format, ...)
|
||||
/* Add a line of data to the current data segment */
|
||||
{
|
||||
|
@ -251,7 +260,7 @@ void OutputSegments (const Segments* S, FILE* F)
|
|||
{
|
||||
/* If the code segment is associated with a function, print a function header */
|
||||
if (S->Code->Func) {
|
||||
PrintFunctionHeader (S->Code->Func, F);
|
||||
PrintFunctionHeader (S->Code->Func, F);
|
||||
}
|
||||
|
||||
/* Output the text segment */
|
||||
|
@ -263,7 +272,7 @@ void OutputSegments (const Segments* S, FILE* F)
|
|||
OutputDataSeg (S->BSS, F);
|
||||
|
||||
/* Output the code segment */
|
||||
OutputCodeSeg (S->Code, F);
|
||||
CS_Output (S->Code, F);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,11 +46,12 @@
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
struct CodeEntry;
|
||||
struct CodeSeg;
|
||||
struct DataSeg;
|
||||
struct TextSeg;
|
||||
|
@ -122,6 +123,9 @@ void AddTextLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
|||
void AddCodeLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
/* Add a line of code to the current code segment */
|
||||
|
||||
void AddCode (struct CodeEntry* E);
|
||||
/* Add a code entry to the current code segment */
|
||||
|
||||
void AddDataLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||
/* Add a line of data to the current data segment */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue