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">
<tr>
<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>
<var class="Ar" title="Ar">chars</var></span>]
[<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>
<dt class="It-tag">&#x00A0;</dt>
<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>
<var class="Ar" title="Ar">dependfile</var></dt>
<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>
Assembling a basic source file is simple:
<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>
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
@@ -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>
<table class="foot">
<tr>
<td class="foot-date">January 26, 2018</td>
<td class="foot-date">February 24, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</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 A,[$FF00+n8]</b> syntax instead. This forces
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>
<div class="Pp"></div>
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>
<table class="foot">
<tr>
<td class="foot-date">January 27, 2018</td>
<td class="foot-date">February 24, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>

View File

@@ -26,9 +26,13 @@
<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:
<div class="Pp"></div>
<div class="D1">$ rgbasm -o bar.o foo.asm</div>
<div class="D1">$ rgblink -o baz.gb bar.o</div>
<div class="D1">$ rgbfix -v -p 0 baz.gb</div>
<div class="Bd" style="margin-left: 5.00ex;">
<pre class="Li">
$ 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
ALSO</a></h1>
<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>
<table class="foot">
<tr>
<td class="foot-date">January 26, 2018</td>
<td class="foot-date">February 24, 2018</td>
<td class="foot-os">RGBDS Manual</td>
</tr>
</table>

View File

@@ -15,12 +15,13 @@
#include "extern/stdnoreturn.h"
struct sOptions {
char gbgfx[4];
char binary[2];
int32_t fillchar;
bool verbose;
bool haltnop;
char gbgfx[4];
bool exportall;
int32_t fillchar;
bool haltnop;
bool optimizeloads;
bool verbose;
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
{
if ((!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
if (CurrentOptions.optimizeloads &&
(!rpn_isReloc(&$2)) && ($2.nVal >= 0xFF00)) {
out_AbsByte(0xE0);
out_AbsByte($2.nVal & 0xFF);
} 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
{
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($4.nVal & 0xFF);
} else {

View File

@@ -282,7 +282,7 @@ void warning(const char *fmt, ...)
static void print_usage(void)
{
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");
exit(1);
}
@@ -316,17 +316,18 @@ int main(int argc, char *argv[])
DefaultOptions.gbgfx[3] = '3';
DefaultOptions.binary[0] = '0';
DefaultOptions.binary[1] = '1';
DefaultOptions.fillchar = 0;
DefaultOptions.verbose = false;
DefaultOptions.haltnop = true;
DefaultOptions.exportall = false;
DefaultOptions.fillchar = 0;
DefaultOptions.optimizeloads = true;
DefaultOptions.haltnop = true;
DefaultOptions.verbose = false;
DefaultOptions.warnings = true;
opt_SetCurrentOptions(&DefaultOptions);
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) {
case 'b':
if (strlen(optarg) == 2) {
@@ -358,6 +359,9 @@ int main(int argc, char *argv[])
case 'i':
fstk_AddIncludePath(optarg);
break;
case 'L':
newopt.optimizeloads = false;
break;
case 'M':
dependfile = fopen(optarg, "w");
if (dependfile == NULL)

View File

@@ -5,7 +5,7 @@
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 26, 2018
.Dd February 24, 2018
.Dt RGBASM 1
.Os RGBDS Manual
.Sh NAME
@@ -13,7 +13,7 @@
.Nd Game Boy assembler
.Sh SYNOPSIS
.Nm rgbasm
.Op Fl EhVvw
.Op Fl EhLVvw
.Op Fl b Ar chars
.Op Fl D Ar name Ns Op = Ns Ar value
.Op Fl g Ar chars
@@ -55,6 +55,12 @@ The
option disables this behavior.
.It Fl i Ar 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
Print
.Xr make 1
@@ -75,7 +81,9 @@ Disable warning output.
.Sh EXAMPLES
Assembling a basic source file is simple:
.Pp
.D1 $ rgbasm -o bar.o foo.asm
.Bd -literal -offset indent
$ rgbasm -o bar.o foo.asm
.Ed
.Pp
The resulting object file is not yet a usable ROM image \(em it must first be
run through

View File

@@ -5,7 +5,7 @@
.\"
.\" SPDX-License-Identifier: MIT
.\"
.Dd January 27, 2018
.Dd February 24, 2018
.Dt RGBASM 5
.Os RGBDS Manual
.Sh NAME
@@ -110,7 +110,13 @@ and
.Sy LDH A,[$FF00+n8]
syntax instead.
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
.Pp
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
.\"
.Dd January 26, 2018
.Dd February 24, 2018
.Dt RGBDS 7
.Os RGBDS Manual
.Sh NAME
@@ -14,9 +14,11 @@
.Sh EXAMPLES
To get a working ROM image from a single assembly source file:
.Pp
.D1 $ rgbasm \-o bar.o foo.asm
.D1 $ rgblink \-o baz.gb bar.o
.D1 $ rgbfix \-v \-p 0 baz.gb
.Bd -literal -offset indent
$ rgbasm \-o bar.o foo.asm
$ rgblink \-o baz.gb bar.o
$ rgbfix \-v \-p 0 baz.gb
.Ed
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,