1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 20:29:34 +00:00

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:
cuz 2001-05-05 16:12:47 +00:00
parent 3ff4baeafb
commit cc9826721b
9 changed files with 284 additions and 144 deletions

View File

@ -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 */

View File

@ -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
View 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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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 \

View File

@ -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;
}
}

View File

@ -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);