[v2] gas: m68k M680LC040 F-LINE NOP insertion fixing emulation of fpu instructions

Message ID 202504091033.38311.nat@netbsd.org
State New
Headers
Series [v2] gas: m68k M680LC040 F-LINE NOP insertion fixing emulation of fpu instructions |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Nathanial Sloss April 9, 2025, 12:33 a.m. UTC
  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

Andreas Schwab April 9, 2025, 8:44 a.m. UTC | #1
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.
  

Patch

--- a/external/gpl3/binutils/dist/gas/config/tc-m68k.c	Sun Dec 01 20:36:00 2024 +0000
+++ b/external/gpl3/binutils/dist/gas/config/tc-m68k.c	Mon Dec 02 19:03:37 2024 +1100
@@ -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, _("\