mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 10:42:07 +00:00
Add flag to rgbasm to disable LD->LDH optimization
rgbasm tries to optimize any loads from/to $FF00-$FFFF and generate LDH 2-byte opcodes instead of regular LD 3-byte opcodes. This is a bit inconsistent as it only works for constant values. If a load is trying to access a label in a HRAM floating section, or a section found in a different object file, this optimization doesn't work. This means that a simple refactor or code could allow rgbasm to perform the optimzation or prevent it from doing so. For certain projects, like disassemblies, this is a problem. This patch adds flag -L to rgbasm to disable the optimization, and doesn't change the behaviour of any other existing code. Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
<table class="Nm">
|
<table class="Nm">
|
||||||
<tr>
|
<tr>
|
||||||
<td><b class="Nm" title="Nm">rgbasm</b></td>
|
<td><b class="Nm" title="Nm">rgbasm</b></td>
|
||||||
<td>[<span class="Op"><b class="Fl" title="Fl">-EhVvw</b></span>]
|
<td>[<span class="Op"><b class="Fl" title="Fl">-EhLVvw</b></span>]
|
||||||
[<span class="Op"><b class="Fl" title="Fl">-b</b>
|
[<span class="Op"><b class="Fl" title="Fl">-b</b>
|
||||||
<var class="Ar" title="Ar">chars</var></span>]
|
<var class="Ar" title="Ar">chars</var></span>]
|
||||||
[<span class="Op"><b class="Fl" title="Fl">-D</b>
|
[<span class="Op"><b class="Fl" title="Fl">-D</b>
|
||||||
@@ -89,6 +89,13 @@ The <b class="Nm" title="Nm">rgbasm</b> program creates an object file from an
|
|||||||
<dd class="It-tag">Add an include path.</dd>
|
<dd class="It-tag">Add an include path.</dd>
|
||||||
<dt class="It-tag"> </dt>
|
<dt class="It-tag"> </dt>
|
||||||
<dd class="It-tag"> </dd>
|
<dd class="It-tag"> </dd>
|
||||||
|
<dt class="It-tag"><a class="selflink" href="#L"><b class="Fl" title="Fl" id="L">-L</b></a></dt>
|
||||||
|
<dd class="It-tag">Disable the optimization that turns loads of the form
|
||||||
|
<b class="Sy" title="Sy">LD [$FF00+n8],A</b> into the opcode
|
||||||
|
<b class="Sy" title="Sy">LDH [$FF00+n8],A</b> in order to have full
|
||||||
|
control of the result in the final ROM.</dd>
|
||||||
|
<dt class="It-tag"> </dt>
|
||||||
|
<dd class="It-tag"> </dd>
|
||||||
<dt class="It-tag"><a class="selflink" href="#M"><b class="Fl" title="Fl" id="M">-M</b></a>
|
<dt class="It-tag"><a class="selflink" href="#M"><b class="Fl" title="Fl" id="M">-M</b></a>
|
||||||
<var class="Ar" title="Ar">dependfile</var></dt>
|
<var class="Ar" title="Ar">dependfile</var></dt>
|
||||||
<dd class="It-tag">Print <a class="Xr" title="Xr">make(1)</a> dependencies to
|
<dd class="It-tag">Print <a class="Xr" title="Xr">make(1)</a> dependencies to
|
||||||
@@ -120,7 +127,11 @@ The <b class="Nm" title="Nm">rgbasm</b> program creates an object file from an
|
|||||||
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
||||||
Assembling a basic source file is simple:
|
Assembling a basic source file is simple:
|
||||||
<div class="Pp"></div>
|
<div class="Pp"></div>
|
||||||
<div class="D1">$ rgbasm -o bar.o foo.asm</div>
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||||||
|
<pre class="Li">
|
||||||
|
$ rgbasm -o bar.o foo.asm
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
<div class="Pp"></div>
|
<div class="Pp"></div>
|
||||||
The resulting object file is not yet a usable ROM image — it must first
|
The resulting object file is not yet a usable ROM image — it must first
|
||||||
be run through <a class="Xr" title="Xr">rgblink(1)</a> and
|
be run through <a class="Xr" title="Xr">rgblink(1)</a> and
|
||||||
@@ -138,7 +149,7 @@ The resulting object file is not yet a usable ROM image — it must first
|
|||||||
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
|
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
|
||||||
<table class="foot">
|
<table class="foot">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="foot-date">January 26, 2018</td>
|
<td class="foot-date">February 24, 2018</td>
|
||||||
<td class="foot-os">RGBDS Manual</td>
|
<td class="foot-os">RGBDS Manual</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -125,7 +125,10 @@ Possible section types are as follows:
|
|||||||
<b class="Sy" title="Sy">LDH [$FF00+n8],A</b> and
|
<b class="Sy" title="Sy">LDH [$FF00+n8],A</b> and
|
||||||
<b class="Sy" title="Sy">LDH A,[$FF00+n8]</b> syntax instead. This forces
|
<b class="Sy" title="Sy">LDH A,[$FF00+n8]</b> syntax instead. This forces
|
||||||
the assembler to emit the correct instruction and the linker to check if
|
the assembler to emit the correct instruction and the linker to check if
|
||||||
the value is in the correct range.</dd>
|
the value is in the correct range. This optimization can be disabled by
|
||||||
|
passing the <b class="Fl" title="Fl">-L</b> flag to
|
||||||
|
<b class="Sy" title="Sy">rgbasm</b> as explained in
|
||||||
|
<a class="Xr" title="Xr">rgbasm(1)</a>.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<div class="Pp"></div>
|
<div class="Pp"></div>
|
||||||
A section is usually defined as a floating one, but the code can restrict where
|
A section is usually defined as a floating one, but the code can restrict where
|
||||||
@@ -1462,7 +1465,7 @@ The options that OPT can modify are currently: <b class="Sy" title="Sy">b</b>,
|
|||||||
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
|
<a class="Lk" title="Lk" href="https://github.com/rednex/rgbds">https://github.com/rednex/rgbds</a>.</div>
|
||||||
<table class="foot">
|
<table class="foot">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="foot-date">January 27, 2018</td>
|
<td class="foot-date">February 24, 2018</td>
|
||||||
<td class="foot-os">RGBDS Manual</td>
|
<td class="foot-os">RGBDS Manual</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -26,9 +26,13 @@
|
|||||||
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
<h1 class="Sh" title="Sh" id="EXAMPLES"><a class="selflink" href="#EXAMPLES">EXAMPLES</a></h1>
|
||||||
To get a working ROM image from a single assembly source file:
|
To get a working ROM image from a single assembly source file:
|
||||||
<div class="Pp"></div>
|
<div class="Pp"></div>
|
||||||
<div class="D1">$ rgbasm -o bar.o foo.asm</div>
|
<div class="Bd" style="margin-left: 5.00ex;">
|
||||||
<div class="D1">$ rgblink -o baz.gb bar.o</div>
|
<pre class="Li">
|
||||||
<div class="D1">$ rgbfix -v -p 0 baz.gb</div>
|
$ rgbasm -o bar.o foo.asm
|
||||||
|
$ rgblink -o baz.gb bar.o
|
||||||
|
$ rgbfix -v -p 0 baz.gb
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
|
<h1 class="Sh" title="Sh" id="SEE_ALSO"><a class="selflink" href="#SEE_ALSO">SEE
|
||||||
ALSO</a></h1>
|
ALSO</a></h1>
|
||||||
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgbfix(1)</a>,
|
<a class="Xr" title="Xr">rgbasm(1)</a>, <a class="Xr" title="Xr">rgbfix(1)</a>,
|
||||||
@@ -58,7 +62,7 @@ To get a working ROM image from a single assembly source file:
|
|||||||
</div>
|
</div>
|
||||||
<table class="foot">
|
<table class="foot">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="foot-date">January 26, 2018</td>
|
<td class="foot-date">February 24, 2018</td>
|
||||||
<td class="foot-os">RGBDS Manual</td>
|
<td class="foot-os">RGBDS Manual</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
#include "extern/stdnoreturn.h"
|
#include "extern/stdnoreturn.h"
|
||||||
|
|
||||||
struct sOptions {
|
struct sOptions {
|
||||||
char gbgfx[4];
|
|
||||||
char binary[2];
|
char binary[2];
|
||||||
int32_t fillchar;
|
char gbgfx[4];
|
||||||
bool verbose;
|
|
||||||
bool haltnop;
|
|
||||||
bool exportall;
|
bool exportall;
|
||||||
|
int32_t fillchar;
|
||||||
|
bool haltnop;
|
||||||
|
bool optimizeloads;
|
||||||
|
bool verbose;
|
||||||
bool warnings; /* True to enable warnings, false to disable them. */
|
bool warnings; /* True to enable warnings, false to disable them. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1728,7 +1728,8 @@ z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP
|
|||||||
}
|
}
|
||||||
| T_Z80_LD op_mem_ind comma T_MODE_A
|
| T_Z80_LD op_mem_ind comma T_MODE_A
|
||||||
{
|
{
|
||||||
if ((!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
|
if (CurrentOptions.optimizeloads &&
|
||||||
|
(!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
|
||||||
out_AbsByte(0xE0);
|
out_AbsByte(0xE0);
|
||||||
out_AbsByte($2.nVal & 0xFF);
|
out_AbsByte($2.nVal & 0xFF);
|
||||||
} else {
|
} else {
|
||||||
@@ -1781,7 +1782,8 @@ z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND
|
|||||||
| T_Z80_LD reg_r comma op_mem_ind
|
| T_Z80_LD reg_r comma op_mem_ind
|
||||||
{
|
{
|
||||||
if ($2 == REG_A) {
|
if ($2 == REG_A) {
|
||||||
if ((!rpn_isReloc(&$4)) && ($4.nVal >= 0xFF00)) {
|
if (CurrentOptions.optimizeloads &&
|
||||||
|
(!rpn_isReloc(&$4)) && ($4.nVal >= 0xFF00)) {
|
||||||
out_AbsByte(0xF0);
|
out_AbsByte(0xF0);
|
||||||
out_AbsByte($4.nVal & 0xFF);
|
out_AbsByte($4.nVal & 0xFF);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ void warning(const char *fmt, ...)
|
|||||||
static void print_usage(void)
|
static void print_usage(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
|
"usage: rgbasm [-EhLVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
|
||||||
" [-M dependfile] [-o outfile] [-p pad_value] file.asm\n");
|
" [-M dependfile] [-o outfile] [-p pad_value] file.asm\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -316,17 +316,18 @@ int main(int argc, char *argv[])
|
|||||||
DefaultOptions.gbgfx[3] = '3';
|
DefaultOptions.gbgfx[3] = '3';
|
||||||
DefaultOptions.binary[0] = '0';
|
DefaultOptions.binary[0] = '0';
|
||||||
DefaultOptions.binary[1] = '1';
|
DefaultOptions.binary[1] = '1';
|
||||||
DefaultOptions.fillchar = 0;
|
|
||||||
DefaultOptions.verbose = false;
|
|
||||||
DefaultOptions.haltnop = true;
|
|
||||||
DefaultOptions.exportall = false;
|
DefaultOptions.exportall = false;
|
||||||
|
DefaultOptions.fillchar = 0;
|
||||||
|
DefaultOptions.optimizeloads = true;
|
||||||
|
DefaultOptions.haltnop = true;
|
||||||
|
DefaultOptions.verbose = false;
|
||||||
DefaultOptions.warnings = true;
|
DefaultOptions.warnings = true;
|
||||||
|
|
||||||
opt_SetCurrentOptions(&DefaultOptions);
|
opt_SetCurrentOptions(&DefaultOptions);
|
||||||
|
|
||||||
newopt = CurrentOptions;
|
newopt = CurrentOptions;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "b:D:g:hi:M:o:p:EVvw")) != -1) {
|
while ((ch = getopt(argc, argv, "b:D:Eg:hi:LM:o:p:Vvw")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'b':
|
case 'b':
|
||||||
if (strlen(optarg) == 2) {
|
if (strlen(optarg) == 2) {
|
||||||
@@ -358,6 +359,9 @@ int main(int argc, char *argv[])
|
|||||||
case 'i':
|
case 'i':
|
||||||
fstk_AddIncludePath(optarg);
|
fstk_AddIncludePath(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
newopt.optimizeloads = false;
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
dependfile = fopen(optarg, "w");
|
dependfile = fopen(optarg, "w");
|
||||||
if (dependfile == NULL)
|
if (dependfile == NULL)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" SPDX-License-Identifier: MIT
|
.\" SPDX-License-Identifier: MIT
|
||||||
.\"
|
.\"
|
||||||
.Dd January 26, 2018
|
.Dd February 24, 2018
|
||||||
.Dt RGBASM 1
|
.Dt RGBASM 1
|
||||||
.Os RGBDS Manual
|
.Os RGBDS Manual
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
.Nd Game Boy assembler
|
.Nd Game Boy assembler
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm rgbasm
|
.Nm rgbasm
|
||||||
.Op Fl EhVvw
|
.Op Fl EhLVvw
|
||||||
.Op Fl b Ar chars
|
.Op Fl b Ar chars
|
||||||
.Op Fl D Ar name Ns Op = Ns Ar value
|
.Op Fl D Ar name Ns Op = Ns Ar value
|
||||||
.Op Fl g Ar chars
|
.Op Fl g Ar chars
|
||||||
@@ -55,6 +55,12 @@ The
|
|||||||
option disables this behavior.
|
option disables this behavior.
|
||||||
.It Fl i Ar path
|
.It Fl i Ar path
|
||||||
Add an include path.
|
Add an include path.
|
||||||
|
.It Fl L
|
||||||
|
Disable the optimization that turns loads of the form
|
||||||
|
.Sy LD [$FF00+n8],A
|
||||||
|
into the opcode
|
||||||
|
.Sy LDH [$FF00+n8],A
|
||||||
|
in order to have full control of the result in the final ROM.
|
||||||
.It Fl M Ar dependfile
|
.It Fl M Ar dependfile
|
||||||
Print
|
Print
|
||||||
.Xr make 1
|
.Xr make 1
|
||||||
@@ -75,7 +81,9 @@ Disable warning output.
|
|||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
Assembling a basic source file is simple:
|
Assembling a basic source file is simple:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 $ rgbasm -o bar.o foo.asm
|
.Bd -literal -offset indent
|
||||||
|
$ rgbasm -o bar.o foo.asm
|
||||||
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The resulting object file is not yet a usable ROM image \(em it must first be
|
The resulting object file is not yet a usable ROM image \(em it must first be
|
||||||
run through
|
run through
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" SPDX-License-Identifier: MIT
|
.\" SPDX-License-Identifier: MIT
|
||||||
.\"
|
.\"
|
||||||
.Dd January 27, 2018
|
.Dd February 24, 2018
|
||||||
.Dt RGBASM 5
|
.Dt RGBASM 5
|
||||||
.Os RGBDS Manual
|
.Os RGBDS Manual
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -110,7 +110,13 @@ and
|
|||||||
.Sy LDH A,[$FF00+n8]
|
.Sy LDH A,[$FF00+n8]
|
||||||
syntax instead.
|
syntax instead.
|
||||||
This forces the assembler to emit the correct instruction and the linker to
|
This forces the assembler to emit the correct instruction and the linker to
|
||||||
check if the value is in the correct range.
|
check if the value is in the correct range. This optimization can be disabled
|
||||||
|
by passing the
|
||||||
|
.Fl L
|
||||||
|
flag to
|
||||||
|
.Sy rgbasm
|
||||||
|
as explained in
|
||||||
|
.Xr rgbasm 1 .
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
A section is usually defined as a floating one, but the code can restrict where
|
A section is usually defined as a floating one, but the code can restrict where
|
||||||
|
|||||||
10
src/rgbds.7
10
src/rgbds.7
@@ -5,7 +5,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" SPDX-License-Identifier: MIT
|
.\" SPDX-License-Identifier: MIT
|
||||||
.\"
|
.\"
|
||||||
.Dd January 26, 2018
|
.Dd February 24, 2018
|
||||||
.Dt RGBDS 7
|
.Dt RGBDS 7
|
||||||
.Os RGBDS Manual
|
.Os RGBDS Manual
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -14,9 +14,11 @@
|
|||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
To get a working ROM image from a single assembly source file:
|
To get a working ROM image from a single assembly source file:
|
||||||
.Pp
|
.Pp
|
||||||
.D1 $ rgbasm \-o bar.o foo.asm
|
.Bd -literal -offset indent
|
||||||
.D1 $ rgblink \-o baz.gb bar.o
|
$ rgbasm \-o bar.o foo.asm
|
||||||
.D1 $ rgbfix \-v \-p 0 baz.gb
|
$ rgblink \-o baz.gb bar.o
|
||||||
|
$ rgbfix \-v \-p 0 baz.gb
|
||||||
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr rgbasm 1 ,
|
.Xr rgbasm 1 ,
|
||||||
.Xr rgbfix 1 ,
|
.Xr rgbfix 1 ,
|
||||||
|
|||||||
Reference in New Issue
Block a user