From 49376daf0d72648a50f20d6a3ad800ba43ca7aaa Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 14 Jul 2001 14:31:50 +0000 Subject: [PATCH] Go back to a working codegen.c git-svn-id: svn://svn.cc65.org/cc65/trunk@779 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codegen.c | 257 +++++++++++++++++++++++++++++++++------------ 1 file changed, 191 insertions(+), 66 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index bdfe1b028..92b954693 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -130,46 +130,6 @@ static char* GetLabelName (unsigned flags, unsigned long label, unsigned offs) -const char* NumToStr (long Val) -/* Convert the given parameter converted to a string in a static buffer */ -{ - static char Buf [64]; - sprintf (Buf, "$%04X", (unsigned) (Val & 0xFFFF)); - return Buf; -} - - - -const char* ByteToStr (unsigned Val) -/* Convert the given byte parameter converted to a string in a static buffer */ -{ - static char Buf [16]; - sprintf (Buf, "$%02X", Val & 0xFF); - return Buf; -} - - - -const char* WordToStr (unsigned Val) -/* Convert the given word parameter converted to a string in a static buffer */ -{ - static char Buf [16]; - sprintf (Buf, "$%04X", Val & 0xFFFF); - return Buf; -} - - - -const char* DWordToStr (unsigned long Val) -/* Convert the given dword parameter converted to a string in a static buffer */ -{ - static char Buf [16]; - sprintf (Buf, "$%08lX", Val & 0xFFFFFFFF); - return Buf; -} - - - /*****************************************************************************/ /* Pre- and postamble */ /*****************************************************************************/ @@ -475,7 +435,7 @@ void g_enter (unsigned flags, unsigned argsize) funcargs = argsize; } else { funcargs = -1; - AddCode (OPC_ENTER, AM_IMP, 0, 0); + AddCodeLine ("jsr enter"); } } @@ -493,20 +453,29 @@ void g_leave (void) /* Drop stackframe if needed */ k += funcargs; if (k > 0) { - CheckLocalOffs (k); - AddCode (OPC_SPACE, AM_IMM, NumToStr (-k), 0); + if (k <= 8) { + AddCodeLine ("jsr incsp%d", k); + } else { + CheckLocalOffs (k); + ldyconst (k); + AddCodeLine ("jsr addysp"); + } } } else { - if (k > 0) { - AddCode (OPC_SPACE, AM_IMM, NumToStr (-k), 0); + if (k == 0) { + /* Nothing to drop */ + AddCodeLine ("jsr leave"); + } else { + /* We've a stack frame to drop */ + ldyconst (k); + AddCodeLine ("jsr leavey"); } - AddCode (OPC_LEAVE, AM_IMP, 0, 0); } /* Add the final rts */ - AddCode (OPC_RET, AM_IMP, 0, 0); + AddCodeLine ("rts"); } @@ -596,7 +565,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) /*****************************************************************************/ -/* Fetching memory cells */ +/* Fetching memory cells */ /*****************************************************************************/ @@ -604,6 +573,10 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs) /* Load a constant into the primary register */ { + unsigned char B1, B2, B3, B4; + unsigned Done; + + if ((Flags & CF_CONST) != 0) { /* Numeric constant */ @@ -611,16 +584,56 @@ void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs) case CF_CHAR: if ((Flags & CF_FORCECHAR) != 0) { - AddCode (OPC_LDA, AM_IMM, ByteToStr (Val), 0); + ldaconst (Val); break; } /* FALL THROUGH */ case CF_INT: - AddCode (OPC_LDAX, AM_IMM, WordToStr (Val), 0); + ldxconst ((Val >> 8) & 0xFF); + ldaconst (Val & 0xFF); break; case CF_LONG: - AddCode (OPC_LDEAX, AM_IMM, DWordToStr (Val), 0); + /* Split the value into 4 bytes */ + B1 = (unsigned char) (Val >> 0); + B2 = (unsigned char) (Val >> 8); + B3 = (unsigned char) (Val >> 16); + B4 = (unsigned char) (Val >> 24); + + /* Remember which bytes are done */ + Done = 0; + + /* Load the value */ + AddCodeLine ("ldx #$%02X", B2); + Done |= 0x02; + if (B2 == B3) { + AddCodeLine ("stx sreg"); + Done |= 0x04; + } + if (B2 == B4) { + AddCodeLine ("stx sreg+1"); + Done |= 0x08; + } + if ((Done & 0x04) == 0 && B1 != B3) { + AddCodeLine ("lda #$%02X", B3); + AddCodeLine ("sta sreg"); + Done |= 0x04; + } + if ((Done & 0x08) == 0 && B1 != B4) { + AddCodeLine ("lda #$%02X", B4); + AddCodeLine ("sta sreg+1"); + Done |= 0x08; + } + AddCodeLine ("lda #$%02X", B1); + Done |= 0x01; + if ((Done & 0x04) == 0) { + CHECK (B1 == B3); + AddCodeLine ("sta sreg"); + } + if ((Done & 0x08) == 0) { + CHECK (B1 == B4); + AddCodeLine ("sta sreg+1"); + } break; default: @@ -631,8 +644,12 @@ void g_getimmed (unsigned Flags, unsigned long Val, unsigned Offs) } else { - /* Some sort of label, load it into the primary */ - AddCode (OPC_LEA, AM_ABS, GetLabelName (Flags, Val, Offs), 0); + /* Some sort of label */ + const char* Label = GetLabelName (Flags, Val, Offs); + + /* Load the address into the primary */ + AddCodeLine ("lda #<(%s)", Label); + AddCodeLine ("ldx #>(%s)", Label); } } @@ -850,8 +867,33 @@ void g_leasp (int offs) /* Calculate the offset relative to sp */ offs -= oursp; - /* Output code */ - AddCode (OPC_LEA, AM_STACK, WordToStr (offs), 0); + /* For value 0 we do direct code */ + if (offs == 0) { + AddCodeLine ("lda sp"); + AddCodeLine ("ldx sp+1"); + } else { + if (CodeSizeFactor < 300) { + ldaconst (offs); /* Load A with offset value */ + AddCodeLine ("jsr leaasp"); /* Load effective address */ + } else { + unsigned L = GetLocalLabel (); + if (CPU == CPU_65C02 && offs == 1) { + AddCodeLine ("lda sp"); + AddCodeLine ("ldx sp+1"); + AddCodeLine ("ina"); + AddCodeLine ("bne %s", LocalLabelName (L)); + AddCodeLine ("inx"); + } else { + ldaconst (offs); + AddCodeLine ("clc"); + AddCodeLine ("ldx sp+1"); + AddCodeLine ("adc sp"); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("inx"); + } + g_defcodelabel (L); + } + } } @@ -920,15 +962,21 @@ void g_putstatic (unsigned flags, unsigned long label, unsigned offs) switch (flags & CF_TYPE) { case CF_CHAR: - AddCode (OPC_STA, AM_ABS, lbuf, 0); + AddCodeLine ("sta %s", lbuf); break; case CF_INT: - AddCode (OPC_STAX, AM_ABS, lbuf, 0); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("stx %s+1", lbuf); break; case CF_LONG: - AddCode (OPC_STEAX, AM_ABS, lbuf, 0); + AddCodeLine ("sta %s", lbuf); + AddCodeLine ("stx %s+1", lbuf); + AddCodeLine ("ldy sreg"); + AddCodeLine ("sty %s+2", lbuf); + AddCodeLine ("ldy sreg+1"); + AddCodeLine ("sty %s+3", lbuf); break; default: @@ -944,23 +992,78 @@ void g_putlocal (unsigned Flags, int Offs, long Val) { Offs -= oursp; CheckLocalOffs (Offs); - - if (Flags & CF_CONST) { - g_getimmed (Flags, Val, Offs); - } - switch (Flags & CF_TYPE) { case CF_CHAR: - AddCode (OPC_STA, AM_STACK, WordToStr (Offs), 0); + if (Flags & CF_CONST) { + AddCodeLine ("lda #$%02X", (unsigned char) Val); + } + if (CPU == CPU_65C02 && Offs == 0) { + AddCodeLine ("sta (sp)"); + } else { + ldyconst (Offs); + AddCodeLine ("sta (sp),y"); + } break; case CF_INT: - AddCode (OPC_STAX, AM_STACK, WordToStr (Offs), 0); + if (Flags & CF_CONST) { + ldyconst (Offs+1); + AddCodeLine ("lda #$%02X", (unsigned char) (Val >> 8)); + AddCodeLine ("sta (sp),y"); + if ((Flags & CF_NOKEEP) == 0) { + /* Place high byte into X */ + AddCodeLine ("tax"); + } + if (CPU == CPU_65C02 && Offs == 0) { + AddCodeLine ("lda #$%02X", (unsigned char) Val); + AddCodeLine ("sta (sp)"); + } else { + if ((Val & 0xFF) == Offs+1) { + /* The value we need is already in Y */ + AddCodeLine ("tya"); + AddCodeLine ("dey"); + } else { + AddCodeLine ("dey"); + AddCodeLine ("lda #$%02X", (unsigned char) Val); + } + AddCodeLine ("sta (sp),y"); + } + } else { + if ((Flags & CF_NOKEEP) == 0 || CodeSizeFactor < 160) { + if (Offs) { + ldyconst (Offs); + AddCodeLine ("jsr staxysp"); + } else { + AddCodeLine ("jsr stax0sp"); + } + } else { + if (CPU == CPU_65C02 && Offs == 0) { + AddCodeLine ("sta (sp)"); + ldyconst (1); + AddCodeLine ("txa"); + AddCodeLine ("sta (sp),y"); + } else { + ldyconst (Offs); + AddCodeLine ("sta (sp),y"); + AddCodeLine ("iny"); + AddCodeLine ("txa"); + AddCodeLine ("sta (sp),y"); + } + } + } break; case CF_LONG: - AddCode (OPC_STEAX, AM_STACK, WordToStr (Offs), 0); + if (Flags & CF_CONST) { + g_getimmed (Flags, Val, 0); + } + if (Offs) { + ldyconst (Offs); + AddCodeLine ("jsr steaxysp"); + } else { + AddCodeLine ("jsr steax0sp"); + } break; default: @@ -1460,6 +1563,28 @@ void g_addstatic (unsigned flags, unsigned long label, unsigned offs) +/*****************************************************************************/ +/* Compares of ax with a variable with fixed address */ +/*****************************************************************************/ + + + +void g_cmplocal (unsigned flags, int offs) +/* Compare a local variable to ax */ +{ + Internal ("g_cmplocal not implemented"); +} + + + +void g_cmpstatic (unsigned flags, unsigned label, unsigned offs) +/* Compare a static variable to ax */ +{ + Internal ("g_cmpstatic not implemented"); +} + + + /*****************************************************************************/ /* Special op= functions */ /*****************************************************************************/