[PATCH 1/2] x86/APX: optimize certain reg-only CFCMOVcc forms

Jan Beulich jbeulich@suse.com
Fri Aug 30 10:40:52 GMT 2024


Along the lines of 2513312930b2 ("x86/APX: apply NDD-to-legacy
transformation to further CMOVcc forms") these can similarly be
converted to the shorter legacy-encoded CMOVcc.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -5052,6 +5052,41 @@ optimize_encoding (void)
 	  break;
 	}
     }
+  else if (optimize > 1
+	   && (i.tm.base_opcode | 0xf) == 0x4f
+	   && i.tm.opcode_space == SPACE_EVEXMAP4
+	   && i.reg_operands == 3
+	   && i.tm.opcode_modifier.operandconstraint == EVEX_NF
+	   && !i.types[0].bitfield.word)
+    {
+      /* Optimize: -O2:
+	   cfcmov<cc> %rM, %rN, %rN -> cmov<cc> %rM, %rN
+	   cfcmov<cc> %rM, %rN, %rM -> cmov<!cc> %rN, %rM
+	   cfcmov<cc> %rN, %rN, %rN -> nop %rN
+       */
+      if (i.op[0].regs == i.op[2].regs)
+	{
+	  i.tm.base_opcode ^= 1;
+	  i.op[0].regs = i.op[1].regs;
+	  i.op[1].regs = i.op[2].regs;
+	}
+      else if (i.op[1].regs != i.op[2].regs)
+	return;
+
+      i.tm.opcode_space = SPACE_0F;
+      i.tm.opcode_modifier.evex = 0;
+      i.tm.opcode_modifier.vexvvvv = 0;
+      i.tm.opcode_modifier.operandconstraint = 0;
+      i.reg_operands = 2;
+
+      /* While at it, convert to NOP if all three regs match.  */
+      if (i.op[0].regs == i.op[1].regs)
+	{
+	  i.tm.base_opcode = 0x1f;
+	  i.tm.extension_opcode = 0;
+	  i.reg_operands = 1;
+	}
+    }
   else if (i.reg_operands == 3
 	   && i.op[0].regs == i.op[1].regs
 	   && !i.types[2].bitfield.xmmword
--- a/gas/testsuite/gas/i386/x86-64-apx-ndd-optimize.d
+++ b/gas/testsuite/gas/i386/x86-64-apx-ndd-optimize.d
@@ -134,6 +134,16 @@ Disassembly of section .text:
 \s*[a-f0-9]+:\s*0f 4c d1             	cmovl  %ecx,%edx
 \s*[a-f0-9]+:\s*0f 4f d1             	cmovg  %ecx,%edx
 \s*[a-f0-9]+:\s*0f 4e d1             	cmovle %ecx,%edx
+\s*[a-f0-9]+:\s*0f 40 ca             	cmovo  %edx,%ecx
+\s*[a-f0-9]+:\s*0f 40 ca             	cmovo  %edx,%ecx
+\s*[a-f0-9]+:\s*49 0f 42 ca          	cmovb  %r10,%rcx
+\s*[a-f0-9]+:\s*49 0f 42 ca          	cmovb  %r10,%rcx
+\s*[a-f0-9]+:\s*44 0f 44 ca          	cmove  %edx,%r9d
+\s*[a-f0-9]+:\s*44 0f 44 ca          	cmove  %edx,%r9d
+\s*[a-f0-9]+:\s*d5 90 4a ca          	cmovp  %r18d,%ecx
+\s*[a-f0-9]+:\s*d5 90 4a ca          	cmovp  %r18d,%ecx
+\s*[a-f0-9]+:\s*d5 c8 4f ca          	cmovg  %rdx,%r17
+\s*[a-f0-9]+:\s*d5 c8 4f ca          	cmovg  %rdx,%r17
 \s*[a-f0-9]+:\s*62 f4 7d 08 60 c0    	movbe  %ax,%ax
 \s*[a-f0-9]+:\s*49 0f c8             	bswap  %r8
 \s*[a-f0-9]+:\s*d5 98 c8             	bswap  %r16
--- a/gas/testsuite/gas/i386/x86-64-apx-ndd-optimize.s
+++ b/gas/testsuite/gas/i386/x86-64-apx-ndd-optimize.s
@@ -128,6 +128,16 @@ cmovnge %edx,%ecx,%edx
 cmovnl %edx,%ecx,%edx
 cmovng %edx,%ecx,%edx
 cmovnle %edx,%ecx,%edx
+cfcmovo %edx,%ecx,%ecx
+cfcmovno %ecx,%edx,%ecx
+cfcmovc %r10,%rcx,%rcx
+cfcmovnc %rcx,%r10,%rcx
+cfcmove %edx,%r9d,%r9d
+cfcmovne %r9d,%edx,%r9d
+cfcmovp %r18d,%ecx,%ecx
+cfcmovnp %ecx,%r18d,%ecx
+cfcmovg %rdx,%r17,%r17
+cfcmovng %r17,%rdx,%r17
 movbe  %ax,%ax
 movbe  %r8,%r8
 movbe  %r16,%r16
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -992,7 +992,7 @@ ud0, 0xfff, i186, Modrm|CheckOperandSize
 cmov<cc>, 0x4<cc:opc>, CMOV&APX_F, C|Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|Optimize, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64 }
 cmov<cc>, 0xf4<cc:opc>, CMOV, Modrm|CheckOperandSize|No_bSuf|No_sSuf, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
 
-cfcmov<cc>, 0x4<cc:opc>, CMOV&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|EVexNF, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64 }
+cfcmov<cc>, 0x4<cc:opc>, CMOV&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|DstVVVV|EVexMap4|EVexNF|Optimize, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64, Reg16|Reg32|Reg64 }
 cfcmov<cc>, 0x4<cc:opc>, CMOV&APX_F, Load|Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
 cfcmov<cc>, 0x4<cc:opc>, CMOV&APX_F, Modrm|CheckOperandSize|No_bSuf|No_sSuf|EVexMap4|EVexNF, { Reg16|Reg32|Reg64, Reg16|Reg32|Reg64|Unspecified|BaseIndex }
 



More information about the Binutils mailing list