shithub: rgbds

Download patch

ref: 6ad5bd232504801b1b6b911c918677a7aff2c698
parent: 2a97535e75be78ca1e7ec47587849a7e0d82fb86
author: Antonio Niño Díaz <antonio_nd@outlook.com>
date: Sat Feb 24 10:43:55 EST 2018

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>

--- a/docs/rgbasm.1.html
+++ b/docs/rgbasm.1.html
@@ -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 @@
   <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 @@
 <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 @@
   <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>
--- a/docs/rgbasm.5.html
+++ b/docs/rgbasm.5.html
@@ -125,7 +125,10 @@
       <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 @@
   <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>
--- a/docs/rgbds.7.html
+++ b/docs/rgbds.7.html
@@ -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 @@
 </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>
--- a/include/asm/main.h
+++ b/include/asm/main.h
@@ -15,12 +15,13 @@
 #include "extern/stdnoreturn.h"
 
 struct sOptions {
-	char gbgfx[4];
 	char binary[2];
+	char gbgfx[4];
+	bool exportall;
 	int32_t fillchar;
-	bool verbose;
 	bool haltnop;
-	bool exportall;
+	bool optimizeloads;
+	bool verbose;
 	bool warnings; /* True to enable warnings, false to disable them. */
 };
 
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1728,7 +1728,8 @@
 		}
 		| 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 @@
 		| 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 {
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -282,7 +282,7 @@
 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,10 +316,11 @@
 	DefaultOptions.gbgfx[3] = '3';
 	DefaultOptions.binary[0] = '0';
 	DefaultOptions.binary[1] = '1';
+	DefaultOptions.exportall = false;
 	DefaultOptions.fillchar = 0;
-	DefaultOptions.verbose = false;
+	DefaultOptions.optimizeloads = true;
 	DefaultOptions.haltnop = true;
-	DefaultOptions.exportall = false;
+	DefaultOptions.verbose = false;
 	DefaultOptions.warnings = true;
 
 	opt_SetCurrentOptions(&DefaultOptions);
@@ -326,7 +327,7 @@
 
 	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) {
@@ -357,6 +358,9 @@
 			break;
 		case 'i':
 			fstk_AddIncludePath(optarg);
+			break;
+		case 'L':
+			newopt.optimizeloads = false;
 			break;
 		case 'M':
 			dependfile = fopen(optarg, "w");
--- a/src/asm/rgbasm.1
+++ b/src/asm/rgbasm.1
@@ -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 @@
 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 @@
 .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
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -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 @@
 .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
--- a/src/rgbds.7
+++ b/src/rgbds.7
@@ -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 ,