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:
Antonio Niño Díaz
2018-02-24 15:43:55 +00:00
parent 2a97535e75
commit 6ad5bd2325
9 changed files with 70 additions and 29 deletions

View File

@@ -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">&#x00A0;</dt> <dt class="It-tag">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</dd> <dd class="It-tag">&#x00A0;</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">&#x00A0;</dt>
<dd class="It-tag">&#x00A0;</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 &#x2014; it must first The resulting object file is not yet a usable ROM image &#x2014; 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 &#x2014; 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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. */
}; };

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 ,