]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: optimize MOVSX between accumulator regs
authorJan Beulich <jbeulich@suse.com>
Fri, 9 Jan 2026 07:44:30 +0000 (08:44 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 9 Jan 2026 07:44:30 +0000 (08:44 +0100)
Except on the K6 CBW/CWDE/CDQE perform equally well, but are shorter to
encode.

gas/config/tc-i386.c
gas/testsuite/gas/i386/optimize-2.d
gas/testsuite/gas/i386/optimize-2.s
gas/testsuite/gas/i386/optimize-2b.d
gas/testsuite/gas/i386/x86-64-optimize-3.d
gas/testsuite/gas/i386/x86-64-optimize-3.s
gas/testsuite/gas/i386/x86-64-optimize-3b.d
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index 28b1f4192d8c928ec0f09ae8883ace788833c90c..c7b47eb7e245b80fbcb9216fdceb3c768a972dbd 100644 (file)
@@ -5174,6 +5174,36 @@ optimize_encoding (void)
       i.seg[0] = NULL;
     }
 
+  if (((i.tm.opcode_space == SPACE_0F
+        && (i.tm.base_opcode | 1) == 0xbf
+        && (i.types[0].bitfield.byte
+           ? i.types[1].bitfield.word
+           : i.types[1].bitfield.dword))
+       || (i.tm.opcode_space == SPACE_BASE
+          && i.tm.base_opcode == 0x63
+          && i.types[1].bitfield.qword))
+      && i.reg_operands == 2
+      && i.op[0].regs->reg_type.bitfield.instance == Accum
+      && i.op[1].regs->reg_type.bitfield.instance == Accum
+      && (cpu_arch_tune != PROCESSOR_K6 || optimize_for_space))
+    {
+      /* Optimize: -O:
+          movsb     %al, %ax    -> cbw
+          movsw     %ax, %eax   -> cwde
+          movsl     %eax, %rax  -> cdqe
+       */
+      i.tm.opcode_space = SPACE_BASE;
+      i.tm.base_opcode = 0x98;
+      i.tm.opcode_modifier.modrm = 0;
+      /* Leave the destination register in place for process_suffix() to take
+        care of operand sizing.  This will end up as short_form encoding,
+        with the register number being 0 (i.e. not altering the opcode).  */
+      i.reg_operands = 1;
+      i.op[0].regs = i.op[1].regs;
+      i.tm.operand_types[1].bitfield.class = ClassNone;
+      return;
+    }
+
   if (optimize_for_space
       && (i.tm.mnem_off == MN_test
           || (i.tm.base_opcode == 0xf6
index 89551d19978cc9f01149d7d2c5f66ba8dc58856e..b9a7b0b0f4a01f91eb64683f25037a9339378580 100644 (file)
@@ -24,6 +24,12 @@ Disassembly of section .text:
  +[a-f0-9]+:   09 f6                   or     %esi,%esi
  +[a-f0-9]+:   87 0a                   xchg   %ecx,\(%edx\)
  +[a-f0-9]+:   87 11                   xchg   %edx,\(%ecx\)
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
  +[a-f0-9]+:   d0 e2                   shl    \$1,%dl
  +[a-f0-9]+:   d0 e2                   shl    \$1,%dl
  +[a-f0-9]+:   66 d1 e2                shl    \$1,%dx
index 1ddaab05540c5efd45c8aa83d448b2ec97923785..375a95a467f24b2860e121c542b5d412ea8c9e5b 100644 (file)
@@ -22,6 +22,17 @@ _start:
        lock xchg %ecx, (%edx)
        lock xchg (%ecx), %edx
 
+       movsb   %al, %ax
+       movsbw  %al, %ax
+
+       movsw   %ax, %eax
+       movswl  %ax, %eax
+
+       .intel_syntax noprefix
+       movsx   ax, al
+       movsx   eax, ax
+       .att_syntax prefix
+
        shl     $1, %dl
        shl     %dl
 
index 3fe8945142ba57ee46c272abe39db957b801f807..9f5c4889e3f4c5ac4c95b2888fb30174e24ef3fc 100644 (file)
@@ -25,6 +25,12 @@ Disassembly of section .text:
  +[a-f0-9]+:   85 f6                   test   %esi,%esi
  +[a-f0-9]+:   87 0a                   xchg   %ecx,\(%edx\)
  +[a-f0-9]+:   87 11                   xchg   %edx,\(%ecx\)
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
  +[a-f0-9]+:   00 d2                   add    %dl,%dl
  +[a-f0-9]+:   00 d2                   add    %dl,%dl
  +[a-f0-9]+:   66 01 d2                add    %dx,%dx
index 51513c828e420641996d99b01cc8aa9b57c106f2..c91503aa8f919e0e41b5f675452f9871f6da21d8 100644 (file)
@@ -80,6 +80,16 @@ Disassembly of section .text:
  +[a-f0-9]+:   66 09 f6                or     %si,%si
  +[a-f0-9]+:   09 ff                   or     %edi,%edi
  +[a-f0-9]+:   4d 09 c0                or     %r8,%r8
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   48 98                   cltq
  +[a-f0-9]+:   c5 f1 55 e9             vandnpd %xmm1,%xmm1,%xmm5
  +[a-f0-9]+:   c5 f9 6f d1             vmovdqa %xmm1,%xmm2
  +[a-f0-9]+:   c5 f9 6f d1             vmovdqa %xmm1,%xmm2
index b2cf16d05ffa628ca197b493f97d9c2bcb97a435..4fd29aeec98aa69446a1b28ec48f7cba3e95873e 100644 (file)
@@ -39,6 +39,22 @@ _start:
        or      %edi, %edi
        or      %r8, %r8
 
+       movsb   %al, %ax
+       movsbw  %al, %ax
+
+       movsw   %ax, %eax
+       movswl  %ax, %eax
+
+       movsl   %eax, %rax
+       movslq  %eax, %rax
+       movsxd  %eax, %rax
+
+       .intel_syntax noprefix
+       movsx   ax, al
+       movsx   eax, ax
+       movsx   rax, eax
+       .att_syntax prefix
+
        vandnpd %zmm1, %zmm1, %zmm5
 
        vmovdqa32       %xmm1, %xmm2
index abfc8f917818cb8ff252afa40e15af3b80dab858..2a8fd3a0f41e0e05ebd5d4a54f647286b23efa72 100644 (file)
@@ -81,6 +81,16 @@ Disassembly of section .text:
  +[a-f0-9]+:   66 85 f6                test   %si,%si
  +[a-f0-9]+:   09 ff                   or     %edi,%edi
  +[a-f0-9]+:   4d 85 c0                test   %r8,%r8
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   48 98                   cltq
+ +[a-f0-9]+:   66 98                   cbtw
+ +[a-f0-9]+:   98                      cwtl
+ +[a-f0-9]+:   48 98                   cltq
  +[a-f0-9]+:   c5 f1 55 e9             vandnpd %xmm1,%xmm1,%xmm5
  +[a-f0-9]+:   c5 f9 6f d1             vmovdqa %xmm1,%xmm2
  +[a-f0-9]+:   c5 f9 6f d1             vmovdqa %xmm1,%xmm2
index 4d247b5c7f450f0924733a5774bb8abfd4a425d0..63f4f31c3016788e66abb1fa370dbde5de65fceb 100644 (file)
@@ -220,12 +220,12 @@ movbe, 0x60, Movbe&APX_F, D|Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4, { R
 bswap, 0xfc8, i486, No_bSuf|No_wSuf|No_sSuf, { Reg32|Reg64 }
 
 // Move with sign extend.
-movsb, 0xfbe, i386, Modrm|No_bSuf|No_sSuf, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-movsw, 0xfbf, i386, Modrm|No_bSuf|No_wSuf|No_sSuf, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
-movsl, 0x63, x64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf, { Reg32|Unspecified|BaseIndex, Reg64 }
-movsx, 0xfbe, i386, W|Modrm|No_lSuf|No_sSuf|No_qSuf, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-movsx, 0x63, x64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
-movsxd, 0x63, x64, Modrm|NoSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
+movsb, 0xfbe, i386, Modrm|No_bSuf|No_sSuf|Optimize, { Reg8|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+movsw, 0xfbf, i386, Modrm|No_bSuf|No_wSuf|No_sSuf|Optimize, { Reg16|Unspecified|BaseIndex, Reg32|Reg64 }
+movsl, 0x63, x64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|Optimize, { Reg32|Unspecified|BaseIndex, Reg64 }
+movsx, 0xfbe, i386, W|Modrm|No_lSuf|No_sSuf|No_qSuf|Optimize, { Reg8|Reg16|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+movsx, 0x63, x64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|Optimize, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
+movsxd, 0x63, x64, Modrm|NoSuf|Optimize, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 }
 movsxd, 0x63, x64, Amd64|Modrm|NoSuf, { Reg32|Unspecified|BaseIndex, Reg16 }
 movsxd, 0x63, x64, Intel64|Modrm|NoSuf, { Reg16|Unspecified|BaseIndex, Reg16 }
 
index 33dee8b02d0d34ad83296f32b910b2c0fc3a3c93..a97dd6487aad6b16f2bf9921ba4e56afdf48e40b 100644 (file)
@@ -214,7 +214,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsb, 0xbe, 2, SPACE_0F, None,
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
@@ -224,7 +224,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsw, 0xbf, 2, SPACE_0F, None,
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
@@ -234,7 +234,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsl, 0x63, 2, SPACE_BASE, None,
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
@@ -244,7 +244,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsx, 0xbe, 2, SPACE_0F, None,
     { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
@@ -254,7 +254,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsx, 0x63, 2, SPACE_BASE, None,
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
@@ -264,7 +264,7 @@ static const insn_template i386_optab[] =
          0, 0, 0, 0, 0, 0 } } } },
   { MN_movsxd, 0x63, 2, SPACE_BASE, None,
     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
       0, 0 },
     { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
     { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },