1
0
mirror of https://github.com/cc65/cc65.git synced 2025-02-02 00:35:32 +00:00

Working on the backend

git-svn-id: svn://svn.cc65.org/cc65/trunk@762 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-28 06:30:03 +00:00
parent 034a4b75e5
commit 369f59c1bb
8 changed files with 419 additions and 421 deletions

View File

@ -140,7 +140,7 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
* lookup the information about this function and use it. The jump itself
* does not change any registers, so we don't need to use the data from D.
*/
if (E->OPC == OPC_JSR || ((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
if ((E->Info & (OF_BRA | OF_CALL)) != 0 && E->JumpTo == 0) {
/* A subroutine call or jump to external symbol (function exit) */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else {
@ -175,8 +175,8 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg,
E->AM = AM;
E->Arg = GetArgCopy (Arg);
E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0;
E->Size = GetInsnSize (E->OPC, E->AM);
E->Info = D->Info;
E->Size = GetInsnSize (E->OPC, E->AM);
E->JumpTo = JumpTo;
E->LI = UseLineInfo (LI);
SetUseChgInfo (E, D);
@ -221,8 +221,8 @@ void ReplaceOPC (CodeEntry* E, opc_t OPC)
/* Replace the opcode */
E->OPC = OPC;
E->Size = GetInsnSize (E->OPC, E->AM);
E->Info = D->Info;
E->Size = GetInsnSize (E->OPC, E->AM);
SetUseChgInfo (E, D);
}
@ -296,53 +296,53 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F)
/* Print the operand */
switch (E->AM) {
case AM_IMP:
case AM65_IMP:
/* implicit */
break;
case AM_ACC:
case AM65_ACC:
/* accumulator */
Chars += fprintf (F, "%*sa", 9-Chars, "");
break;
case AM_IMM:
case AM65_IMM:
/* immidiate */
Chars += fprintf (F, "%*s#%s", 9-Chars, "", E->Arg);
break;
case AM_ZP:
case AM_ABS:
case AM65_ZP:
case AM65_ABS:
/* zeropage and absolute */
Chars += fprintf (F, "%*s%s", 9-Chars, "", E->Arg);
break;
case AM_ZPX:
case AM_ABSX:
case AM65_ZPX:
case AM65_ABSX:
/* zeropage,X and absolute,X */
Chars += fprintf (F, "%*s%s,x", 9-Chars, "", E->Arg);
break;
case AM_ABSY:
case AM65_ABSY:
/* absolute,Y */
Chars += fprintf (F, "%*s%s,y", 9-Chars, "", E->Arg);
break;
case AM_ZPX_IND:
case AM65_ZPX_IND:
/* (zeropage,x) */
Chars += fprintf (F, "%*s(%s,x)", 9-Chars, "", E->Arg);
break;
case AM_ZP_INDY:
case AM65_ZP_INDY:
/* (zeropage),y */
Chars += fprintf (F, "%*s(%s),y", 9-Chars, "", E->Arg);
break;
case AM_ZP_IND:
case AM65_ZP_IND:
/* (zeropage) */
Chars += fprintf (F, "%*s(%s)", 9-Chars, "", E->Arg);
break;
case AM_BRA:
case AM65_BRA:
/* branch */
Target = E->JumpTo? E->JumpTo->Name : E->Arg;
Chars += fprintf (F, "%*s%s", 9-Chars, "", Target);

View File

@ -69,8 +69,8 @@ struct CodeEntry {
char* Arg; /* Argument as string */
unsigned long Num; /* Numeric argument */
unsigned short Flags; /* Flags */
unsigned short Info; /* Additional code info */
unsigned char Size; /* Estimated size */
unsigned char Info; /* Additional code info */
unsigned char Use; /* Registers used */
unsigned char Chg; /* Registers changed/destroyed */
CodeLabel* JumpTo; /* Jump label */

View File

@ -167,7 +167,7 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
/* Did we find it in the top level table? */
if (E && IsTypeFunc (E->Type)) {
/* A function may use the A or A/X registers if it is a fastcall
* function. If it is not a fastcall function but a variadic one,
* it will use the Y register (the parameter size is passed here).
@ -266,7 +266,7 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
/* Evaluate the used registers */
R = E->Use;
if (E->OPC == OPC_RTS ||
if (E->OPC == OP65_RTS ||
((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
/* This instruction will leave the function */
R |= S->ExitRegs;
@ -296,7 +296,7 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
}
/* If the instruction is an RTS or RTI, we're done */
if (E->OPC == OPC_RTS || E->OPC == OPC_RTI) {
if (E->OPC == OP65_RTS || E->OPC == OP65_RTI) {
break;
}

View File

@ -167,11 +167,11 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
switch (Cond) {
case CMP_EQ:
ReplaceOPC (E, OPC_JEQ);
ReplaceOPC (E, OP65_JEQ);
break;
case CMP_NE:
ReplaceOPC (E, OPC_JNE);
ReplaceOPC (E, OP65_JNE);
break;
case CMP_GT:
@ -185,17 +185,17 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
Internal ("Invalid program flow");
}
L = GenCodeLabel (S, N);
N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI);
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
InsertCodeEntry (S, N, I);
ReplaceOPC (E, OPC_JPL);
ReplaceOPC (E, OP65_JPL);
break;
case CMP_GE:
ReplaceOPC (E, OPC_JPL);
ReplaceOPC (E, OP65_JPL);
break;
case CMP_LT:
ReplaceOPC (E, OPC_JMI);
ReplaceOPC (E, OP65_JMI);
break;
case CMP_LE:
@ -203,9 +203,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
* jmi Target
* jeq Target
*/
ReplaceOPC (E, OPC_JMI);
ReplaceOPC (E, OP65_JMI);
L = E->JumpTo;
N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI);
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
InsertCodeEntry (S, N, I+1);
break;
@ -220,17 +220,17 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
Internal ("Invalid program flow");
}
L = GenCodeLabel (S, N);
N = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L, E->LI);
N = NewCodeEntry (OP65_BEQ, AM65_BRA, L->Name, L, E->LI);
InsertCodeEntry (S, N, I);
ReplaceOPC (E, OPC_JCS);
ReplaceOPC (E, OP65_JCS);
break;
case CMP_UGE:
ReplaceOPC (E, OPC_JCS);
ReplaceOPC (E, OP65_JCS);
break;
case CMP_ULT:
ReplaceOPC (E, OPC_JCC);
ReplaceOPC (E, OP65_JCC);
break;
case CMP_ULE:
@ -238,9 +238,9 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
* jcc Target
* jeq Target
*/
ReplaceOPC (E, OPC_JCC);
ReplaceOPC (E, OP65_JCC);
L = E->JumpTo;
N = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L, E->LI);
N = NewCodeEntry (OP65_JEQ, AM65_BRA, L->Name, L, E->LI);
InsertCodeEntry (S, N, I+1);
break;
@ -253,19 +253,10 @@ static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
static int IsUnsignedCmp (int Code)
/* Check if this is an unsigned compare */
{
CHECK (Code >= 0);
return CmpSignedTab [Code] == 0;
}
static int IsBitOp (const CodeEntry* E)
/* Check if E is one of the bit operations (and, or, eor) */
{
return (E->OPC == OPC_AND || E->OPC == OPC_ORA || E->OPC == OPC_EOR);
return (E->OPC == OP65_AND || E->OPC == OP65_ORA || E->OPC == OP65_EOR);
}
@ -273,8 +264,8 @@ static int IsBitOp (const CodeEntry* E)
static int IsCmpToZero (const CodeEntry* E)
/* Check if the given instrcuction is a compare to zero instruction */
{
return (E->OPC == OPC_CMP &&
E->AM == AM_IMM &&
return (E->OPC == OP65_CMP &&
E->AM == AM65_IMM &&
(E->Flags & CEF_NUMARG) != 0 &&
E->Num == 0);
}
@ -284,7 +275,7 @@ static int IsCmpToZero (const CodeEntry* E)
static int IsSpLoad (const CodeEntry* E)
/* Return true if this is the load of A from the stack */
{
return E->OPC == OPC_LDA && E->AM == AM_ZP_INDY && strcmp (E->Arg, "sp") == 0;
return E->OPC == OP65_LDA && E->AM == AM65_ZP_INDY && strcmp (E->Arg, "sp") == 0;
}
@ -310,15 +301,15 @@ static int IsLocalLoad16 (CodeSeg* S, unsigned Index,
L[0] = GetCodeEntry (S, Index);
/* Check for the sequence */
return (L[0]->OPC == OPC_LDY &&
L[0]->AM == AM_IMM &&
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 == OPC_TAX &&
L[2]->OPC == OP65_TAX &&
!CodeEntryHasLabel (L[2]) &&
L[3]->OPC == OPC_DEY &&
L[3]->OPC == OP65_DEY &&
!CodeEntryHasLabel (L[3]) &&
IsSpLoad (L[4]) &&
!CodeEntryHasLabel (L[4]));
@ -332,18 +323,18 @@ static int IsImmCmp16 (CodeSeg* S, CodeEntry** L)
*
*/
{
return (L[0]->OPC == OPC_CPX &&
L[0]->AM == AM_IMM &&
(L[0]->Flags & CEF_NUMARG) != 0 &&
!CodeEntryHasLabel (L[0]) &&
(L[1]->OPC == OPC_JNE || L[1]->OPC == OPC_BNE) &&
L[1]->JumpTo != 0 &&
!CodeEntryHasLabel (L[1]) &&
L[2]->OPC == OPC_CMP &&
L[2]->AM == AM_IMM &&
(L[2]->Flags & CEF_NUMARG) != 0 &&
(L[3]->Info & OF_ZBRA) != 0 &&
L[3]->JumpTo != 0 &&
return (L[0]->OPC == OP65_CPX &&
L[0]->AM == AM65_IMM &&
(L[0]->Flags & CEF_NUMARG) != 0 &&
!CodeEntryHasLabel (L[0]) &&
(L[1]->OPC == OP65_JNE || L[1]->OPC == OP65_BNE) &&
L[1]->JumpTo != 0 &&
!CodeEntryHasLabel (L[1]) &&
L[2]->OPC == OP65_CMP &&
L[2]->AM == AM65_IMM &&
(L[2]->Flags & CEF_NUMARG) != 0 &&
(L[3]->Info & OF_ZBRA) != 0 &&
L[3]->JumpTo != 0 &&
(L[1]->JumpTo->Owner == L[3] || L[1]->JumpTo == L[3]->JumpTo));
}
@ -373,7 +364,7 @@ static unsigned OptBoolTransforms (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for a boolean transformer */
if (E->OPC == OPC_JSR &&
if (E->OPC == OP65_JSR &&
(Cond = FindBoolCmpCond (E->Arg)) != CMP_INV &&
(N = GetNextCodeEntry (S, I)) != 0 &&
(N->Info & OF_ZBRA) != 0) {
@ -440,14 +431,14 @@ static unsigned OptSub1 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_SBC &&
GetCodeEntries (S, L, I+1, 3) &&
(L[0]->OPC == OPC_BCS || L[0]->OPC == OPC_JCS) &&
L[0]->JumpTo != 0 &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OPC_DEX &&
!CodeEntryHasLabel (L[1]) &&
L[0]->JumpTo->Owner == L[2] &&
if (E->OPC == OP65_SBC &&
GetCodeEntries (S, L, I+1, 3) &&
(L[0]->OPC == OP65_BCS || L[0]->OPC == OP65_JCS) &&
L[0]->JumpTo != 0 &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OP65_DEX &&
!CodeEntryHasLabel (L[1]) &&
L[0]->JumpTo->Owner == L[2] &&
!RegXUsed (S, I+3)) {
/* Remove the bcs/dex */
@ -499,19 +490,19 @@ static unsigned OptSub2 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_LDA &&
if (E->OPC == OP65_LDA &&
GetCodeEntries (S, L, I+1, 5) &&
L[0]->OPC == OPC_SEC &&
L[0]->OPC == OP65_SEC &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OPC_STA &&
L[1]->OPC == OP65_STA &&
strcmp (L[1]->Arg, "tmp1") == 0 &&
!CodeEntryHasLabel (L[1]) &&
L[2]->OPC == OPC_LDA &&
L[2]->OPC == OP65_LDA &&
!CodeEntryHasLabel (L[2]) &&
L[3]->OPC == OPC_SBC &&
L[3]->OPC == OP65_SBC &&
strcmp (L[3]->Arg, "tmp1") == 0 &&
!CodeEntryHasLabel (L[3]) &&
L[4]->OPC == OPC_STA &&
L[4]->OPC == OP65_STA &&
strcmp (L[4]->Arg, L[2]->Arg) == 0 &&
!CodeEntryHasLabel (L[4])) {
@ -525,7 +516,7 @@ static unsigned OptSub2 (CodeSeg* S)
* op to SBC.
*/
MoveCodeEntry (S, I, I+3);
ReplaceOPC (E, OPC_SBC);
ReplaceOPC (E, OP65_SBC);
/* If the sequence head had a label, move this label back to the
* head.
@ -579,14 +570,14 @@ static unsigned OptAdd1 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_ADC &&
GetCodeEntries (S, L, I+1, 3) &&
(L[0]->OPC == OPC_BCC || L[0]->OPC == OPC_JCC) &&
L[0]->JumpTo != 0 &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OPC_INX &&
!CodeEntryHasLabel (L[1]) &&
L[0]->JumpTo->Owner == L[2] &&
if (E->OPC == OP65_ADC &&
GetCodeEntries (S, L, I+1, 3) &&
(L[0]->OPC == OP65_BCC || L[0]->OPC == OP65_JCC) &&
L[0]->JumpTo != 0 &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OP65_INX &&
!CodeEntryHasLabel (L[1]) &&
L[0]->JumpTo->Owner == L[2] &&
!RegXUsed (S, I+3)) {
/* Remove the bcs/dex */
@ -639,12 +630,12 @@ static unsigned OptCmp1 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_STX &&
if (E->OPC == OP65_STX &&
GetCodeEntries (S, L, I+1, 2) &&
L[0]->OPC == OPC_STX &&
L[0]->OPC == OP65_STX &&
strcmp (L[0]->Arg, "tmp1") == 0 &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OPC_ORA &&
L[1]->OPC == OP65_ORA &&
strcmp (L[1]->Arg, "tmp1") == 0 &&
!CodeEntryHasLabel (L[1])) {
@ -652,7 +643,7 @@ static unsigned OptCmp1 (CodeSeg* S)
DelCodeEntries (S, I+1, 2);
/* Insert the ora instead */
InsertCodeEntry (S, NewCodeEntry (OPC_ORA, E->AM, E->Arg, 0, E->LI), I+1);
InsertCodeEntry (S, NewCodeEntry (OP65_ORA, E->AM, E->Arg, 0, E->LI), I+1);
/* Remember, we had changes */
++Changes;
@ -692,7 +683,7 @@ static unsigned OptCmp2 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if ((E->OPC == OPC_LDA || IsBitOp (E)) &&
if ((E->OPC == OP65_LDA || IsBitOp (E)) &&
GetCodeEntries (S, L, I+1, 2) &&
IsCmpToZero (L[0]) &&
!CodeEntryHasLabel (L[0]) &&
@ -751,15 +742,15 @@ static unsigned OptCmp3 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_LDA &&
GetCodeEntries (S, L, I+1, 5) &&
L[0]->OPC == OPC_LDX &&
!CodeEntryHasLabel (L[0]) &&
if (E->OPC == OP65_LDA &&
GetCodeEntries (S, L, I+1, 5) &&
L[0]->OPC == OP65_LDX &&
!CodeEntryHasLabel (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], OPC_ORA);
ReplaceOPC (L[0], OP65_ORA);
DelCodeEntries (S, I+2, 3);
} else {
/* Move the lda instruction after the first branch. This will
@ -769,8 +760,8 @@ static unsigned OptCmp3 (CodeSeg* S)
MoveCodeEntry (S, I, I+4);
/* We will replace the ldx/cpx by lda/cmp */
ReplaceOPC (L[0], OPC_LDA);
ReplaceOPC (L[1], OPC_CMP);
ReplaceOPC (L[0], OP65_LDA);
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.
@ -829,7 +820,7 @@ static unsigned OptCmp4 (CodeSeg* S)
* ora (sp),y
* jne/jeq ...
*/
ReplaceOPC (L[4], OPC_ORA);
ReplaceOPC (L[4], OP65_ORA);
DelCodeEntries (S, I+5, 3); /* cpx/bne/cmp */
DelCodeEntry (S, I+2); /* tax */
@ -848,7 +839,7 @@ static unsigned OptCmp4 (CodeSeg* S)
* jne/jeq ...
*/
DelCodeEntry (S, I+2); /* tax */
ReplaceOPC (L[5], OPC_CMP); /* cpx -> cmp */
ReplaceOPC (L[5], OP65_CMP); /* cpx -> cmp */
MoveCodeEntry (S, I+4, I+2); /* cmp */
MoveCodeEntry (S, I+5, I+3); /* bne */
@ -888,7 +879,7 @@ static unsigned OptCmp5 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_JSR &&
if (E->OPC == OP65_JSR &&
(Cond = FindTosCmpCond (E->Arg)) != CMP_INV &&
(N = GetNextCodeEntry (S, I)) != 0 &&
(N->Info & OF_ZBRA) != 0 &&
@ -907,7 +898,7 @@ static unsigned OptCmp5 (CodeSeg* S)
}
/* Replace the subroutine call. */
E = NewCodeEntry (OPC_JSR, AM_ABS, "tosicmp", 0, E->LI);
E = NewCodeEntry (OP65_JSR, AM65_ABS, "tosicmp", 0, E->LI);
InsertCodeEntry (S, E, I+1);
DelCodeEntry (S, I);
@ -958,14 +949,14 @@ static unsigned OptNegA1 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for a ldx */
if (E->OPC == OPC_LDX &&
E->AM == AM_IMM &&
if (E->OPC == OP65_LDX &&
E->AM == AM65_IMM &&
(E->Flags & CEF_NUMARG) != 0 &&
E->Num == 0 &&
GetCodeEntries (S, L, I+1, 2) &&
L[0]->OPC == OPC_LDA &&
L[0]->OPC == OP65_LDA &&
(L[0]->Use & REG_X) == 0 &&
L[1]->OPC == OPC_JSR &&
L[1]->OPC == OP65_JSR &&
strcmp (L[1]->Arg, "bnega") == 0) {
/* Remove the ldx instruction */
@ -1009,9 +1000,9 @@ static unsigned OptNegA2 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_LDA &&
if (E->OPC == OP65_LDA &&
GetCodeEntries (S, L, I+1, 2) &&
L[0]->OPC == OPC_JSR &&
L[0]->OPC == OP65_JSR &&
strcmp (L[0]->Arg, "bnega") == 0 &&
!CodeEntryHasLabel (L[0]) &&
(L[1]->Info & OF_ZBRA) != 0) {
@ -1074,22 +1065,22 @@ static unsigned OptNegAX1 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_LDA &&
E->AM == AM_ZP_INDY &&
if (E->OPC == OP65_LDA &&
E->AM == AM65_ZP_INDY &&
GetCodeEntries (S, L, I+1, 5) &&
L[0]->OPC == OPC_TAX &&
L[1]->OPC == OPC_DEY &&
L[2]->OPC == OPC_LDA &&
L[2]->AM == AM_ZP_INDY &&
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]) &&
L[3]->OPC == OPC_JSR &&
L[3]->OPC == OP65_JSR &&
strcmp (L[3]->Arg, "bnegax") == 0 &&
!CodeEntryHasLabel (L[3]) &&
(L[4]->Info & OF_ZBRA) != 0) {
/* lda --> ora */
ReplaceOPC (L[2], OPC_ORA);
ReplaceOPC (L[2], OP65_ORA);
/* Invert the branch */
ReplaceOPC (L[4], GetInverseBranch (L[4]->OPC));
@ -1143,17 +1134,17 @@ static unsigned OptNegAX2 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_LDA &&
if (E->OPC == OP65_LDA &&
GetCodeEntries (S, L, I+1, 3) &&
L[0]->OPC == OPC_LDX &&
L[0]->OPC == OP65_LDX &&
!CodeEntryHasLabel (L[0]) &&
L[1]->OPC == OPC_JSR &&
L[1]->OPC == OP65_JSR &&
strcmp (L[1]->Arg, "bnegax") == 0 &&
!CodeEntryHasLabel (L[1]) &&
(L[2]->Info & OF_ZBRA) != 0) {
/* ldx --> ora */
ReplaceOPC (L[0], OPC_ORA);
ReplaceOPC (L[0], OP65_ORA);
/* Invert the branch */
ReplaceOPC (L[2], GetInverseBranch (L[2]->OPC));
@ -1203,10 +1194,10 @@ static unsigned OptNegAX3 (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check for the sequence */
if (E->OPC == OPC_JSR &&
E->Arg[0] == '_' &&
if (E->OPC == OP65_JSR &&
E->Arg[0] == '_' &&
GetCodeEntries (S, L, I+1, 2) &&
L[0]->OPC == OPC_JSR &&
L[0]->OPC == OP65_JSR &&
strncmp (L[0]->Arg,"bnega",5) == 0 &&
!CodeEntryHasLabel (L[0]) &&
(L[1]->Info & OF_ZBRA) != 0) {
@ -1219,13 +1210,13 @@ static unsigned OptNegAX3 (CodeSeg* S)
/* Insert apropriate test code */
if (ByteSized) {
/* Test bytes */
X = NewCodeEntry (OPC_TAX, AM_IMP, 0, 0, L[0]->LI);
X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[0]->LI);
InsertCodeEntry (S, X, I+2);
} else {
/* Test words */
X = NewCodeEntry (OPC_STX, AM_ZP, "tmp1", 0, L[0]->LI);
X = NewCodeEntry (OP65_STX, AM65_ZP, "tmp1", 0, L[0]->LI);
InsertCodeEntry (S, X, I+2);
X = NewCodeEntry (OPC_ORA, AM_ZP, "tmp1", 0, L[0]->LI);
X = NewCodeEntry (OP65_ORA, AM65_ZP, "tmp1", 0, L[0]->LI);
InsertCodeEntry (S, X, I+3);
}

View File

@ -221,13 +221,13 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
case '\0':
/* Implicit */
AM = AM_IMP;
AM = AM65_IMP;
break;
case '#':
/* Immidiate */
StrCopy (Arg, sizeof (Arg), L+1);
AM = AM_IMM;
AM = AM65_IMM;
break;
case '(':
@ -258,7 +258,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
Error ("ASM code error: syntax error");
return 0;
}
AM = AM_ZPX_IND;
AM = AM65_ZPX_IND;
} else if (*L == ')') {
/* zp indirect or zp indirect, y */
L = SkipSpace (L+1);
@ -273,9 +273,9 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
Error ("ASM code error: syntax error");
return 0;
}
AM = AM_ZP_INDY;
AM = AM65_ZP_INDY;
} else if (*L == '\0') {
AM = AM_ZP_IND;
AM = AM65_ZP_IND;
} else {
Error ("ASM code error: syntax error");
return 0;
@ -287,7 +287,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
case 'A':
/* Accumulator? */
if (L[1] == '\0') {
AM = AM_ACC;
AM = AM65_ACC;
break;
}
/* FALLTHROUGH */
@ -299,11 +299,11 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
/* Absolute, zeropage or branch */
if ((OPC->Info & OF_BRA) != 0) {
/* Branch */
AM = AM_BRA;
AM = AM65_BRA;
} else if (IsZPName (Arg)) {
AM = AM_ZP;
AM = AM65_ZP;
} else {
AM = AM_ABS;
AM = AM65_ABS;
}
} else if (*L == ',') {
/* Indexed */
@ -316,12 +316,12 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
L = SkipSpace (L+1);
if (Reg == 'X') {
if (IsZPName (Arg)) {
AM = AM_ZPX;
AM = AM65_ZPX;
} else {
AM = AM_ABSX;
AM = AM65_ABSX;
}
} else if (Reg == 'Y') {
AM = AM_ABSY;
AM = AM65_ABSY;
} else {
Error ("ASM code error: syntax error");
return 0;
@ -340,7 +340,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
* if it does not exist. Ignore anything but local labels here.
*/
Label = 0;
if (AM == AM_BRA && Arg[0] == 'L') {
if (AM == AM65_BRA && Arg[0] == 'L') {
/* Generate the hash over the label, then search for the label */
unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE;

View File

@ -65,10 +65,10 @@ unsigned OptRTSJumps (CodeSeg* S)
/* Check if it's an unconditional branch to a local target */
if ((E->Info & OF_UBRA) != 0 &&
E->JumpTo != 0 &&
E->JumpTo->Owner->OPC == OPC_RTS) {
E->JumpTo->Owner->OPC == OP65_RTS) {
/* Insert an RTS instruction */
CodeEntry* X = NewCodeEntry (OPC_RTS, AM_IMP, 0, 0, E->LI);
CodeEntry* X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->LI);
InsertCodeEntry (S, X, I+1);
/* Delete the jump */
@ -119,7 +119,7 @@ unsigned OptDeadJumps (CodeSeg* S)
/* Check if it's a branch, if it has a local target, and if the target
* is the next instruction.
*/
if (E->AM == AM_BRA && E->JumpTo && E->JumpTo->Owner == GetCodeEntry (S, I+1)) {
if (E->AM == AM65_BRA && E->JumpTo && E->JumpTo->Owner == GetCodeEntry (S, I+1)) {
/* Delete the dead jump */
DelCodeEntry (S, I);
@ -351,13 +351,13 @@ unsigned OptRTS (CodeSeg* S)
CodeEntry* E = GetCodeEntry (S, I);
/* Check if it's a subroutine call and if the following insn is RTS */
if (E->OPC == OPC_JSR &&
if (E->OPC == OP65_JSR &&
(N = GetNextCodeEntry (S, I)) != 0 &&
N->OPC == OPC_RTS) {
N->OPC == OP65_RTS) {
/* Change the jsr to a jmp and use the additional info for a jump */
E->AM = AM_BRA;
ReplaceOPC (E, OPC_JMP);
E->AM = AM65_BRA;
ReplaceOPC (E, OP65_JMP);
/* Remember, we had changes */
++Changes;
@ -510,7 +510,7 @@ unsigned OptCondBranches (CodeSeg* S)
/* Check if it's a register load */
if ((E->Info & OF_LOAD) != 0 && /* It's a load instruction */
E->AM == AM_IMM && /* ..with immidiate addressing */
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 */
@ -538,7 +538,7 @@ unsigned OptCondBranches (CodeSeg* S)
(BC == BC_MI && (E->Num & 0x80) != 0)) {
/* The branch is always taken, replace it by a jump */
ReplaceOPC (N, OPC_JMP);
ReplaceOPC (N, OP65_JMP);
/* Remember, we had changes */
++Changes;
@ -606,13 +606,13 @@ unsigned OptUnusedLoads (CodeSeg* S)
/* Check which sort of load or transfer it is */
unsigned R;
switch (E->OPC) {
case OPC_TXA:
case OPC_TYA:
case OPC_LDA: R = REG_A; break;
case OPC_TAX:
case OPC_LDX: R = REG_X; break;
case OPC_TAY:
case OPC_LDY: R = REG_Y; break;
case OP65_TXA:
case OP65_TYA:
case OP65_LDA: R = REG_A; break;
case OP65_TAX:
case OP65_LDX: R = REG_X; break;
case OP65_TAY:
case OP65_LDY: R = REG_Y; break;
default: goto NextEntry; /* OOPS */
}

View File

@ -55,80 +55,82 @@
/* Opcode description table */
const OPCDesc OPCTable[OPC_COUNT] = {
{ OPC_ADC, "adc", 0, REG_A, REG_A, OF_NONE },
{ OPC_AND, "and", 0, REG_A, REG_A, OF_NONE },
{ OPC_ASL, "asl", 0, REG_A, REG_A, OF_NONE },
{ OPC_BCC, "bcc", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OPC_BCS, "bcs", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OPC_BEQ, "beq", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
{ OPC_BIT, "bit", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_BMI, "bmi", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
{ OPC_BNE, "bne", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
{ OPC_BPL, "bpl", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
{ OPC_BRA, "bra", 2, REG_NONE, REG_NONE, OF_UBRA },
{ OPC_BRK, "brk", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_BVC, "bvc", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OPC_BVS, "bvs", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OPC_CLC, "clc", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_CLD, "cld", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_CLI, "cli", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_CLV, "clv", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_CMP, "cmp", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_CPX, "cpx", 0, REG_X, REG_NONE, OF_NONE },
{ OPC_CPY, "cpy", 0, REG_Y, REG_NONE, OF_NONE },
{ OPC_DEA, "dea", 1, REG_A, REG_A, OF_NONE },
{ OPC_DEC, "dec", 0, REG_NONE, REG_NONE, OF_NONE },
{ OPC_DEX, "dex", 1, REG_X, REG_X, OF_NONE },
{ OPC_DEY, "dey", 1, REG_Y, REG_Y, OF_NONE },
{ OPC_EOR, "eor", 0, REG_A, REG_A, OF_NONE },
{ OPC_INA, "ina", 1, REG_A, REG_A, OF_NONE },
{ OPC_INC, "inc", 0, REG_NONE, REG_NONE, OF_NONE },
{ OPC_INX, "inx", 1, REG_X, REG_X, OF_NONE },
{ OPC_INY, "iny", 1, REG_Y, REG_Y, OF_NONE },
{ OPC_JCC, "jcc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OPC_JCS, "jcs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OPC_JEQ, "jeq", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
{ OPC_JMI, "jmi", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
{ OPC_JMP, "jmp", 3, REG_NONE, REG_NONE, OF_UBRA | OF_LBRA },
{ OPC_JNE, "jne", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
{ OPC_JPL, "jpl", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
{ OPC_JSR, "jsr", 3, REG_NONE, REG_NONE, OF_NONE },
{ OPC_JVC, "jvc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OPC_JVS, "jvs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OPC_LDA, "lda", 0, REG_NONE, REG_A, OF_LOAD },
{ OPC_LDX, "ldx", 0, REG_NONE, REG_X, OF_LOAD },
{ OPC_LDY, "ldy", 0, REG_NONE, REG_Y, OF_LOAD },
{ OPC_LSR, "lsr", 0, REG_A, REG_A, OF_NONE },
{ OPC_NOP, "nop", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_ORA, "ora", 0, REG_A, REG_A, OF_NONE },
{ OPC_PHA, "pha", 1, REG_A, REG_NONE, OF_NONE },
{ OPC_PHP, "php", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_PHX, "phx", 1, REG_X, REG_NONE, OF_NONE },
{ OPC_PHY, "phy", 1, REG_Y, REG_NONE, OF_NONE },
{ OPC_PLA, "pla", 1, REG_NONE, REG_A, OF_NONE },
{ OPC_PLP, "plp", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_PLX, "plx", 1, REG_NONE, REG_X, OF_NONE },
{ OPC_PLY, "ply", 1, REG_NONE, REG_Y, OF_NONE },
{ OPC_ROL, "rol", 0, REG_A, REG_A, OF_NONE },
{ OPC_ROR, "ror", 0, REG_A, REG_A, OF_NONE },
{ OPC_RTI, "rti", 1, REG_NONE, REG_NONE, OF_RET },
{ OPC_RTS, "rts", 1, REG_NONE, REG_NONE, OF_RET },
{ OPC_SBC, "sbc", 0, REG_A, REG_A, OF_NONE },
{ OPC_SEC, "sec", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_SED, "sed", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_SEI, "sei", 1, REG_NONE, REG_NONE, OF_NONE },
{ OPC_STA, "sta", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_STX, "stx", 0, REG_X, REG_NONE, OF_NONE },
{ OPC_STY, "sty", 0, REG_Y, REG_NONE, OF_NONE },
{ OPC_TAX, "tax", 1, REG_A, REG_X, OF_XFR },
{ OPC_TAY, "tay", 1, REG_A, REG_Y, OF_XFR },
{ OPC_TRB, "trb", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_TSB, "tsb", 0, REG_A, REG_NONE, OF_NONE },
{ OPC_TSX, "tsx", 1, REG_NONE, REG_X, OF_XFR },
{ OPC_TXA, "txa", 1, REG_X, REG_A, OF_XFR },
{ OPC_TXS, "txs", 1, REG_X, REG_NONE, OF_XFR },
{ OPC_TYA, "tya", 1, REG_A, REG_A, OF_XFR },
const OPCDesc OPCTable[OPCODE_COUNT] = {
/* 65XX opcodes */
{ OP65_ADC, "adc", 0, REG_A, REG_A, OF_NONE },
{ OP65_AND, "and", 0, REG_A, REG_A, OF_NONE },
{ OP65_ASL, "asl", 0, REG_A, REG_A, OF_NONE },
{ OP65_BCC, "bcc", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OP65_BCS, "bcs", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OP65_BEQ, "beq", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
{ OP65_BIT, "bit", 0, REG_A, REG_NONE, OF_NONE },
{ OP65_BMI, "bmi", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
{ OP65_BNE, "bne", 2, REG_NONE, REG_NONE, OF_CBRA | OF_ZBRA | OF_FBRA },
{ OP65_BPL, "bpl", 2, REG_NONE, REG_NONE, OF_CBRA | OF_FBRA },
{ OP65_BRA, "bra", 2, REG_NONE, REG_NONE, OF_UBRA },
{ OP65_BRK, "brk", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_BVC, "bvc", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OP65_BVS, "bvs", 2, REG_NONE, REG_NONE, OF_CBRA },
{ OP65_CLC, "clc", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_CLD, "cld", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_CLI, "cli", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_CLV, "clv", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_CMP, "cmp", 0, REG_A, REG_NONE, OF_NONE },
{ OP65_CPX, "cpx", 0, REG_X, REG_NONE, OF_NONE },
{ OP65_CPY, "cpy", 0, REG_Y, REG_NONE, OF_NONE },
{ OP65_DEA, "dea", 1, REG_A, REG_A, OF_NONE },
{ OP65_DEC, "dec", 0, REG_NONE, REG_NONE, OF_NONE },
{ OP65_DEX, "dex", 1, REG_X, REG_X, OF_NONE },
{ OP65_DEY, "dey", 1, REG_Y, REG_Y, OF_NONE },
{ OP65_EOR, "eor", 0, REG_A, REG_A, OF_NONE },
{ OP65_INA, "ina", 1, REG_A, REG_A, OF_NONE },
{ OP65_INC, "inc", 0, REG_NONE, REG_NONE, OF_NONE },
{ OP65_INX, "inx", 1, REG_X, REG_X, OF_NONE },
{ OP65_INY, "iny", 1, REG_Y, REG_Y, OF_NONE },
{ OP65_JCC, "jcc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OP65_JCS, "jcs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OP65_JEQ, "jeq", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
{ OP65_JMI, "jmi", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
{ OP65_JMP, "jmp", 3, REG_NONE, REG_NONE, OF_UBRA | OF_LBRA },
{ OP65_JNE, "jne", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_ZBRA | OF_FBRA },
{ OP65_JPL, "jpl", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA | OF_FBRA },
{ OP65_JSR, "jsr", 3, REG_NONE, REG_NONE, OF_CALL },
{ OP65_JVC, "jvc", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OP65_JVS, "jvs", 5, REG_NONE, REG_NONE, OF_CBRA | OF_LBRA },
{ OP65_LDA, "lda", 0, REG_NONE, REG_A, OF_LOAD },
{ OP65_LDX, "ldx", 0, REG_NONE, REG_X, OF_LOAD },
{ OP65_LDY, "ldy", 0, REG_NONE, REG_Y, OF_LOAD },
{ OP65_LSR, "lsr", 0, REG_A, REG_A, OF_NONE },
{ OP65_NOP, "nop", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_ORA, "ora", 0, REG_A, REG_A, OF_NONE },
{ OP65_PHA, "pha", 1, REG_A, REG_NONE, OF_NONE },
{ OP65_PHP, "php", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_PHX, "phx", 1, REG_X, REG_NONE, OF_NONE },
{ OP65_PHY, "phy", 1, REG_Y, REG_NONE, OF_NONE },
{ OP65_PLA, "pla", 1, REG_NONE, REG_A, OF_NONE },
{ OP65_PLP, "plp", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_PLX, "plx", 1, REG_NONE, REG_X, OF_NONE },
{ OP65_PLY, "ply", 1, REG_NONE, REG_Y, OF_NONE },
{ OP65_ROL, "rol", 0, REG_A, REG_A, OF_NONE },
{ OP65_ROR, "ror", 0, REG_A, REG_A, OF_NONE },
{ OP65_RTI, "rti", 1, REG_NONE, REG_NONE, OF_RET },
{ OP65_RTS, "rts", 1, REG_NONE, REG_NONE, OF_RET },
{ OP65_SBC, "sbc", 0, REG_A, REG_A, OF_NONE },
{ OP65_SEC, "sec", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_SED, "sed", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_SEI, "sei", 1, REG_NONE, REG_NONE, OF_NONE },
{ OP65_STA, "sta", 0, REG_A, REG_NONE, OF_NONE },
{ OP65_STX, "stx", 0, REG_X, REG_NONE, OF_NONE },
{ OP65_STY, "sty", 0, REG_Y, REG_NONE, OF_NONE },
{ OP65_TAX, "tax", 1, REG_A, REG_X, OF_XFR },
{ OP65_TAY, "tay", 1, REG_A, REG_Y, OF_XFR },
{ OP65_TRB, "trb", 0, REG_A, REG_NONE, OF_NONE },
{ OP65_TSB, "tsb", 0, REG_A, REG_NONE, OF_NONE },
{ OP65_TSX, "tsx", 1, REG_NONE, REG_X, OF_XFR },
{ OP65_TXA, "txa", 1, REG_X, REG_A, OF_XFR },
{ OP65_TXS, "txs", 1, REG_X, REG_NONE, OF_XFR },
{ OP65_TYA, "tya", 1, REG_A, REG_A, OF_XFR },
};
@ -149,7 +151,7 @@ static int Compare (const void* Key, const void* Desc)
const OPCDesc* FindOpcode (const char* M)
/* Find the given opcode and return the opcode number. If the opcode was not
* found, return OPC_INVALID.
* found, return OP65_INVALID.
*/
{
unsigned I;
@ -170,7 +172,7 @@ const OPCDesc* FindOpcode (const char* M)
Mnemo[I] = '\0';
/* Search for the mnemonic in the table and return the result */
return bsearch (Mnemo, OPCTable, OPC_COUNT, sizeof (OPCTable[0]), Compare);
return bsearch (Mnemo, OPCTable, OPCODE_COUNT, sizeof (OPCTable[0]), Compare);
}
@ -186,17 +188,17 @@ unsigned GetInsnSize (opc_t OPC, am_t AM)
/* Check the addressing mode. */
switch (AM) {
case AM_IMP: return 1;
case AM_ACC: return 1;
case AM_IMM: return 2;
case AM_ZP: return 2;
case AM_ZPX: return 2;
case AM_ABS: return 3;
case AM_ABSX: return 3;
case AM_ABSY: return 3;
case AM_ZPX_IND: return 2;
case AM_ZP_INDY: return 2;
case AM_ZP_IND: return 2;
case AM65_IMP: return 1;
case AM65_ACC: return 1;
case AM65_IMM: return 2;
case AM65_ZP: return 2;
case AM65_ZPX: return 2;
case AM65_ABS: return 3;
case AM65_ABSX: return 3;
case AM65_ABSY: return 3;
case AM65_ZPX_IND: return 2;
case AM65_ZP_INDY: return 2;
case AM65_ZP_IND: return 2;
default:
Internal ("Invalid addressing mode");
return 0;
@ -212,13 +214,13 @@ unsigned char GetAMUseInfo (am_t AM)
{
/* Check the addressing mode. */
switch (AM) {
case AM_ACC: return REG_A;
case AM_ZPX: return REG_X;
case AM_ABSX: return REG_X;
case AM_ABSY: return REG_Y;
case AM_ZPX_IND: return REG_X;
case AM_ZP_INDY: return REG_Y;
default: return REG_NONE;
case AM65_ACC: return REG_A;
case AM65_ZPX: return REG_X;
case AM65_ABSX: return REG_X;
case AM65_ABSY: return REG_Y;
case AM65_ZPX_IND: return REG_X;
case AM65_ZP_INDY: return REG_Y;
default: return REG_NONE;
}
}
@ -228,22 +230,22 @@ opc_t GetInverseBranch (opc_t OPC)
/* Return a branch that reverse the condition of the branch given in OPC */
{
switch (OPC) {
case OPC_BCC: return OPC_BCS;
case OPC_BCS: return OPC_BCC;
case OPC_BEQ: return OPC_BNE;
case OPC_BMI: return OPC_BPL;
case OPC_BNE: return OPC_BEQ;
case OPC_BPL: return OPC_BMI;
case OPC_BVC: return OPC_BVS;
case OPC_BVS: return OPC_BVC;
case OPC_JCC: return OPC_JCS;
case OPC_JCS: return OPC_JCC;
case OPC_JEQ: return OPC_JNE;
case OPC_JMI: return OPC_JPL;
case OPC_JNE: return OPC_JEQ;
case OPC_JPL: return OPC_JMI;
case OPC_JVC: return OPC_JVS;
case OPC_JVS: return OPC_JVC;
case OP65_BCC: return OP65_BCS;
case OP65_BCS: return OP65_BCC;
case OP65_BEQ: return OP65_BNE;
case OP65_BMI: return OP65_BPL;
case OP65_BNE: return OP65_BEQ;
case OP65_BPL: return OP65_BMI;
case OP65_BVC: return OP65_BVS;
case OP65_BVS: return OP65_BVC;
case OP65_JCC: return OP65_JCS;
case OP65_JCS: return OP65_JCC;
case OP65_JEQ: return OP65_JNE;
case OP65_JMI: return OP65_JPL;
case OP65_JNE: return OP65_JEQ;
case OP65_JPL: return OP65_JMI;
case OP65_JVC: return OP65_JVS;
case OP65_JVS: return OP65_JVC;
default:
Internal ("GetInverseBranch: Invalid opcode: %d", OPC);
return 0;
@ -258,24 +260,24 @@ opc_t MakeShortBranch (opc_t OPC)
*/
{
switch (OPC) {
case OPC_BCC:
case OPC_JCC: return OPC_BCC;
case OPC_BCS:
case OPC_JCS: return OPC_BCS;
case OPC_BEQ:
case OPC_JEQ: return OPC_BEQ;
case OPC_BMI:
case OPC_JMI: return OPC_BMI;
case OPC_BNE:
case OPC_JNE: return OPC_BNE;
case OPC_BPL:
case OPC_JPL: return OPC_BPL;
case OPC_BVC:
case OPC_JVC: return OPC_BVC;
case OPC_BVS:
case OPC_JVS: return OPC_BVS;
case OPC_BRA:
case OPC_JMP: return (CPU == CPU_65C02)? OPC_BRA : OPC_JMP;
case OP65_BCC:
case OP65_JCC: return OP65_BCC;
case OP65_BCS:
case OP65_JCS: return OP65_BCS;
case OP65_BEQ:
case OP65_JEQ: return OP65_BEQ;
case OP65_BMI:
case OP65_JMI: return OP65_BMI;
case OP65_BNE:
case OP65_JNE: return OP65_BNE;
case OP65_BPL:
case OP65_JPL: return OP65_BPL;
case OP65_BVC:
case OP65_JVC: return OP65_BVC;
case OP65_BVS:
case OP65_JVS: return OP65_BVS;
case OP65_BRA:
case OP65_JMP: return (CPU == CPU_65C02)? OP65_BRA : OP65_JMP;
default:
Internal ("MakeShortBranch: Invalid opcode: %d", OPC);
return 0;
@ -290,24 +292,24 @@ opc_t MakeLongBranch (opc_t OPC)
*/
{
switch (OPC) {
case OPC_BCC:
case OPC_JCC: return OPC_JCC;
case OPC_BCS:
case OPC_JCS: return OPC_JCS;
case OPC_BEQ:
case OPC_JEQ: return OPC_JEQ;
case OPC_BMI:
case OPC_JMI: return OPC_JMI;
case OPC_BNE:
case OPC_JNE: return OPC_JNE;
case OPC_BPL:
case OPC_JPL: return OPC_JPL;
case OPC_BVC:
case OPC_JVC: return OPC_JVC;
case OPC_BVS:
case OPC_JVS: return OPC_JVS;
case OPC_BRA:
case OPC_JMP: return OPC_JMP;
case OP65_BCC:
case OP65_JCC: return OP65_JCC;
case OP65_BCS:
case OP65_JCS: return OP65_JCS;
case OP65_BEQ:
case OP65_JEQ: return OP65_JEQ;
case OP65_BMI:
case OP65_JMI: return OP65_JMI;
case OP65_BNE:
case OP65_JNE: return OP65_JNE;
case OP65_BPL:
case OP65_JPL: return OP65_JPL;
case OP65_BVC:
case OP65_JVC: return OP65_JVC;
case OP65_BVS:
case OP65_JVS: return OP65_JVS;
case OP65_BRA:
case OP65_JMP: return OP65_JMP;
default:
Internal ("MakeLongBranch: Invalid opcode: %d", OPC);
return 0;
@ -320,22 +322,22 @@ bc_t GetBranchCond (opc_t OPC)
/* Get the condition for the conditional branch in OPC */
{
switch (OPC) {
case OPC_BCC: return BC_CC;
case OPC_BCS: return BC_CS;
case OPC_BEQ: return BC_EQ;
case OPC_BMI: return BC_MI;
case OPC_BNE: return BC_NE;
case OPC_BPL: return BC_PL;
case OPC_BVC: return BC_VC;
case OPC_BVS: return BC_VS;
case OPC_JCC: return BC_CC;
case OPC_JCS: return BC_CS;
case OPC_JEQ: return BC_EQ;
case OPC_JMI: return BC_MI;
case OPC_JNE: return BC_NE;
case OPC_JPL: return BC_PL;
case OPC_JVC: return BC_VC;
case OPC_JVS: return BC_VS;
case OP65_BCC: return BC_CC;
case OP65_BCS: return BC_CS;
case OP65_BEQ: return BC_EQ;
case OP65_BMI: return BC_MI;
case OP65_BNE: return BC_NE;
case OP65_BPL: return BC_PL;
case OP65_BVC: return BC_VC;
case OP65_BVS: return BC_VS;
case OP65_JCC: return BC_CC;
case OP65_JCS: return BC_CS;
case OP65_JEQ: return BC_EQ;
case OP65_JMI: return BC_MI;
case OP65_JNE: return BC_NE;
case OP65_JPL: return BC_PL;
case OP65_JVC: return BC_VC;
case OP65_JVS: return BC_VS;
default:
Internal ("GetBranchCond: Invalid opcode: %d", OPC);
return 0;

View File

@ -44,110 +44,112 @@
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
/* Definitions for the possible opcodes */
typedef enum {
OPC_ADC,
OPC_AND,
OPC_ASL,
OPC_BCC,
OPC_BCS,
OPC_BEQ,
OPC_BIT,
OPC_BMI,
OPC_BNE,
OPC_BPL,
OPC_BRA,
OPC_BRK,
OPC_BVC,
OPC_BVS,
OPC_CLC,
OPC_CLD,
OPC_CLI,
OPC_CLV,
OPC_CMP,
OPC_CPX,
OPC_CPY,
OPC_DEA,
OPC_DEC,
OPC_DEX,
OPC_DEY,
OPC_EOR,
OPC_INA,
OPC_INC,
OPC_INX,
OPC_INY,
OPC_JCC,
OPC_JCS,
OPC_JEQ,
OPC_JMI,
OPC_JMP,
OPC_JNE,
OPC_JPL,
OPC_JSR,
OPC_JVC,
OPC_JVS,
OPC_LDA,
OPC_LDX,
OPC_LDY,
OPC_LSR,
OPC_NOP,
OPC_ORA,
OPC_PHA,
OPC_PHP,
OPC_PHX,
OPC_PHY,
OPC_PLA,
OPC_PLP,
OPC_PLX,
OPC_PLY,
OPC_ROL,
OPC_ROR,
OPC_RTI,
OPC_RTS,
OPC_SBC,
OPC_SEC,
OPC_SED,
OPC_SEI,
OPC_STA,
OPC_STX,
OPC_STY,
OPC_TAX,
OPC_TAY,
OPC_TRB,
OPC_TSB,
OPC_TSX,
OPC_TXA,
OPC_TXS,
OPC_TYA,
OPC_COUNT /* Number of opcodes available */
/* 65XX opcodes */
OP65_ADC,
OP65_AND,
OP65_ASL,
OP65_BCC,
OP65_BCS,
OP65_BEQ,
OP65_BIT,
OP65_BMI,
OP65_BNE,
OP65_BPL,
OP65_BRA,
OP65_BRK,
OP65_BVC,
OP65_BVS,
OP65_CLC,
OP65_CLD,
OP65_CLI,
OP65_CLV,
OP65_CMP,
OP65_CPX,
OP65_CPY,
OP65_DEA,
OP65_DEC,
OP65_DEX,
OP65_DEY,
OP65_EOR,
OP65_INA,
OP65_INC,
OP65_INX,
OP65_INY,
OP65_JCC,
OP65_JCS,
OP65_JEQ,
OP65_JMI,
OP65_JMP,
OP65_JNE,
OP65_JPL,
OP65_JSR,
OP65_JVC,
OP65_JVS,
OP65_LDA,
OP65_LDX,
OP65_LDY,
OP65_LSR,
OP65_NOP,
OP65_ORA,
OP65_PHA,
OP65_PHP,
OP65_PHX,
OP65_PHY,
OP65_PLA,
OP65_PLP,
OP65_PLX,
OP65_PLY,
OP65_ROL,
OP65_ROR,
OP65_RTI,
OP65_RTS,
OP65_SBC,
OP65_SEC,
OP65_SED,
OP65_SEI,
OP65_STA,
OP65_STX,
OP65_STY,
OP65_TAX,
OP65_TAY,
OP65_TRB,
OP65_TSB,
OP65_TSX,
OP65_TXA,
OP65_TXS,
OP65_TYA,
OPCODE_COUNT /* Number of opcodes available */
} opc_t;
/* Addressing modes (bitmapped). */
typedef enum {
AM_IMP = 0x0001, /* implicit */
AM_ACC = 0x0002, /* accumulator */
AM_IMM = 0x0004, /* immidiate */
AM_ZP = 0x0008, /* zeropage */
AM_ZPX = 0x0010, /* zeropage,X */
AM_ABS = 0x0020, /* absolute */
AM_ABSX = 0x0040, /* absolute,X */
AM_ABSY = 0x0080, /* absolute,Y */
AM_ZPX_IND = 0x0100, /* (zeropage,x) */
AM_ZP_INDY = 0x0200, /* (zeropage),y */
AM_ZP_IND = 0x0400, /* (zeropage) */
AM_BRA = 0x0800 /* branch */
AM65_IMP, /* implicit */
AM65_ACC, /* accumulator */
AM65_IMM, /* immidiate */
AM65_ZP, /* zeropage */
AM65_ZPX, /* zeropage,X */
AM65_ABS, /* absolute */
AM65_ABSX, /* absolute,X */
AM65_ABSY, /* absolute,Y */
AM65_ZPX_IND, /* (zeropage,x) */
AM65_ZP_INDY, /* (zeropage),y */
AM65_ZP_IND, /* (zeropage) */
AM65_BRA /* branch */
} am_t;
/* Branch conditions */
typedef enum {
BC_CC,
BC_CS,
BC_EQ,
BC_EQ,
BC_MI,
BC_NE,
BC_PL,
@ -156,35 +158,38 @@ typedef enum {
} bc_t;
/* Opcode info */
#define OF_NONE 0x0000U /* No additional information */
#define OF_UBRA 0x0001U /* Unconditional branch */
#define OF_CBRA 0x0002U /* Conditional branch */
#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
#define OF_NONE 0x0000U /* No additional information */
#define OF_UBRA 0x0001U /* Unconditional branch */
#define OF_CBRA 0x0002U /* Conditional branch */
#define OF_ZBRA 0x0004U /* Branch on zero flag condition */
#define OF_FBRA 0x0008U /* Branch on cond set by a load */
#define OF_LBRA 0x0010U /* Jump/branch is long */
#define OF_RET 0x0020U /* Return from function */
#define OF_LOAD 0x0040U /* Register load */
#define OF_XFR 0x0080 /* Transfer instruction */
#define OF_BRA (OF_UBRA|OF_CBRA) /* Operation is a jump/branch */
#define OF_DEAD (OF_UBRA|OF_RET) /* Dead end - no exec behind this point */
#define OF_LBRA 0x0010U /* Jump/branch is long */
#define OF_RET 0x0020U /* Return from function */
#define OF_LOAD 0x0040U /* Register load */
#define OF_XFR 0x0080U /* Transfer instruction */
#define OF_CALL 0x0100U /* A subroutine call */
/* Combined infos */
#define OF_BRA (OF_UBRA | OF_CBRA) /* Operation is a jump/branch */
#define OF_DEAD (OF_UBRA | OF_RET) /* Dead end - no exec behind this point */
/* Opcode description */
typedef struct {
opc_t OPC; /* Opcode */
char Mnemo[4]; /* Mnemonic */
char Mnemo[8]; /* Mnemonic */
unsigned char Size; /* Size, 0 = check addressing mode */
unsigned char Use; /* Registers used by this insn */
unsigned char Chg; /* Registers changed by this insn */
unsigned char Info; /* Additional information */
unsigned short Info; /* Additional information */
} OPCDesc;
/* Opcode description table */
extern const OPCDesc OPCTable[OPC_COUNT];
extern const OPCDesc OPCTable[OPCODE_COUNT];
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@ -209,14 +214,14 @@ INLINE const OPCDesc* GetOPCDesc (opc_t OPC)
#endif
#if defined(HAVE_INLINE)
INLINE unsigned char GetOPCInfo (opc_t OPC)
INLINE unsigned GetOPCInfo (opc_t OPC)
/* Get opcode information */
{
/* Return the info */
return OPCTable[OPC].Info;
}
#else
# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
# define GetOPCInfo(OPC) (OPCTable[(OPC)].Info)
#endif
unsigned char GetAMUseInfo (am_t AM);