From 36dd82f0e61a2c288bf4dda16ef9a3a69bc6c044 Mon Sep 17 00:00:00 2001 From: Greg King Date: Tue, 18 Aug 2020 19:07:29 -0400 Subject: [PATCH] Added g_branch() to cc65's code generator. It uses BRA if the platform's CPU has BRA. Else, it generates a JMP. (Used it in the bitfield sign-extending code.) --- src/cc65/codegen.c | 34 +++++++++++++++++++++++++--------- src/cc65/codegen.h | 7 ++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index a0dbc498b..6b6b292b0 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -2207,7 +2207,7 @@ void g_restore (unsigned flags) void g_cmp (unsigned flags, unsigned long val) -/* Immidiate compare. The primary register will not be changed, Z flag +/* Immediate compare. The primary register will not be changed, Z flag ** will be set. */ { @@ -2455,6 +2455,21 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) } + +void g_branch (unsigned Label) +/* Branch unconditionally to Label if the CPU has the BRA instruction. +** Otherwise, jump to Label. +*/ +{ + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0) { + AddCodeLine ("bra %s", LocalLabelName (Label)); + } else { + g_jump (Label); + } +} + + + void g_lateadjustSP (unsigned label) /* Adjust stack based on non-immediate data */ { @@ -2761,12 +2776,14 @@ void g_div (unsigned flags, unsigned long val) AddCodeLine ("lsr a"); g_restore (flags); AddCodeLine ("bcs %s", LocalLabelName (DoShiftLabel)); - + /* The result is 0. We can just load 0 and skip the shifting. */ g_getimmed (flags | CF_ABSOLUTE, 0, 0); + + /* TODO: replace with BEQ? Would it be optimized? */ g_jump (EndLabel); - /* Do the shift. The sign of the result may need be corrected + /* Do the shift. The sign of the result may need to be corrected ** later. */ g_defcodelabel (DoShiftLabel); @@ -4511,18 +4528,17 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, unsigned ZeroExtendLabel = GetLocalLabel (); AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); - /* Pop A back and sign extend if required; operating on the full result need + /* Pop A back and sign-extend if required; operating on the full result needs ** to sign-extend into high byte, too. */ AddCodeLine ("pla"); g_or (FullWidthFlags | CF_CONST, ~Mask); - /* Apparently, there is no unconditional branch BRA, so use JMP. */ unsigned DoneLabel = GetLocalLabel (); - AddCodeLine ("jmp %s", LocalLabelName (DoneLabel)); + g_branch (DoneLabel); - /* Pop A back, then zero-extend; we need to duplicate the PLA rather than move it before - ** the branch to share with the other label because PLA sets the condition codes. + /* Pop A back, then zero-extend. We need to duplicate the PLA, rather than move it before + ** the branch to share with the other label, because PLA changes some condition codes. */ g_defcodelabel (ZeroExtendLabel); AddCodeLine ("pla"); @@ -4534,7 +4550,7 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned, g_defcodelabel (DoneLabel); } else { - /* Unsigned bit-field, only needs zero-extension. */ + /* Unsigned bit-field, needs only zero-extension. */ if (ZeroExtendMask != 0) { g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); } diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index ec4756f2d..d946a9a10 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -380,7 +380,7 @@ void g_restore (unsigned flags); /* Copy hold register to primary. */ void g_cmp (unsigned flags, unsigned long val); -/* Immidiate compare. The primary register will not be changed, Z flag +/* Immediate compare. The primary register will not be changed, Z flag ** will be set. */ @@ -410,6 +410,11 @@ void g_truejump (unsigned flags, unsigned label); void g_falsejump (unsigned flags, unsigned label); /* Jump to label if zero flag set */ +void g_branch (unsigned Label); +/* Branch unconditionally to Label if the CPU has the BRA instruction. +** Otherwise, jump to Label. +*/ + void g_lateadjustSP (unsigned label); /* Adjust stack based on non-immediate data */