[v2] gas: m68k M680LC040 F-LINE NOP insertion fixing emulation of fpu instructions
Checks
Commit Message
On Sun, 30 Mar 2025 14:52:36 Nathanial Sloss wrote:
> Hi,
>
> The m68k m68lc040 (early revisions) have an issue after executing f-line
> (co processor mmu/fpu) instructions and executing a trap in the case of
> fpu emulation.
>
> Unfornately due to time passed the processor errata as to how to address
> the issue has been lost.
>
> Fortunately the issue was documented in a NetBSD PR:
>
> http://gnats.netbsd.org/13078
>
> Which proposes a solution to the problem which I have patched the GNU
> assembler for.
>
> As I have an affected machine with an lc040 processor I can confirm that
> all programmes compiled with the patched assember work as expected.
>
>
I've changed the patch so the nop insertion is not the default.
Now one has to pass -mlcfix to enable it.
> Best regards,
>
> Nat
Comments
On Apr 09 2025, Nathanial Sloss wrote:
> @@ -4272,8 +4273,24 @@
> }
> }
>
> + bool hasnop = false;
> + char nop[4] = "nop";
> + toP = NULL;
> +next:
> memset (&the_ins, '\0', sizeof (the_ins));
> +
> m68k_ip (str);
> +
> + if (lcfix == true && hasnop == false &&
Never compare a bool with a literal.
@@ -74,6 +74,7 @@
static int flag_short_refs; /* -l option. */
static int flag_long_jumps; /* -S option. */
static int flag_keep_pcrel; /* --pcrel option. */
+static bool lcfix = false;
#ifdef REGISTER_PREFIX_OPTIONAL
int flag_reg_prefix_optional = REGISTER_PREFIX_OPTIONAL;
@@ -4272,8 +4273,24 @@
}
}
+ bool hasnop = false;
+ char nop[4] = "nop";
+ toP = NULL;
+next:
memset (&the_ins, '\0', sizeof (the_ins));
+
m68k_ip (str);
+
+ if (lcfix == true && hasnop == false &&
+ (the_ins.opcode[0] & 0xf000) == 0xf000)
+ {
+ memset (&the_ins, '\0', sizeof (the_ins));
+ m68k_ip (nop);
+ hasnop = true;
+ }
+ else
+ hasnop = false;
+
er = the_ins.error;
if (!er)
{
@@ -4349,6 +4366,8 @@
if (the_ins.reloc[m].wid == 'B')
fixP->fx_signed = 1;
}
+ if (hasnop == true)
+ goto next;
return;
}
@@ -4447,6 +4466,8 @@
the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
}
+ if (hasnop == true)
+ goto next;
}
/* Comparison function used by qsort to rank the opcode entries by name. */
@@ -7455,6 +7476,8 @@
;
else if (m68k_set_cpu (arg, 0, 1))
;
+ else if (startswith (arg, "lcfix"))
+ lcfix = true;
else
return 0;
break;
@@ -7556,6 +7579,7 @@
fprintf (stream, _("\
-march=<arch> set architecture\n\
-mcpu=<cpu> set cpu [default %s]\n\
+-mlcfix compatability with lc040 nop before f-line\n\
"), default_cpu);
for (i = 0; m68k_extensions[i].name; i++)
fprintf (stream, _("\