[avr,applied] PR34307: Fix illegal opcode diagnostic

Message ID 28e3d238-7b0c-4cf7-bc49-cf172810efea@gjlay.de
State New
Headers
Series [avr,applied] PR34307: Fix illegal opcode diagnostic |

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

Georg-Johann Lay June 21, 2026, 4:47 p.m. UTC
  When there is an AVR instruction in include/opcode/avr.h that is not 
supported by a specific core, then gas will diagnose with the mnemonic 
of the next instruction:

     mul 1,2
     mulsu 1,1
     lat

$ avr-as x.sx
x.sx: Assembler messages:
x.sx:1: Error: illegal opcode or for mcu avr2
x.sx:2: Error: illegal opcode fmul for mcu avr2
x.sx:3: Error: illegal opcode movw for mcu avr2

The reason is that in gas/config/tc-avr.c::md_assemble() we have this loop:

    while ((opcode->isa & avr_mcu->isa) != opcode->isa)
      {
        opcode++;

        if (opcode->name && strcmp(op, opcode->name))
          {
            as_bad (_("illegal opcode %s for mcu %s"),
                    opcode->name, avr_mcu->name);
            return;
          }
      }

which in the as_bad case prints the next instruction's mnemonic due to 
the opcode++ above.

Applied as obvious.

Johann

--

     AVR: PR34307 - Fix diagnostic for unknown ISA opcode

     When there is an AVR instruction in include/opcode/avr.h that
     is not supported by a specific MCU, then gas will diagnose
     with the mnemonic of the next instruction:

         mul 1,2
         mulsu 1,1
         lat

     $ avr-as x.sx
     x.sx: Assembler messages:
     x.sx:1: Error: illegal opcode or for mcu avr2
     x.sx:2: Error: illegal opcode fmul for mcu avr2
     x.sx:3: Error: illegal opcode movw for mcu avr2

     The reason is that in gas/config/tc-avr.c::md_assemble() we have:

        while ((opcode->isa & avr_mcu->isa) != opcode->isa)
          {
            opcode++;

            if (opcode->name && strcmp(op, opcode->name))
              {
                as_bad (_("illegal opcode %s for mcu %s"),
                        opcode->name, avr_mcu->name);
                return;
              }
          }

     which in the as_bad case prints the next instruction's mnemonic
     due to the opcode++ above.

     gas/
             * config/tc-avr.c (md_assemble): Use right index to diagnose
             an opcode that are not supported by the MCU.
             * testsuite/gas/avr/pr34307-1.d: New test.
             * testsuite/gas/avr/pr34307-1.s: New test source.
             * testsuite/gas/avr/pr34307-2.d: New test.
             * testsuite/gas/avr/pr34307-2.s: New test source.
  

Patch

    AVR: PR34307 - Fix diagnostic for unknown ISA opcode
    
    When there is an AVR instruction in include/opcode/avr.h that
    is not supported by a specific MCU, then gas will diagnose
    with the mnemonic of the next instruction:
    
        mul 1,2
        mulsu 1,1
        lat
    
    $ avr-as x.sx
    x.sx: Assembler messages:
    x.sx:1: Error: illegal opcode or for mcu avr2
    x.sx:2: Error: illegal opcode fmul for mcu avr2
    x.sx:3: Error: illegal opcode movw for mcu avr2
    
    The reason is that in gas/config/tc-avr.c::md_assemble() we have:
    
       while ((opcode->isa & avr_mcu->isa) != opcode->isa)
         {
           opcode++;
    
           if (opcode->name && strcmp(op, opcode->name))
             {
               as_bad (_("illegal opcode %s for mcu %s"),
                       opcode->name, avr_mcu->name);
               return;
             }
         }
    
    which in the as_bad case prints the next instruction's mnemonic
    due to the opcode++ above.
    
    gas/
            * config/tc-avr.c (md_assemble): Use right index to diagnose
            an opcode that are not supported by the MCU.
            * testsuite/gas/avr/pr34307-1.d: New test.
            * testsuite/gas/avr/pr34307-1.s: New test source.
            * testsuite/gas/avr/pr34307-2.d: New test.
            * testsuite/gas/avr/pr34307-2.s: New test source.

diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index 671df820ede..b66ff2d956a 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -1900,8 +1900,8 @@  md_assemble (char *str)
 
           if (opcode->name && strcmp(op, opcode->name))
             {
-              as_bad (_("illegal opcode %s for mcu %s"),
-                      opcode->name, avr_mcu->name);
+              as_bad (_("illegal opcode `%s' for mcu %s"),
+                      (opcode - 1)->name, avr_mcu->name);
               return;
             }
         }
diff --git a/gas/testsuite/gas/avr/pr34307-1.d b/gas/testsuite/gas/avr/pr34307-1.d
new file mode 100644
index 00000000000..1651d28c2dd
--- /dev/null
+++ b/gas/testsuite/gas/avr/pr34307-1.d
@@ -0,0 +1,4 @@ 
+#name: Unknown opcode DES diagnostic
+#as:
+#error: illegal opcode `des' for mcu
+#target: avr-*-*
diff --git a/gas/testsuite/gas/avr/pr34307-1.s b/gas/testsuite/gas/avr/pr34307-1.s
new file mode 100644
index 00000000000..80d9dcd2bbe
--- /dev/null
+++ b/gas/testsuite/gas/avr/pr34307-1.s
@@ -0,0 +1 @@ 
+    des
diff --git a/gas/testsuite/gas/avr/pr34307-2.d b/gas/testsuite/gas/avr/pr34307-2.d
new file mode 100644
index 00000000000..5c5df64db0b
--- /dev/null
+++ b/gas/testsuite/gas/avr/pr34307-2.d
@@ -0,0 +1,4 @@ 
+#name: Unknown opcode LAT diagnostic
+#as: -mmcu=avr4
+#error: illegal opcode `lat' for mcu
+#target: avr-*-*
diff --git a/gas/testsuite/gas/avr/pr34307-2.s b/gas/testsuite/gas/avr/pr34307-2.s
new file mode 100644
index 00000000000..ea364345738
--- /dev/null
+++ b/gas/testsuite/gas/avr/pr34307-2.s
@@ -0,0 +1 @@ 
+    lat 0,z