1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-15 22:30:04 +00:00

Working on the new backend

git-svn-id: svn://svn.cc65.org/cc65/trunk@701 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-01 15:50:31 +00:00
parent 9d1940a124
commit 88792854a6
8 changed files with 226 additions and 144 deletions

View File

@ -391,7 +391,7 @@ void g_defloclabel (unsigned label)
/* Define a local label */
{
if (CurSeg == SEG_CODE) {
AddCodeSegLabel (CS, LocalLabelName (label));
AddLocCodeLabel (CS, LocalLabelName (label));
} else {
AddDataSegLine (DS, "%s:", LocalLabelName (label));
}
@ -412,7 +412,7 @@ void g_defgloblabel (const char* Name)
/* ##### */
char Buf[64];
xsprintf (Buf, sizeof (Buf), "_%s", Name);
AddCodeSegLabel (CS, Buf);
AddExtCodeLabel (CS, Buf);
} else {
AddDataSegLine (DS, "_%s:", Name);
}

View File

@ -57,6 +57,7 @@ CodeLabel* NewCodeLabel (const char* Name, unsigned Hash)
L->Next = 0;
L->Name = xstrdup (Name);
L->Hash = Hash;
L->Flags = 0;
L->Owner = 0;
InitCollection (&L->JumpFrom);

View File

@ -51,12 +51,17 @@
/* Label flags, bitmapped */
#define LF_DEF 0x0001U /* Label was defined */
#define LF_EXT 0x0002U /* Label is external */
/* Label structure */
typedef struct CodeLabel CodeLabel;
struct CodeLabel {
CodeLabel* Next; /* Next in hash list */
char* Name; /* Label name */
unsigned Hash; /* Hash over the name */
unsigned short Hash; /* Hash over the name */
unsigned short Flags; /* Flag flags */
struct CodeEntry* Owner; /* Owner entry */
Collection JumpFrom; /* Entries that jump here */
};
@ -64,7 +69,7 @@ struct CodeLabel {
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/

View File

@ -233,7 +233,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
/* Indexed */
L = SkipSpace (L+1);
if (*L == '\0') {
Error ("ASM code error: syntax error");
Error ("ASM code error: syntax error");
return 0;
} else {
Reg = toupper (*L);
@ -390,23 +390,30 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
if (E) {
/* Transfer the labels if we have any */
unsigned LabelCount = CollCount (&S->Labels);
unsigned I;
unsigned LabelCount = CollCount (&S->Labels);
for (I = 0; I < LabelCount; ++I) {
CollAppend (&E->Labels, CollAt (&S->Labels, I));
/* Get the label */
CodeLabel* L = CollAt (&S->Labels, I);
/* Mark it as defined */
L->Flags |= LF_DEF;
/* Move it to the code entry */
CollAppend (&E->Labels, L);
}
/* Delete the transfered labels */
CollDeleteAll (&S->Labels);
/* Add the entry to the list of code entries in this segment */
CollAppend (&S->Entries, E);
CollAppend (&S->Entries, E);
}
}
void AddCodeSegLabel (CodeSeg* S, const char* Name)
/* Add a label for the next instruction to follow */
CodeLabel* AddCodeLabel (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;
@ -425,6 +432,30 @@ void AddCodeSegLabel (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;
}
void AddExtCodeLabel (CodeSeg* S, const char* Name)
/* Add an external code label for the next instruction to follow */
{
/* Add the code label */
CodeLabel* L = AddCodeLabel (S, Name);
/* Mark it as external label */
L->Flags |= LF_EXT;
}
void AddLocCodeLabel (CodeSeg* S, const char* Name)
/* Add a local code label for the next instruction to follow */
{
/* Add the code label */
AddCodeLabel (S, Name);
}
@ -450,23 +481,34 @@ void AddCodeSegHint (CodeSeg* S, unsigned Hint)
void DelCodeSegAfter (CodeSeg* S, unsigned Last)
/* Delete all entries after the given one */
/* Delete all entries including the given one */
{
unsigned I;
/* Get the number of entries in this segment */
unsigned Count = CollCount (&S->Entries);
/* ### We need some more cleanup here wrt labels */
/* Must not be called with count zero */
CHECK (Count > 0 && Count >= Last);
/* Remove all entries after the given one */
for (I = Count-1; I > Last; --I) {
FreeCodeEntry (CollAt (&S->Entries, I));
CollDelete (&S->Entries, I);
}
while (Last < Count) {
/* Delete all waiting labels */
CollDeleteAll (&S->Labels);
/* Get the next entry */
CodeEntry* E = CollAt (&S->Entries, Count-1);
/* We have to transfer all labels to the code segment label pool */
unsigned LabelCount = CollCount (&E->Labels);
while (LabelCount--) {
CodeLabel* L = CollAt (&E->Labels, LabelCount);
L->Flags &= ~LF_DEF;
CollAppend (&S->Labels, L);
}
CollDeleteAll (&E->Labels);
/* Remove the code entry */
FreeCodeEntry (CollAt (&S->Entries, Count-1));
CollDelete (&S->Entries, Count-1);
--Count;
}
}
@ -501,7 +543,7 @@ CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash)
if (strcmp (Name, L->Name) == 0) {
/* Found */
break;
}
}
L = L->Next;
}
return L;
@ -526,63 +568,68 @@ void MergeCodeLabels (CodeSeg* S)
/* Get a pointer to the next entry */
CodeEntry* E = CollAt (&S->Entries, I);
/* If this entry has zero labels, continue with the next one */
unsigned LabelCount = CollCount (&E->Labels);
if (LabelCount == 0) {
continue;
}
/* If this entry has zero labels, continue with the next one */
unsigned LabelCount = CollCount (&E->Labels);
if (LabelCount == 0) {
continue;
}
/* We have at least one label. Use the first one as reference label.
* We don't have a notification for global labels for now, and using
* the first one will also keep the global function labels, since these
* are inserted at position 0.
*/
RefLab = CollAt (&E->Labels, 0);
/* We have at least one label. Use the first one as reference label.
* We don't have a notification for global labels for now, and using
* the first one will also keep the global function labels, since these
* are inserted at position 0.
*/
RefLab = CollAt (&E->Labels, 0);
/* Walk through the remaining labels and change references to these
* labels to a reference to the one and only label. Delete the labels
* that are no longer used. To increase performance, walk backwards
* through the list.
*/
for (J = LabelCount-1; J >= 1; --J) {
/* Walk through the remaining labels and change references to these
* labels to a reference to the one and only label. Delete the labels
* that are no longer used. To increase performance, walk backwards
* through the list.
*/
for (J = LabelCount-1; J >= 1; --J) {
unsigned K;
unsigned K;
/* Get the next label */
CodeLabel* L = CollAt (&E->Labels, J);
/* Get the next label */
CodeLabel* L = CollAt (&E->Labels, J);
/* Walk through all instructions referencing this label */
unsigned RefCount = CollCount (&L->JumpFrom);
for (K = 0; K < RefCount; ++K) {
/* Walk through all instructions referencing this label */
unsigned RefCount = CollCount (&L->JumpFrom);
for (K = 0; K < RefCount; ++K) {
/* Get the next instrcuction that references this label */
CodeEntry* E = CollAt (&L->JumpFrom, K);
/* Get the next instrcuction that references this label */
CodeEntry* E = CollAt (&L->JumpFrom, K);
/* Change the reference */
CHECK (E->JumpTo == L);
E->JumpTo = RefLab;
CollAppend (&RefLab->JumpFrom, E);
/* Change the reference */
CHECK (E->JumpTo == L);
E->JumpTo = RefLab;
CollAppend (&RefLab->JumpFrom, E);
}
/* Delete the label */
FreeCodeLabel (L);
/* Remove it from the list */
CollDelete (&E->Labels, J);
}
/* If the label is not an external label, we may remove the
* label completely.
*/
#if 0
if ((L->Flags & LF_EXT) == 0) {
FreeCodeLabel (L);
CollDelete (&E->Labels, J);
}
#endif
}
/* The reference label is the only remaining label. Check if there
* are any references to this label, and delete it if this is not
* the case.
/* The reference label is the only remaining label. If it is not an
* external label, check if there are any references to this label,
* and delete it if this is not the case.
*/
if (CollCount (&RefLab->JumpFrom) == 0) {
/* Delete the label */
FreeCodeLabel (RefLab);
/* Remove it from the list */
CollDelete (&E->Labels, 0);
}
#if 0
if ((RefLab->Flags & LF_EXT) == 0 && CollCount (&RefLab->JumpFrom) == 0) {
/* Delete the label */
FreeCodeLabel (RefLab);
/* Remove it from the list */
CollDelete (&E->Labels, 0);
}
#endif
}
}

View File

@ -84,14 +84,17 @@ void FreeCodeSeg (CodeSeg* S);
void AddCodeSegLine (CodeSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
/* Add a line to the given code segment */
void AddCodeSegLabel (CodeSeg* S, const char* Name);
/* Add a label for the next instruction to follow */
void AddExtCodeLabel (CodeSeg* S, const char* Name);
/* Add an external code label for the next instruction to follow */
void AddLocCodeLabel (CodeSeg* S, const char* Name);
/* Add a local code label for the next instruction to follow */
void AddCodeSegHint (CodeSeg* S, unsigned Hint);
/* Add a hint for the preceeding instruction */
void DelCodeSegAfter (CodeSeg* S, unsigned Last);
/* Delete all entries after the given one */
/* Delete all entries including the given one */
void OutputCodeSeg (FILE* F, const CodeSeg* S);
/* Output the code segment data to a file */
@ -106,7 +109,7 @@ void MergeCodeLabels (CodeSeg* S);
unsigned GetCodeSegEntries (const CodeSeg* S);
/* Return the number of entries for the given code segment */
/* End of codeseg.h */

View File

@ -39,7 +39,7 @@ OBJS = anonname.o \
funcdesc.o \
function.o \
global.o \
goto.o \
goto.o \
ident.o \
incpath.o \
input.o \
@ -60,7 +60,7 @@ OBJS = anonname.o \
util.o
LIBS = $(B6502)/b6502.a \
$(COMMON)/common.a
$(COMMON)/common.a
# ------------------------------------------------------------------------------
@ -76,10 +76,16 @@ all: depend
@$(MAKE) -f make/gcc.mak all
endif
$(EXE): $(OBJS) $(LIBS)
$(EXE): $(OBJS) $(LIBS) subs
$(CC) $(LDFLAGS) -o $(EXE) $(CFLAGS) $(OBJS) $(LIBS)
@if [ $(OS2_SHELL) ] ; then $(EBIND) $(EXE) ; fi
.PHONY: subs
subs:
@for dir in $(COMMON) $(B6502); do \
$(MAKE) -C $$dir -f make/gcc.mak || exit 1; \
done
clean:
rm -f *~ core *.map

View File

@ -54,77 +54,85 @@
/* Mapper table, mnemonic --> opcode */
static const OPCDesc OPCTable[OPC_COUNT] = {
{ "adc", OPC_ADC, CI_USE_A | CI_CHG_A },
{ "and", OPC_AND, CI_USE_A | CI_CHG_A },
{ "asl", OPC_ASL, CI_USE_A | CI_CHG_A },
{ "bcc", OPC_BCC, CI_BRA },
{ "bcs", OPC_BCS, CI_BRA },
{ "beq", OPC_BEQ, CI_BRA },
{ "bit", OPC_BIT, CI_USE_A },
{ "bmi", OPC_BMI, CI_BRA },
{ "bne", OPC_BNE, CI_BRA },
{ "bpl", OPC_BPL, CI_BRA },
{ "bra", OPC_BRA, CI_BRA },
{ "brk", OPC_BRK, CI_BRA },
{ "bvc", OPC_BVC, CI_BRA },
{ "bvs", OPC_BVS, CI_BRA },
{ "clc", OPC_CLC, CI_CHG_NONE },
{ "cld", OPC_CLD, CI_CHG_NONE },
{ "cli", OPC_CLI, CI_CHG_NONE },
{ "clv", OPC_CLV, CI_CHG_NONE },
{ "cmp", OPC_CMP, CI_USE_A },
{ "cpx", OPC_CPX, CI_USE_X },
{ "cpy", OPC_CPY, CI_USE_Y },
{ "dea", OPC_DEA, CI_USE_A | CI_CHG_A },
{ "dec", OPC_DEC, CI_NONE },
{ "dex", OPC_DEX, CI_USE_X | CI_CHG_X },
{ "dey", OPC_DEY, CI_USE_Y | CI_CHG_Y },
{ "eor", OPC_EOR, CI_USE_A | CI_CHG_A },
{ "ina", OPC_INA, CI_USE_A | CI_CHG_A },
{ "inc", OPC_INC, CI_NONE },
{ "inx", OPC_INX, CI_USE_X | CI_CHG_X },
{ "iny", OPC_INY, CI_USE_Y | CI_CHG_Y },
{ "jmp", OPC_JMP, CI_BRA },
{ "jsr", OPC_JSR, CI_BRA },
{ "lda", OPC_LDA, CI_CHG_A },
{ "ldx", OPC_LDX, CI_CHG_X },
{ "ldy", OPC_LDY, CI_CHG_Y },
{ "lsr", OPC_LSR, CI_USE_A | CI_CHG_A },
{ "nop", OPC_NOP, CI_NONE },
{ "ora", OPC_ORA, CI_USE_A | CI_CHG_A },
{ "pha", OPC_PHA, CI_USE_A },
{ "php", OPC_PHP, CI_NONE },
{ "phx", OPC_PHX, CI_USE_X },
{ "phy", OPC_PHY, CI_USE_Y },
{ "pla", OPC_PLA, CI_CHG_A },
{ "plp", OPC_PLP, CI_NONE },
{ "plx", OPC_PLX, CI_CHG_X },
{ "ply", OPC_PLY, CI_CHG_Y },
{ "rol", OPC_ROL, CI_USE_A | CI_CHG_A },
{ "ror", OPC_ROR, CI_USE_A | CI_CHG_A },
{ "rti", OPC_RTI, CI_NONE },
{ "rts", OPC_RTS, CI_NONE },
{ "sbc", OPC_SBC, CI_USE_A | CI_CHG_A },
{ "sec", OPC_SEC, CI_NONE },
{ "sed", OPC_SED, CI_NONE },
{ "sei", OPC_SEI, CI_NONE },
{ "sta", OPC_STA, CI_USE_A },
{ "stx", OPC_STX, CI_USE_X },
{ "sty", OPC_STY, CI_USE_Y },
{ "tax", OPC_TAX, CI_USE_A | CI_CHG_X },
{ "tay", OPC_TAY, CI_USE_A | CI_CHG_Y },
{ "trb", OPC_TRB, CI_USE_A },
{ "tsb", OPC_TSB, CI_USE_A },
{ "tsx", OPC_TSX, CI_CHG_X },
{ "txa", OPC_TXA, CI_USE_X | CI_CHG_A },
{ "txs", OPC_TXS, CI_USE_X },
{ "tya", OPC_TYA, CI_USE_Y | CI_CHG_A }
{ "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_BRA },
{ "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 }
};
/*****************************************************************************/
/* Code */
/* Code */
/*****************************************************************************/
@ -168,9 +176,13 @@ const OPCDesc* FindOpcode (const char* M)
unsigned GetInsnSize (opc_t OPC, am_t AM)
/* Return the size of the given instruction */
{
/* On the 6502 (and 65C02), the instruction size is determined only by the
* addressing mode.
*/
/* Get the opcode desc and check the size given there */
const OPCDesc* D = &OPCTable[OPC];
if (D->Size != 0) {
return D->Size;
}
/* Check the addressing mode. */
switch (AM) {
case AM_IMP: return 1;
case AM_ACC: return 1;
@ -183,7 +195,6 @@ unsigned GetInsnSize (opc_t OPC, am_t AM)
case AM_ZPX_IND: return 2;
case AM_ZP_INDY: return 2;
case AM_ZP_IND: return 2;
case AM_BRA: return 2;
default: FAIL ("Invalid addressing mode");
}
}

View File

@ -76,8 +76,16 @@ typedef enum {
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,
@ -134,6 +142,7 @@ typedef enum {
typedef struct {
char Mnemo[4]; /* Mnemonic */
opc_t OPC; /* Opcode */
unsigned Size; /* Size, 0 means "check addressing mode" */
unsigned Info; /* Usage flags */
} OPCDesc;
@ -155,7 +164,7 @@ unsigned GetInsnSize (opc_t OPC, am_t AM);
const OPCDesc* GetOPCDesc (opc_t OPC);
/* Get an opcode description */
/* End of opcodes.h */