+2020-01-21  Jan Beulich  <jbeulich@suse.com>
+
+       * config/tc-i386.c (process_suffix): Merge CRC32 handling into
+       generic code path. Deal with No_lSuf being set in a template.
+       * testsuite/gas/i386/inval-crc32.l,
+       testsuite/gas/i386/x86-64-inval-crc32.l: Expect warning(s)
+       instead of error(s) when operand size is ambiguous.
+       * testsuite/gas/i386/noreg16.s, testsuite/gas/i386/noreg32.s,
+       testsuite/gas/i386/noreg64.s: Add CRC32 tests.
+       * testsuite/gas/i386/noreg16.d, testsuite/gas/i386/noreg16.l,
+       testsuite/gas/i386/noreg32.d, testsuite/gas/i386/noreg32.l,
+       testsuite/gas/i386/noreg64.d, testsuite/gas/i386/noreg64.l:
+       Adjust expectations.
+
 2020-01-21  Jan Beulich  <jbeulich@suse.com>
 
        * config/tc-i386.c (process_suffix): Drop SYSRET special case
 
             Destination register type is more significant than source
             register type.  crc32 in SSE4.2 prefers source register
             type. */
-         if (i.tm.base_opcode == 0xf20f38f0
-             && i.types[0].bitfield.class == Reg)
-           {
-             if (i.types[0].bitfield.byte)
-               i.suffix = BYTE_MNEM_SUFFIX;
-             else if (i.types[0].bitfield.word)
-               i.suffix = WORD_MNEM_SUFFIX;
-             else if (i.types[0].bitfield.dword)
-               i.suffix = LONG_MNEM_SUFFIX;
-             else if (i.types[0].bitfield.qword)
-               i.suffix = QWORD_MNEM_SUFFIX;
-           }
-
-         if (!i.suffix)
-           {
-             int op;
+         unsigned int op = i.tm.base_opcode != 0xf20f38f0 ? i.operands : 1;
 
-             if (i.tm.base_opcode == 0xf20f38f0)
-               {
-                 /* We have to know the operand size for crc32.  */
-                 as_bad (_("ambiguous memory operand size for `%s`"),
-                         i.tm.name);
-                 return 0;
-               }
-
-             for (op = i.operands; --op >= 0;)
-               if (i.tm.operand_types[op].bitfield.instance == InstanceNone
-                   || i.tm.operand_types[op].bitfield.instance == Accum)
-                 {
-                   if (i.types[op].bitfield.class != Reg)
-                     continue;
-                   if (i.types[op].bitfield.byte)
-                     i.suffix = BYTE_MNEM_SUFFIX;
-                   else if (i.types[op].bitfield.word)
-                     i.suffix = WORD_MNEM_SUFFIX;
-                   else if (i.types[op].bitfield.dword)
-                     i.suffix = LONG_MNEM_SUFFIX;
-                   else if (i.types[op].bitfield.qword)
-                     i.suffix = QWORD_MNEM_SUFFIX;
-                   else
-                     continue;
-                   break;
-                 }
-           }
+         while (op--)
+           if (i.tm.operand_types[op].bitfield.instance == InstanceNone
+               || i.tm.operand_types[op].bitfield.instance == Accum)
+             {
+               if (i.types[op].bitfield.class != Reg)
+                 continue;
+               if (i.types[op].bitfield.byte)
+                 i.suffix = BYTE_MNEM_SUFFIX;
+               else if (i.types[op].bitfield.word)
+                 i.suffix = WORD_MNEM_SUFFIX;
+               else if (i.types[op].bitfield.dword)
+                 i.suffix = LONG_MNEM_SUFFIX;
+               else if (i.types[op].bitfield.qword)
+                 i.suffix = QWORD_MNEM_SUFFIX;
+               else
+                 continue;
+               break;
+             }
        }
       else if (i.suffix == BYTE_MNEM_SUFFIX)
        {
            i.suffix = SHORT_MNEM_SUFFIX;
          else if (flag_code == CODE_16BIT)
            i.suffix = WORD_MNEM_SUFFIX;
-         else
+         else if (!i.tm.opcode_modifier.no_lsuf)
            i.suffix = LONG_MNEM_SUFFIX;
+         else
+           i.suffix = QWORD_MNEM_SUFFIX;
        }
     }
 
 
 .*:7: Error: .*
 .*:8: Error: .*
 .*:9: Error: .*
-.*:10: Error: .*
+.*:10: Warning: .*
 .*:11: Error: .*
 .*:12: Error: .*
 .*:13: Error: .*
 [      ]*7[    ]+crc32w \(%esi\), %ax
 [      ]*8[    ]+crc32 \(%esi\), %al
 [      ]*9[    ]+crc32 \(%esi\), %ax
-[      ]*10[   ]+crc32 \(%esi\), %eax
+[      ]*10[   ]+\?\?\?\? F20F38F1[    ]+crc32 \(%esi\), %eax
+\*\*\*\*  Warning: .* `crc32'
+[      ]*10[   ]+06
 [      ]*11[   ]+crc32  %al, %al
 [      ]*12[   ]+crc32b  %al, %al
 [      ]*13[   ]+crc32  %ax, %ax
 
  *[a-f0-9]+:   81 3f 34 12             cmpw   \$0x1234,\(%bx\)
  *[a-f0-9]+:   a7                      cmpsw  %es:\(%di\),%ds:\(%si\)
  *[a-f0-9]+:   67 a7                   cmpsw  %es:\(%edi\),%ds:\(%esi\)
+ *[a-f0-9]+:   f2 0f 38 f1 07          crc32w \(%bx\),%eax
  *[a-f0-9]+:   f2 0f 2a 07             cvtsi2sdl \(%bx\),%xmm0
  *[a-f0-9]+:   f3 0f 2a 07             cvtsi2ssl \(%bx\),%xmm0
  *[a-f0-9]+:   ff 0f                   decw   \(%bx\)
 
 .*:[1-9][0-9]*: Warning: .* `cmp'
 .*:[1-9][0-9]*: Warning: .* `cmps'
 .*:[1-9][0-9]*: Warning: .* `cmps'
+.*:[1-9][0-9]*: Warning: .* `crc32'
 .*:[1-9][0-9]*: Warning: .* `dec'
 .*:[1-9][0-9]*: Warning: .* `div'
 .*:[1-9][0-9]*: Warning: .* `fadd'
 
        cmp     $0x1234, (%bx)
        cmps
        cmps    %es:(%edi), (%esi)
+       crc32   (%bx), %eax
        cvtsi2sd (%bx), %xmm0
        cvtsi2ss (%bx), %xmm0
        dec     (%bx)
 
  *[a-f0-9]+:   81 38 78 56 34 12       cmpl   \$0x12345678,\(%eax\)
  *[a-f0-9]+:   a7                      cmpsl  %es:\(%edi\),%ds:\(%esi\)
  *[a-f0-9]+:   a7                      cmpsl  %es:\(%edi\),%ds:\(%esi\)
+ *[a-f0-9]+:   f2 0f 38 f1 00          crc32l \(%eax\),%eax
  *[a-f0-9]+:   f2 0f 2a 00             cvtsi2sdl \(%eax\),%xmm0
  *[a-f0-9]+:   f3 0f 2a 00             cvtsi2ssl \(%eax\),%xmm0
  *[a-f0-9]+:   ff 08                   decl   \(%eax\)
 
 .*:[1-9][0-9]*: Warning: .* `cmp'
 .*:[1-9][0-9]*: Warning: .* `cmps'
 .*:[1-9][0-9]*: Warning: .* `cmps'
+.*:[1-9][0-9]*: Warning: .* `crc32'
 .*:[1-9][0-9]*: Warning: .* `dec'
 .*:[1-9][0-9]*: Warning: .* `div'
 .*:[1-9][0-9]*: Warning: .* `fadd'
 
        cmp     $0x12345678, (%eax)
        cmps
        cmps    %es:(%edi), (%esi)
+       crc32   (%eax), %eax
        cvtsi2sd (%eax), %xmm0
        cvtsi2ss (%eax), %xmm0
        dec     (%eax)
 
  *[a-f0-9]+:   81 38 78 56 34 12       cmpl   \$0x12345678,\(%rax\)
  *[a-f0-9]+:   a7                      cmpsl  %es:\(%rdi\),%ds:\(%rsi\)
  *[a-f0-9]+:   a7                      cmpsl  %es:\(%rdi\),%ds:\(%rsi\)
+ *[a-f0-9]+:   f2 0f 38 f1 00          crc32l \(%rax\),%eax
+ *[a-f0-9]+:   f2 48 0f 38 f1 00       crc32q \(%rax\),%rax
  *[a-f0-9]+:   f2 0f 2a 00             cvtsi2sdl \(%rax\),%xmm0
  *[a-f0-9]+:   f3 0f 2a 00             cvtsi2ssl \(%rax\),%xmm0
  *[a-f0-9]+:   ff 08                   decl   \(%rax\)
 
 .*:[1-9][0-9]*: Warning: .* `cmp'
 .*:[1-9][0-9]*: Warning: .* `cmps'
 .*:[1-9][0-9]*: Warning: .* `cmps'
+.*:[1-9][0-9]*: Warning: .* `crc32'
+.*:[1-9][0-9]*: Warning: .* `crc32'
 .*:[1-9][0-9]*: Warning: .* `cvtsi2sd'
 .*:[1-9][0-9]*: Warning: .* `cvtsi2ss'
 .*:[1-9][0-9]*: Warning: .* `dec'
 
        cmp     $0x12345678, (%rax)
        cmps
        cmps    %es:(%rdi), (%rsi)
+       crc32   (%rax), %eax
+       crc32   (%rax), %rax
        cvtsi2sd (%rax), %xmm0
        cvtsi2ss (%rax), %xmm0
        dec     (%rax)
 
 .*:7: Error: .*
 .*:8: Error: .*
 .*:9: Error: .*
-.*:10: Error: .*
-.*:11: Error: .*
+.*:10: Warning: .*
+.*:11: Warning: .*
 .*:12: Error: .*
 .*:13: Error: .*
 .*:14: Error: .*
 [      ]*7[    ]+crc32w \(%rsi\), %ax
 [      ]*8[    ]+crc32 \(%rsi\), %al
 [      ]*9[    ]+crc32 \(%rsi\), %ax
-[      ]*10[   ]+crc32 \(%rsi\), %eax
-[      ]*11[   ]+crc32 \(%rsi\), %rax
+[      ]*10[   ]+\?\?\?\? F20F38F1[    ]+crc32 \(%rsi\), %eax
+\*\*\*\*  Warning: .* `crc32'
+[      ]*10[   ]+06
+[      ]*11[   ]+\?\?\?\? F2480F38[    ]+crc32 \(%rsi\), %rax
+\*\*\*\*  Warning: .* `crc32'
+[      ]*11[   ]+F106
 [      ]*12[   ]+crc32  %al, %al
 [      ]*13[   ]+crc32b  %al, %al
 [      ]*14[   ]+crc32  %ax, %ax