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.)
This commit is contained in:
Greg King
2020-08-18 19:07:29 -04:00
parent 0690a12ad2
commit 36dd82f0e6
2 changed files with 31 additions and 10 deletions

View File

@@ -2207,7 +2207,7 @@ void g_restore (unsigned flags)
void g_cmp (unsigned flags, unsigned long val) 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. ** 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) void g_lateadjustSP (unsigned label)
/* Adjust stack based on non-immediate data */ /* Adjust stack based on non-immediate data */
{ {
@@ -2764,9 +2779,11 @@ void g_div (unsigned flags, unsigned long val)
/* The result is 0. We can just load 0 and skip the shifting. */ /* The result is 0. We can just load 0 and skip the shifting. */
g_getimmed (flags | CF_ABSOLUTE, 0, 0); g_getimmed (flags | CF_ABSOLUTE, 0, 0);
/* TODO: replace with BEQ? Would it be optimized? */
g_jump (EndLabel); 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. ** later.
*/ */
g_defcodelabel (DoShiftLabel); g_defcodelabel (DoShiftLabel);
@@ -4511,18 +4528,17 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned,
unsigned ZeroExtendLabel = GetLocalLabel (); unsigned ZeroExtendLabel = GetLocalLabel ();
AddCodeLine ("beq %s", LocalLabelName (ZeroExtendLabel)); 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. ** to sign-extend into high byte, too.
*/ */
AddCodeLine ("pla"); AddCodeLine ("pla");
g_or (FullWidthFlags | CF_CONST, ~Mask); g_or (FullWidthFlags | CF_CONST, ~Mask);
/* Apparently, there is no unconditional branch BRA, so use JMP. */
unsigned DoneLabel = GetLocalLabel (); 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 /* 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. ** the branch to share with the other label, because PLA changes some condition codes.
*/ */
g_defcodelabel (ZeroExtendLabel); g_defcodelabel (ZeroExtendLabel);
AddCodeLine ("pla"); AddCodeLine ("pla");
@@ -4534,7 +4550,7 @@ void g_extractbitfield (unsigned Flags, unsigned FullWidthFlags, int IsSigned,
g_defcodelabel (DoneLabel); g_defcodelabel (DoneLabel);
} else { } else {
/* Unsigned bit-field, only needs zero-extension. */ /* Unsigned bit-field, needs only zero-extension. */
if (ZeroExtendMask != 0) { if (ZeroExtendMask != 0) {
g_and (FullWidthFlags | CF_CONST, ZeroExtendMask); g_and (FullWidthFlags | CF_CONST, ZeroExtendMask);
} }

View File

@@ -380,7 +380,7 @@ void g_restore (unsigned flags);
/* Copy hold register to primary. */ /* Copy hold register to primary. */
void g_cmp (unsigned flags, unsigned long val); 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. ** will be set.
*/ */
@@ -410,6 +410,11 @@ void g_truejump (unsigned flags, unsigned label);
void g_falsejump (unsigned flags, unsigned label); void g_falsejump (unsigned flags, unsigned label);
/* Jump to label if zero flag set */ /* 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); void g_lateadjustSP (unsigned label);
/* Adjust stack based on non-immediate data */ /* Adjust stack based on non-immediate data */