mirror of
https://github.com/cc65/cc65.git
synced 2024-11-19 06:31:31 +00:00
Merge pull request #2001 from bbbradsmith/ca65_long_jsr_jmp_rts
ca65 jsr/jmp/rts will not promote to jsl/jml/rtl by default, new feature long_jsr_jmp_rts to re-enable this ability
This commit is contained in:
commit
302d6ee4a4
@ -184,7 +184,7 @@ Here is a description of all the command line options:
|
||||
|
||||
Enable an emulation feature. This is identical as using <tt/.FEATURE/
|
||||
in the source with two exceptions: Feature names must be lower case, and
|
||||
each feature must be specified by using an extra <tt/--feature/ option,
|
||||
each feature must be specified by using a separate <tt/--feature/ option,
|
||||
comma separated lists are not allowed.
|
||||
|
||||
See the discussion of the <tt><ref id=".FEATURE" name=".FEATURE"></tt>
|
||||
@ -2833,6 +2833,23 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
|
||||
overridden. When using this feature, you may also get into trouble if
|
||||
later versions of the assembler define new keywords starting with a dot.
|
||||
|
||||
<tag><tt>long_jsr_jmp_rts</tt><label id="long_jsr_jmp_rts"></tag>
|
||||
|
||||
Affects 65816 mode only.
|
||||
|
||||
Allows <tt>jsr</tt> and <tt>jmp</tt> to produce long jumps if the target
|
||||
address has been previously declared in a <tt>far</tt> segment,
|
||||
or imported as <tt>far</tt>.
|
||||
Otherwise <tt>jsl</tt> and <tt>jml</tt> must be used instead.
|
||||
|
||||
Also allows <tt><ref id=".SMART" name=".SMART"></tt> to convert <tt>rts</tt>
|
||||
to a long return <tt>rtl</tt> when the enclosing scope or memory model
|
||||
indicates returning from a <tt>far</tt> procedure.
|
||||
|
||||
This permits compatibility with the old behavior of this assembler, or other
|
||||
assemblers which similarly allowed <tt>jsr</tt> and <tt>jmp</tt> to be used
|
||||
this way.
|
||||
|
||||
<tag><tt>loose_char_term</tt><label id="loose_char_term"></tag>
|
||||
|
||||
Accept single quotes as well as double quotes as terminators for char
|
||||
@ -4002,7 +4019,9 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".BYTE" name=".BYTE"
|
||||
the assembler cannot trace the execution flow this may lead to false
|
||||
results in some cases. If in doubt, use the <tt/.Inn/ and <tt/.Ann/
|
||||
instructions to tell the assembler about the current settings.
|
||||
<item>In 65816 mode, replace a <tt/RTS/ instruction by <tt/RTL/ if it is
|
||||
<item>In 65816 mode, if the <tt><ref id="long_jsr_jmp_rts"
|
||||
name="long_jsr_jmp_rts"></tt> feature is enabled,
|
||||
smart mode will replace a <tt/RTS/ instruction by <tt/RTL/ if it is
|
||||
used within a procedure declared as <tt/far/, or if the procedure has
|
||||
no explicit address specification, but it is <tt/far/ because of the
|
||||
memory model used.
|
||||
|
@ -66,6 +66,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = {
|
||||
"addrsize",
|
||||
"bracket_as_indirect",
|
||||
"string_escapes",
|
||||
"long_jsr_jmp_rts",
|
||||
};
|
||||
|
||||
|
||||
@ -125,6 +126,7 @@ feature_t SetFeature (const StrBuf* Key)
|
||||
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break;
|
||||
case FEAT_STRING_ESCAPES: StringEscapes = 1; break;
|
||||
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = 1; break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ typedef enum {
|
||||
FEAT_ADDRSIZE,
|
||||
FEAT_BRACKET_AS_INDIRECT,
|
||||
FEAT_STRING_ESCAPES,
|
||||
FEAT_LONG_JSR_JMP_RTS,
|
||||
|
||||
/* Special value: Number of features available */
|
||||
FEAT_COUNT
|
||||
|
@ -67,6 +67,7 @@ unsigned char LineCont = 0; /* Allow line continuation */
|
||||
unsigned char LargeAlignment = 0; /* Don't warn about large alignments */
|
||||
unsigned char RelaxChecks = 0; /* Relax a few assembler checks */
|
||||
unsigned char StringEscapes = 0; /* Allow C-style escapes in strings */
|
||||
unsigned char LongJsrJmpRts = 0; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||
unsigned char WarningsAsErrors = 0; /* Error if any warnings */
|
||||
|
||||
/* Emulation features */
|
||||
|
@ -69,6 +69,7 @@ extern unsigned char LineCont; /* Allow line continuation */
|
||||
extern unsigned char LargeAlignment; /* Don't warn about large alignments */
|
||||
extern unsigned char RelaxChecks; /* Relax a few assembler checks */
|
||||
extern unsigned char StringEscapes; /* Allow C-style escapes in strings */
|
||||
extern unsigned char LongJsrJmpRts; /* Allow JSR/JMP/RTS as alias for JSL/JML/RTL */
|
||||
extern unsigned char WarningsAsErrors; /* Error if any warnings */
|
||||
|
||||
/* Emulation features */
|
||||
|
@ -120,9 +120,21 @@ static void PutJMP (const InsDesc* Ins);
|
||||
** to check for this case and is otherwise identical to PutAll.
|
||||
*/
|
||||
|
||||
static void PutJMP816 (const InsDesc* Ins);
|
||||
/* Handle the JMP instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JMP.
|
||||
** Note that JMP [abs] and JML [abs] are always both permitted for instruction $DC,
|
||||
** because the [] notation for long indirection makes the generated instruction unambiguous.
|
||||
*/
|
||||
|
||||
static void PutJSR816 (const InsDesc* Ins);
|
||||
/* Handle the JSR instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JSR.
|
||||
*/
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)));
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR.
|
||||
** the enclosing scope is FAR, but only if the long_jsr_jmp_rts feature applies.
|
||||
*/
|
||||
|
||||
static void PutAll (const InsDesc* Ins);
|
||||
@ -758,9 +770,9 @@ static const struct {
|
||||
{ "INX", 0x0000001, 0xe8, 0, PutAll },
|
||||
{ "INY", 0x0000001, 0xc8, 0, PutAll },
|
||||
{ "JML", 0x4000010, 0x5c, 1, PutAll },
|
||||
{ "JMP", 0x4010818, 0x4c, 6, PutAll },
|
||||
{ "JMP", 0x4010818, 0x4c, 6, PutJMP816 },
|
||||
{ "JSL", 0x0000010, 0x20, 7, PutAll },
|
||||
{ "JSR", 0x0010018, 0x20, 7, PutAll },
|
||||
{ "JSR", 0x0010018, 0x20, 7, PutJSR816 },
|
||||
{ "LDA", 0x0b8f6fc, 0xa0, 0, PutAll },
|
||||
{ "LDX", 0x0c0030c, 0xa2, 1, PutAll },
|
||||
{ "LDY", 0x0c0006c, 0xa0, 1, PutAll },
|
||||
@ -1627,12 +1639,46 @@ static void PutJMP (const InsDesc* Ins)
|
||||
|
||||
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)))
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR.
|
||||
static void PutJMP816 (const InsDesc* Ins)
|
||||
/* Handle the JMP instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JMP.
|
||||
** Note that JMP [abs] and JML [abs] are always both permitted for instruction $DC,
|
||||
** because the [] notation for long indirection makes the generated instruction unambiguous.
|
||||
*/
|
||||
{
|
||||
if (SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
|
||||
if (LongJsrJmpRts) {
|
||||
PutJMP (Ins);
|
||||
} else {
|
||||
InsDesc InsAbs = *Ins;
|
||||
InsAbs.AddrMode &= ~(AM65_ABS_LONG);
|
||||
PutJMP (&InsAbs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void PutJSR816 (const InsDesc* Ins)
|
||||
/* Handle the JSR instruction for the 816.
|
||||
** Allowing the long_jsr_jmp_rts feature to permit a long JSR.
|
||||
*/
|
||||
{
|
||||
if (LongJsrJmpRts) {
|
||||
PutAll (Ins);
|
||||
} else {
|
||||
InsDesc InsAbs = *Ins;
|
||||
InsAbs.AddrMode &= ~(AM65_ABS_LONG);
|
||||
PutJMP (&InsAbs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void PutRTS (const InsDesc* Ins attribute ((unused)))
|
||||
/* Handle the RTS instruction for the 816. In smart mode emit a RTL opcode if
|
||||
** the enclosing scope is FAR, but only if the long_jsr_jmp_rts feature applies.
|
||||
*/
|
||||
{
|
||||
if (LongJsrJmpRts && SmartMode && CurrentScope->AddrSize == ADDR_SIZE_FAR) {
|
||||
Emit0 (0x6B); /* RTL */
|
||||
} else {
|
||||
Emit0 (0x60); /* RTS */
|
||||
|
@ -3,5 +3,5 @@ GLOBAL {
|
||||
};
|
||||
|
||||
RANGE { START $8000; END $8229; ADDRMODE "MX"; TYPE Code;};
|
||||
RANGE { START $822a; END $824b; ADDRMODE "mx"; TYPE Code;};
|
||||
RANGE { START $822a; END $825b; ADDRMODE "mx"; TYPE Code;};
|
||||
|
||||
|
@ -151,10 +151,11 @@ BVC LABEL
|
||||
BVS LABEL
|
||||
BRL LABEL
|
||||
JMP $1234
|
||||
JMP $FEDCBA
|
||||
JML $FEDCBA
|
||||
JMP ($1234)
|
||||
JMP ($1234,X)
|
||||
JMP [$1234]
|
||||
JML [$1234] ; alternative to JMP []
|
||||
JSL $123456
|
||||
JSR $1234
|
||||
JSR ($1234,X)
|
||||
@ -271,3 +272,15 @@ BIT #$5432
|
||||
LDA #$5432
|
||||
LDX #$5432
|
||||
LDY #$5432
|
||||
|
||||
; test of smart and long_jsr_jmp_rts
|
||||
.smart
|
||||
.proc short_rts : far
|
||||
RTS ; not promoted to RTL
|
||||
.endproc
|
||||
.feature long_jsr_jmp_rts
|
||||
JSR $FEDCBA ; promoted to JSL
|
||||
JMP $FEDCBA ; promoted to JML
|
||||
.proc long_rts : far
|
||||
RTS ; promoted to RTL
|
||||
.endproc
|
||||
|
Loading…
Reference in New Issue
Block a user