Working on the new backend
git-svn-id: svn://svn.cc65.org/cc65/trunk@717 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
3ff4baeafb
commit
cc9826721b
9 changed files with 284 additions and 144 deletions
|
@ -40,7 +40,6 @@
|
|||
/* cc65 */
|
||||
#include "codeinfo.h"
|
||||
#include "error.h"
|
||||
#include "funcinfo.h"
|
||||
#include "global.h"
|
||||
#include "codelab.h"
|
||||
#include "opcodes.h"
|
||||
|
@ -74,13 +73,14 @@ CodeEntry* NewCodeEntry (const OPCDesc* D, am_t AM, const char* Arg, CodeLabel*
|
|||
E->Arg = (Arg && Arg[0] != '\0')? xstrdup (Arg) : 0;
|
||||
E->Num = 0;
|
||||
E->Flags = 0;
|
||||
E->Info = D->Info;
|
||||
E->Use = D->Use;
|
||||
E->Chg = D->Chg;
|
||||
if (E->OPC == OPC_JSR && E->Arg) {
|
||||
/* A subroutine call */
|
||||
E->Info |= GetFuncInfo (E->Arg);
|
||||
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
|
||||
} else {
|
||||
/* Some other instruction */
|
||||
E->Info |= GetAMUseInfo (AM);
|
||||
E->Use |= GetAMUseInfo (AM);
|
||||
}
|
||||
E->JumpTo = JumpTo;
|
||||
InitCollection (&E->Labels);
|
||||
|
@ -203,12 +203,12 @@ void OutputCodeEntry (const CodeEntry* E, FILE* F)
|
|||
Chars += fprintf (F,
|
||||
"%*s; USE: %c%c%c CHG: %c%c%c",
|
||||
30-Chars, "",
|
||||
(E->Info & CI_USE_A)? 'A' : '_',
|
||||
(E->Info & CI_USE_X)? 'X' : '_',
|
||||
(E->Info & CI_USE_Y)? 'Y' : '_',
|
||||
(E->Info & CI_CHG_A)? 'A' : '_',
|
||||
(E->Info & CI_CHG_X)? 'X' : '_',
|
||||
(E->Info & CI_CHG_Y)? 'Y' : '_');
|
||||
(E->Use & REG_A)? 'A' : '_',
|
||||
(E->Use & REG_X)? 'X' : '_',
|
||||
(E->Use & REG_Y)? 'Y' : '_',
|
||||
(E->Chg & REG_A)? 'A' : '_',
|
||||
(E->Chg & REG_X)? 'X' : '_',
|
||||
(E->Chg & REG_Y)? 'Y' : '_');
|
||||
// }
|
||||
|
||||
/* Terminate the line */
|
||||
|
|
|
@ -69,7 +69,8 @@ struct CodeEntry {
|
|||
char* Arg; /* Argument as string */
|
||||
unsigned Num; /* Numeric argument */
|
||||
unsigned short Flags; /* Flags */
|
||||
unsigned short Info; /* Register usage info for this entry */
|
||||
unsigned char Use; /* Registers used */
|
||||
unsigned char Chg; /* Registers changed/destroyed */
|
||||
CodeLabel* JumpTo; /* Jump label */
|
||||
Collection Labels; /* Labels for this instruction */
|
||||
};
|
||||
|
|
138
src/cc65/codeinfo.c
Normal file
138
src/cc65/codeinfo.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*****************************************************************************/
|
||||
/* */
|
||||
/* codeinfo.c */
|
||||
/* */
|
||||
/* Additional information about 6502 code */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* cc65 */
|
||||
#include "codeinfo.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Table listing the function names and code info values for known internally
|
||||
* used functions. This table should get auto-generated in the future.
|
||||
*/
|
||||
typedef struct FuncInfo FuncInfo;
|
||||
struct FuncInfo {
|
||||
const char* Name; /* Function name */
|
||||
unsigned char Use; /* Register usage */
|
||||
unsigned char Chg; /* Changed/destroyed registers */
|
||||
};
|
||||
|
||||
static const FuncInfo FuncInfoTable[] = {
|
||||
{ "booleq", REG_NONE, REG_AX },
|
||||
{ "boolge", REG_NONE, REG_AX },
|
||||
{ "boolgt", REG_NONE, REG_AX },
|
||||
{ "boolle", REG_NONE, REG_AX },
|
||||
{ "boollt", REG_NONE, REG_AX },
|
||||
{ "boolne", REG_NONE, REG_AX },
|
||||
{ "booluge", REG_NONE, REG_AX },
|
||||
{ "boolugt", REG_NONE, REG_AX },
|
||||
{ "boolule", REG_NONE, REG_AX },
|
||||
{ "boolult", REG_NONE, REG_AX },
|
||||
{ "decax1", REG_AX, REG_AX },
|
||||
{ "decax2", REG_AX, REG_AX },
|
||||
{ "decax3", REG_AX, REG_AX },
|
||||
{ "decax4", REG_AX, REG_AX },
|
||||
{ "decax5", REG_AX, REG_AX },
|
||||
{ "decax6", REG_AX, REG_AX },
|
||||
{ "decax7", REG_AX, REG_AX },
|
||||
{ "decax8", REG_AX, REG_AX },
|
||||
{ "decaxy", REG_AXY, REG_AX },
|
||||
{ "decsp2", REG_NONE, REG_A },
|
||||
{ "decsp3", REG_NONE, REG_A },
|
||||
{ "decsp4", REG_NONE, REG_A },
|
||||
{ "decsp5", REG_NONE, REG_A },
|
||||
{ "decsp6", REG_NONE, REG_A },
|
||||
{ "decsp7", REG_NONE, REG_A },
|
||||
{ "decsp8", REG_NONE, REG_A },
|
||||
{ "ldax0sp", REG_Y, REG_AX },
|
||||
{ "ldaxysp", REG_Y, REG_AX },
|
||||
{ "pusha", REG_A, REG_Y },
|
||||
{ "pusha0", REG_A, REG_XY },
|
||||
{ "pushax", REG_AX, REG_Y },
|
||||
{ "pushw0sp", REG_NONE, REG_AXY },
|
||||
{ "pushwysp", REG_Y, REG_AXY },
|
||||
{ "tosicmp", REG_AX, REG_AXY },
|
||||
};
|
||||
#define FuncInfoCount (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static int CompareFuncInfo (const void* Key, const void* Info)
|
||||
/* Compare function for bsearch */
|
||||
{
|
||||
return strcmp (Key, ((const FuncInfo*) Info)->Name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
|
||||
/* For the given function, lookup register information and combine it with
|
||||
* the information already in place. If the function is unknown, assume it
|
||||
* will use all registers and load all registers.
|
||||
* See codeinfo.h for possible flags.
|
||||
*/
|
||||
{
|
||||
/* Search for the function */
|
||||
const FuncInfo* Info = bsearch (Name, FuncInfoTable, FuncInfoCount,
|
||||
sizeof(FuncInfo), CompareFuncInfo);
|
||||
|
||||
/* Do we know the function? */
|
||||
if (Info) {
|
||||
/* Use the information we have */
|
||||
*Use |= Info->Use;
|
||||
*Chg |= Info->Chg;
|
||||
} else {
|
||||
*Use |= REG_AXY;
|
||||
*Chg |= REG_AXY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
/* */
|
||||
/* codeinfo.h */
|
||||
/* */
|
||||
/* Additional information about code instructions */
|
||||
/* Additional information about 6502 code */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
|
@ -44,31 +44,19 @@
|
|||
|
||||
|
||||
|
||||
/* Flags that tell what a specific instruction does with a register.
|
||||
* Please note that *changing* a register must not necessarily mean that the
|
||||
* value currently in the register is used. A prominent example is a load
|
||||
* instruction: It changes the register contents and does not use the old
|
||||
* value. On the flip side, a shift or something similar would use the
|
||||
* current value and change it.
|
||||
*/
|
||||
#define CI_USE_NONE 0x0000U /* Use nothing */
|
||||
#define CI_USE_A 0x0001U /* Use the A register */
|
||||
#define CI_USE_X 0x0002U /* Use the X register */
|
||||
#define CI_USE_Y 0x0004U /* Use the Y register */
|
||||
#define CI_USE_ALL 0x0007U /* Use all registers */
|
||||
#define CI_MASK_USE 0x000FU /* Extract usage info */
|
||||
|
||||
#define CI_CHG_NONE 0x0000U /* Change nothing */
|
||||
#define CI_CHG_A 0x0010U /* Change the A register */
|
||||
#define CI_CHG_X 0x0020U /* Change the X register */
|
||||
#define CI_CHG_Y 0x0040U /* Change the Y register */
|
||||
#define CI_CHG_ALL 0x0070U /* Change all registers */
|
||||
#define CI_MASK_CHG 0x00F0U /* Extract change info */
|
||||
|
||||
#define CI_BRA 0x0100U /* Instruction is a branch */
|
||||
#define CI_MASK_BRA 0x0100U /* Extract branch info */
|
||||
|
||||
#define CI_NONE 0x0000U /* Nothing used/changed */
|
||||
/* Defines for registers. */
|
||||
#define REG_NONE 0x00U
|
||||
#define REG_A 0x01U
|
||||
#define REG_X 0x02U
|
||||
#define REG_Y 0x04U
|
||||
#define REG_SREG_LO 0x08U
|
||||
#define REG_SREG_HI 0x10U
|
||||
#define REG_TMP1 0x20U
|
||||
#define REG_PTR1_LO 0x40U
|
||||
#define REG_PTR1_HI 0x80U
|
||||
#define REG_AX (REG_A | REG_X)
|
||||
#define REG_XY (REG_X | REG_Y)
|
||||
#define REG_AXY (REG_A | REG_X | REG_Y)
|
||||
|
||||
|
||||
|
||||
|
@ -78,8 +66,17 @@
|
|||
|
||||
|
||||
|
||||
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg);
|
||||
/* For the given function, lookup register information and combine it with
|
||||
* the information already in place. If the function is unknown, assume it
|
||||
* will use all registers and load all registers.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* End of codeinfo.h */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -210,11 +210,9 @@ static void OptJumpCascades (CodeSeg* S)
|
|||
DelCodeLabel (S, OldLabel);
|
||||
}
|
||||
|
||||
/* Remove usage information from the entry and use the usage
|
||||
* information from the new instruction instead.
|
||||
*/
|
||||
E->Info &= ~(CI_MASK_USE | CI_MASK_CHG);
|
||||
E->Info |= N->Info & ~(CI_MASK_USE | CI_MASK_CHG);
|
||||
/* Use the usage information from the new instruction */
|
||||
E->Use = N->Use;
|
||||
E->Chg = N->Chg;
|
||||
|
||||
/* Use the new label */
|
||||
AddLabelRef (NewLabel, E);
|
||||
|
|
|
@ -260,7 +260,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
|
|||
* if it does not exist. Ignore anything but local labels here.
|
||||
*/
|
||||
Label = 0;
|
||||
if ((OPC->Info & CI_MASK_BRA) == CI_BRA && Arg[0] == 'L') {
|
||||
if ((OPC->Info & OF_BRA) != 0 && Arg[0] == 'L') {
|
||||
|
||||
unsigned Hash;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ OBJS = anonname.o \
|
|||
codeent.o \
|
||||
codegen.o \
|
||||
codelab.o \
|
||||
codeinfo.o \
|
||||
codeopt.o \
|
||||
codeseg.o \
|
||||
compile.o \
|
||||
|
@ -41,7 +42,6 @@ OBJS = anonname.o \
|
|||
exprheap.o \
|
||||
exprnode.o \
|
||||
funcdesc.o \
|
||||
funcinfo.o \
|
||||
function.o \
|
||||
global.o \
|
||||
goto.o \
|
||||
|
|
|
@ -48,86 +48,86 @@
|
|||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Mapper table, mnemonic --> opcode */
|
||||
static const OPCDesc OPCTable[OPC_COUNT] = {
|
||||
{ "adc", OPC_ADC, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "and", OPC_AND, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "asl", OPC_ASL, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "bcc", OPC_BCC, 2, CI_BRA },
|
||||
{ "bcs", OPC_BCS, 2, CI_BRA },
|
||||
{ "beq", OPC_BEQ, 2, CI_BRA },
|
||||
{ "bit", OPC_BIT, 0, CI_USE_A },
|
||||
{ "bmi", OPC_BMI, 2, CI_BRA },
|
||||
{ "bne", OPC_BNE, 2, CI_BRA },
|
||||
{ "bpl", OPC_BPL, 2, CI_BRA },
|
||||
{ "bra", OPC_BRA, 2, CI_BRA },
|
||||
{ "brk", OPC_BRK, 1, CI_NONE },
|
||||
{ "bvc", OPC_BVC, 2, CI_BRA },
|
||||
{ "bvs", OPC_BVS, 2, CI_BRA },
|
||||
{ "clc", OPC_CLC, 1, CI_CHG_NONE },
|
||||
{ "cld", OPC_CLD, 1, CI_CHG_NONE },
|
||||
{ "cli", OPC_CLI, 1, CI_CHG_NONE },
|
||||
{ "clv", OPC_CLV, 1, CI_CHG_NONE },
|
||||
{ "cmp", OPC_CMP, 0, CI_USE_A },
|
||||
{ "cpx", OPC_CPX, 0, CI_USE_X },
|
||||
{ "cpy", OPC_CPY, 0, CI_USE_Y },
|
||||
{ "dea", OPC_DEA, 1, CI_USE_A | CI_CHG_A },
|
||||
{ "dec", OPC_DEC, 0, CI_NONE },
|
||||
{ "dex", OPC_DEX, 1, CI_USE_X | CI_CHG_X },
|
||||
{ "dey", OPC_DEY, 1, CI_USE_Y | CI_CHG_Y },
|
||||
{ "eor", OPC_EOR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "ina", OPC_INA, 1, CI_USE_A | CI_CHG_A },
|
||||
{ "inc", OPC_INC, 0, CI_NONE },
|
||||
{ "inx", OPC_INX, 1, CI_USE_X | CI_CHG_X },
|
||||
{ "iny", OPC_INY, 1, CI_USE_Y | CI_CHG_Y },
|
||||
{ "jcc", OPC_JCC, 5, CI_BRA },
|
||||
{ "jcs", OPC_JCS, 5, CI_BRA },
|
||||
{ "jeq", OPC_JEQ, 5, CI_BRA },
|
||||
{ "jmi", OPC_JMI, 5, CI_BRA },
|
||||
{ "jmp", OPC_JMP, 3, CI_BRA },
|
||||
{ "jne", OPC_JNE, 5, CI_BRA },
|
||||
{ "jpl", OPC_JPL, 5, CI_BRA },
|
||||
{ "jsr", OPC_JSR, 3, CI_NONE },
|
||||
{ "jvc", OPC_JVC, 5, CI_BRA },
|
||||
{ "jvs", OPC_JVS, 5, CI_BRA },
|
||||
{ "lda", OPC_LDA, 0, CI_CHG_A },
|
||||
{ "ldx", OPC_LDX, 0, CI_CHG_X },
|
||||
{ "ldy", OPC_LDY, 0, CI_CHG_Y },
|
||||
{ "lsr", OPC_LSR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "nop", OPC_NOP, 1, CI_NONE },
|
||||
{ "ora", OPC_ORA, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "pha", OPC_PHA, 1, CI_USE_A },
|
||||
{ "php", OPC_PHP, 1, CI_NONE },
|
||||
{ "phx", OPC_PHX, 1, CI_USE_X },
|
||||
{ "phy", OPC_PHY, 1, CI_USE_Y },
|
||||
{ "pla", OPC_PLA, 1, CI_CHG_A },
|
||||
{ "plp", OPC_PLP, 1, CI_NONE },
|
||||
{ "plx", OPC_PLX, 1, CI_CHG_X },
|
||||
{ "ply", OPC_PLY, 1, CI_CHG_Y },
|
||||
{ "rol", OPC_ROL, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "ror", OPC_ROR, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "rti", OPC_RTI, 1, CI_NONE },
|
||||
{ "rts", OPC_RTS, 1, CI_NONE },
|
||||
{ "sbc", OPC_SBC, 0, CI_USE_A | CI_CHG_A },
|
||||
{ "sec", OPC_SEC, 1, CI_NONE },
|
||||
{ "sed", OPC_SED, 1, CI_NONE },
|
||||
{ "sei", OPC_SEI, 1, CI_NONE },
|
||||
{ "sta", OPC_STA, 0, CI_USE_A },
|
||||
{ "stx", OPC_STX, 0, CI_USE_X },
|
||||
{ "sty", OPC_STY, 0, CI_USE_Y },
|
||||
{ "tax", OPC_TAX, 1, CI_USE_A | CI_CHG_X },
|
||||
{ "tay", OPC_TAY, 1, CI_USE_A | CI_CHG_Y },
|
||||
{ "trb", OPC_TRB, 0, CI_USE_A },
|
||||
{ "tsb", OPC_TSB, 0, CI_USE_A },
|
||||
{ "tsx", OPC_TSX, 1, CI_CHG_X },
|
||||
{ "txa", OPC_TXA, 1, CI_USE_X | CI_CHG_A },
|
||||
{ "txs", OPC_TXS, 1, CI_USE_X },
|
||||
{ "tya", OPC_TYA, 1, CI_USE_Y | CI_CHG_A }
|
||||
{ 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_BRA },
|
||||
{ OPC_BCS, "bcs", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BEQ, "beq", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BIT, "bit", 0, REG_A, REG_NONE, OF_NONE },
|
||||
{ OPC_BMI, "bmi", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BNE, "bne", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BPL, "bpl", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BRA, "bra", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BRK, "brk", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_BVC, "bvc", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_BVS, "bvs", 2, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ 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_BRA },
|
||||
{ OPC_JCS, "jcs", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JEQ, "jeq", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JMI, "jmi", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JMP, "jmp", 3, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JNE, "jne", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JPL, "jpl", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JSR, "jsr", 3, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ OPC_JVC, "jvc", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_JVS, "jvs", 5, REG_NONE, REG_NONE, OF_BRA },
|
||||
{ OPC_LDA, "lda", 0, REG_NONE, REG_A, OF_NONE },
|
||||
{ OPC_LDX, "ldx", 0, REG_NONE, REG_X, OF_NONE },
|
||||
{ OPC_LDY, "ldy", 0, REG_NONE, REG_Y, OF_NONE },
|
||||
{ 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_NONE },
|
||||
{ OPC_RTS, "rts", 1, REG_NONE, REG_NONE, OF_NONE },
|
||||
{ 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_NONE },
|
||||
{ OPC_TAY, "tay", 1, REG_A, REG_Y, OF_NONE },
|
||||
{ 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_NONE },
|
||||
{ OPC_TXA, "txa", 1, REG_X, REG_A, OF_NONE },
|
||||
{ OPC_TXS, "txs", 1, REG_X, REG_NONE, OF_NONE },
|
||||
{ OPC_TYA, "tya", 1, REG_A, REG_A, OF_NONE },
|
||||
};
|
||||
|
||||
|
||||
|
@ -214,20 +214,20 @@ const OPCDesc* GetOPCDesc (opc_t OPC)
|
|||
|
||||
|
||||
|
||||
unsigned GetAMUseInfo (am_t AM)
|
||||
unsigned char GetAMUseInfo (am_t AM)
|
||||
/* Get usage info for the given addressing mode (addressing modes that use
|
||||
* index registers return CI_USE... info for these registers).
|
||||
* index registers return REG_r info for these registers).
|
||||
*/
|
||||
{
|
||||
/* Check the addressing mode. */
|
||||
switch (AM) {
|
||||
case AM_ACC: return CI_USE_A;
|
||||
case AM_ZPX: return CI_USE_X;
|
||||
case AM_ABSX: return CI_USE_X;
|
||||
case AM_ABSY: return CI_USE_Y;
|
||||
case AM_ZPX_IND: return CI_USE_X;
|
||||
case AM_ZP_INDY: return CI_USE_Y;
|
||||
default: return CI_USE_NONE;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -125,31 +125,37 @@ typedef enum {
|
|||
/* 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_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 */
|
||||
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 */
|
||||
} am_t;
|
||||
|
||||
/* Opcode info */
|
||||
#define OF_NONE 0x0000U /* No additional information */
|
||||
#define OF_BRA 0x0001U /* Operation is a jump/branch */
|
||||
|
||||
/* Opcode description */
|
||||
typedef struct {
|
||||
char Mnemo[4]; /* Mnemonic */
|
||||
opc_t OPC; /* Opcode */
|
||||
unsigned Size; /* Size, 0 means "check addressing mode" */
|
||||
unsigned Info; /* Usage flags */
|
||||
opc_t OPC; /* Opcode */
|
||||
char Mnemo[4]; /* Mnemonic */
|
||||
unsigned char Size; /* Size, 0 means "check addressing mode" */
|
||||
unsigned char Use; /* Registers used by this insn */
|
||||
unsigned char Chg; /* Registers changed/destroyed by this insn */
|
||||
unsigned char Info; /* Additional information */
|
||||
} OPCDesc;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
@ -165,9 +171,9 @@ unsigned GetInsnSize (opc_t OPC, am_t AM);
|
|||
const OPCDesc* GetOPCDesc (opc_t OPC);
|
||||
/* Get an opcode description */
|
||||
|
||||
unsigned GetAMUseInfo (am_t AM);
|
||||
unsigned char GetAMUseInfo (am_t AM);
|
||||
/* Get usage info for the given addressing mode (addressing modes that use
|
||||
* index registers return CI_USE... info for these registers).
|
||||
* index registers return REG_r info for these registers).
|
||||
*/
|
||||
|
||||
opc_t GetInverseBranch (opc_t OPC);
|
||||
|
|
Loading…
Add table
Reference in a new issue