public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: "binutils@sourceware.org" <binutils@sourceware.org>
Cc: "H.J. Lu" <hjl.tools@gmail.com>
Subject: [PATCH 2/6] x86-64: Intel64 adjustments for conditional jumps
Date: Fri, 06 Mar 2020 08:12:00 -0000	[thread overview]
Message-ID: <da820d1f-252e-0984-04ad-fc4cf135f12d@suse.com> (raw)
In-Reply-To: <17ee93b3-33ea-5c10-23b2-408c7fb5b5a2@suse.com>

Just like for unconditional direct JMP, AMD and Intel differ in their
handling. Mirror JMP handling to Jcc.

gas/
2020-03-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/x86-64-branch-2.s,
	testsuite/gas/i386/x86-64-branch-3.s: Add Jcc cases.
	* testsuite/gas/i386/ilp32/x86-64-branch.d,
	testsuite/gas/i386/opcode-suffix.d,
	testsuite/gas/i386/x86-64-branch-2.d,
	testsuite/gas/i386/x86-64-branch-3.d,
	testsuite/gas/i386/x86-64-branch.d: Adjust expectations.

opcodes/
2020-03-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-dis.c (safe-ctype.h): Include.
	(X86_64_0F8x): New enumerator.
	(dis386): Extend comment ahead of it.
	(dis386_twobyte): Vector Jcc to X86_64_0F8x.
	(condition_code): New.
	(x86_64_table): Add X86_64_0F8x entry.
	(print_insn): Set condition_code. Move advancing of codep after
	it.
	(putop): Handle two-char escape case for 'C'. Handle 'C' prefix
	case for 'P' and '@'.
	* i386-opc.tbl (j<cc>): Split into AMD64 and Intel64 variants.
	* i386-tbl.h: Re-generate.
---
I wonder if the suffix handling done here wouldn't also be the more
suitable one for JMP and CALL. In particular the 'q' suffix printed
unconditionally in 64-bit mode is more of a problem than helpful imo.

--- a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d
@@ -22,7 +22,7 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   0x24	20: R_X86_64_PC32	\*ABS\*\+0x10003c
 [ 	]*[a-f0-9]+:	66 e8 00 00 00 00    	data16 callq 0x2a	26: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	66 e9 00 00 00 00    	data16 jmpq 0x30	2c: R_X86_64_PLT32	foo-0x4
-[ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jb 0x37	33: R_X86_64_PLT32	foo-0x4
+[ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jbq 0x37	33: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	66 c3                	data16 retq *
 [ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
--- a/gas/testsuite/gas/i386/opcode-suffix.d
+++ b/gas/testsuite/gas/i386/opcode-suffix.d
@@ -305,22 +305,22 @@ Disassembly of section .text:
  *[0-9a-f]+:	0f 77[ 	]+emms[ 	]+
  *[0-9a-f]+:	0f 7e 90 90 90 90 90[ 	]+movd[ 	]+%mm2,-0x6f6f6f70\(%eax\)
  *[0-9a-f]+:	0f 7f 90 90 90 90 90[ 	]+movq[ 	]+%mm2,-0x6f6f6f70\(%eax\)
- *[0-9a-f]+:	0f 80 90 90 90 90[ 	]+jo[ 	]+909094e2 <foo\+0x909094e2>
- *[0-9a-f]+:	0f 81 90 90 90 90[ 	]+jno[ 	]+909094e8 <foo\+0x909094e8>
- *[0-9a-f]+:	0f 82 90 90 90 90[ 	]+jb[ 	]+909094ee <foo\+0x909094ee>
- *[0-9a-f]+:	0f 83 90 90 90 90[ 	]+jae[ 	]+909094f4 <foo\+0x909094f4>
- *[0-9a-f]+:	0f 84 90 90 90 90[ 	]+je[ 	]+909094fa <foo\+0x909094fa>
- *[0-9a-f]+:	0f 85 90 90 90 90[ 	]+jne[ 	]+90909500 <foo\+0x90909500>
- *[0-9a-f]+:	0f 86 90 90 90 90[ 	]+jbe[ 	]+90909506 <foo\+0x90909506>
- *[0-9a-f]+:	0f 87 90 90 90 90[ 	]+ja[ 	]+9090950c <foo\+0x9090950c>
- *[0-9a-f]+:	0f 88 90 90 90 90[ 	]+js[ 	]+90909512 <foo\+0x90909512>
- *[0-9a-f]+:	0f 89 90 90 90 90[ 	]+jns[ 	]+90909518 <foo\+0x90909518>
- *[0-9a-f]+:	0f 8a 90 90 90 90[ 	]+jp[ 	]+9090951e <foo\+0x9090951e>
- *[0-9a-f]+:	0f 8b 90 90 90 90[ 	]+jnp[ 	]+90909524 <foo\+0x90909524>
- *[0-9a-f]+:	0f 8c 90 90 90 90[ 	]+jl[ 	]+9090952a <foo\+0x9090952a>
- *[0-9a-f]+:	0f 8d 90 90 90 90[ 	]+jge[ 	]+90909530 <foo\+0x90909530>
- *[0-9a-f]+:	0f 8e 90 90 90 90[ 	]+jle[ 	]+90909536 <foo\+0x90909536>
- *[0-9a-f]+:	0f 8f 90 90 90 90[ 	]+jg[ 	]+9090953c <foo\+0x9090953c>
+ *[0-9a-f]+:	0f 80 90 90 90 90[ 	]+jol[ 	]+909094e2 <foo\+0x909094e2>
+ *[0-9a-f]+:	0f 81 90 90 90 90[ 	]+jnol[ 	]+909094e8 <foo\+0x909094e8>
+ *[0-9a-f]+:	0f 82 90 90 90 90[ 	]+jbl[ 	]+909094ee <foo\+0x909094ee>
+ *[0-9a-f]+:	0f 83 90 90 90 90[ 	]+jael[ 	]+909094f4 <foo\+0x909094f4>
+ *[0-9a-f]+:	0f 84 90 90 90 90[ 	]+jel[ 	]+909094fa <foo\+0x909094fa>
+ *[0-9a-f]+:	0f 85 90 90 90 90[ 	]+jnel[ 	]+90909500 <foo\+0x90909500>
+ *[0-9a-f]+:	0f 86 90 90 90 90[ 	]+jbel[ 	]+90909506 <foo\+0x90909506>
+ *[0-9a-f]+:	0f 87 90 90 90 90[ 	]+jal[ 	]+9090950c <foo\+0x9090950c>
+ *[0-9a-f]+:	0f 88 90 90 90 90[ 	]+jsl[ 	]+90909512 <foo\+0x90909512>
+ *[0-9a-f]+:	0f 89 90 90 90 90[ 	]+jnsl[ 	]+90909518 <foo\+0x90909518>
+ *[0-9a-f]+:	0f 8a 90 90 90 90[ 	]+jpl[ 	]+9090951e <foo\+0x9090951e>
+ *[0-9a-f]+:	0f 8b 90 90 90 90[ 	]+jnpl[ 	]+90909524 <foo\+0x90909524>
+ *[0-9a-f]+:	0f 8c 90 90 90 90[ 	]+jll[ 	]+9090952a <foo\+0x9090952a>
+ *[0-9a-f]+:	0f 8d 90 90 90 90[ 	]+jgel[ 	]+90909530 <foo\+0x90909530>
+ *[0-9a-f]+:	0f 8e 90 90 90 90[ 	]+jlel[ 	]+90909536 <foo\+0x90909536>
+ *[0-9a-f]+:	0f 8f 90 90 90 90[ 	]+jgl[ 	]+9090953c <foo\+0x9090953c>
  *[0-9a-f]+:	0f 90 80 90 90 90 90[ 	]+seto[ 	]+-0x6f6f6f70\(%eax\)
  *[0-9a-f]+:	0f 91 80 90 90 90 90[ 	]+setno[ 	]+-0x6f6f6f70\(%eax\)
  *[0-9a-f]+:	0f 92 80 90 90 90 90[ 	]+setb[ 	]+-0x6f6f6f70\(%eax\)
--- a/gas/testsuite/gas/i386/x86-64-branch-2.d
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.d
@@ -16,4 +16,6 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 48 e8 00 00 00 00 	data16 callq 18 <bar\+0xd>	14: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	66 c3                	retw *
 [ 	]*[a-f0-9]+:	66 c2 08 00          	retw   \$0x8
+[ 	]*[a-f0-9]+:	66 0f 84 00 00       	jew    23 <bar\+0x18>	21: R_X86_64_PC16	foo-0x2
+[ 	]*[a-f0-9]+:	66 48 0f 85 00 00 00 00 	data16 jneq 2b <bar\+0x20>	27: R_X86_64_PLT32	foo-0x4
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch-2.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.s
@@ -10,3 +10,6 @@ bar:
 
 	retw
 	retw $8
+
+	data16 je foo
+	data16 rex.w jne foo
--- a/gas/testsuite/gas/i386/x86-64-branch-3.d
+++ b/gas/testsuite/gas/i386/x86-64-branch-3.d
@@ -18,4 +18,6 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 48 c7 f8 00 00 00 00 	data16 xbeginq 29 <bar\+0x1c>	25: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	48 ff 18             	lcallq \*\(%rax\)
 [ 	]*[a-f0-9]+:	48 ff 29             	ljmpq  \*\(%rcx\)
+[ 	]*[a-f0-9]+:	66 0f 84 00 00 00 00 	data16 jeq 36 <bar\+0x29>	32: R_X86_64_PLT32	foo-0x4
+[ 	]*[a-f0-9]+:	66 48 0f 85 00 00 00 00 	data16 rex\.W jneq 3e <bar\+0x31>	3a: R_X86_64_PLT32	foo-0x4
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch-3.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-3.s
@@ -13,3 +13,6 @@ bar:
 
 	lcallq *(%rax)
 	ljmpq *(%rcx)
+
+	data16 je foo
+	data16 rex.w jne foo
--- a/gas/testsuite/gas/i386/x86-64-branch.d
+++ b/gas/testsuite/gas/i386/x86-64-branch.d
@@ -21,7 +21,7 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	e9 (00|60) 00 (00|10) 00       	jmpq   (0x24|100084 <.text\+0x100084>)
 [ 	]*[a-f0-9]+:	66 e8 00 00 00 00    	data16 callq (0x2a|2a <.text\+0x2a>)
 [ 	]*[a-f0-9]+:	66 e9 00 00 00 00    	data16 jmpq (0x30|30 <.text\+0x30>)
-[ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jb (0x37|37 <.text\+0x37>)
+[ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jbq (0x37|37 <.text\+0x37>)
 [ 	]*[a-f0-9]+:	66 c3                	data16 retq *
 [ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -37,6 +37,7 @@
 #include "opintl.h"
 #include "opcode/i386.h"
 #include "libiberty.h"
+#include "safe-ctype.h"
 
 #include <setjmp.h>
 
@@ -1771,7 +1772,8 @@ enum
   X86_64_0F01_REG_0,
   X86_64_0F01_REG_1,
   X86_64_0F01_REG_2,
-  X86_64_0F01_REG_3
+  X86_64_0F01_REG_3,
+  X86_64_0F8x,
 };
 
 enum
@@ -2341,6 +2343,10 @@ struct dis386 {
 	  otherwise
 
    2 upper case letter macros:
+   "CP" => print condition encoding and continue like P if there's any form
+           of size override present, or if suffix_always is true
+   "C@" => print condition encoding and continue like @ if there's any form
+           of size override present, or if suffix_always is true
    "XY" => print 'x' or 'y' if suffix_always is true or no register
 	   operands and no broadcast.
    "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
@@ -2799,23 +2805,23 @@ static const struct dis386 dis386_twobyt
   { PREFIX_TABLE (PREFIX_0F7E) },
   { PREFIX_TABLE (PREFIX_0F7F) },
   /* 80 */
-  { "joH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jnoH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jbH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jaeH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jeH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jneH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jbeH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jaH",		{ Jv, BND, cond_jump_flag }, 0 },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
   /* 88 */
-  { "jsH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jnsH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jpH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jnpH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jlH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jgeH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jleH",		{ Jv, BND, cond_jump_flag }, 0 },
-  { "jgH",		{ Jv, BND, cond_jump_flag }, 0 },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
+  { X86_64_TABLE (X86_64_0F8x) },
   /* 90 */
   { "seto",		{ Eb }, 0 },
   { "setno",		{ Eb }, 0 },
@@ -3021,6 +3027,7 @@ static struct
   }
 modrm;
 static unsigned char need_modrm;
+static unsigned char condition_code;
 static struct
   {
     int scale;
@@ -6984,6 +6991,12 @@ static const struct dis386 x86_64_table[
     { "lidt{Q|Q}", { M }, 0 },
     { "lidt", { M }, 0 },
   },
+
+  /* X86_64_0F8x */
+  {
+    { "j%CPH", { Jv, BND, cond_jump_flag }, 0 },
+    { "j%C@H", { Jv, BND, cond_jump_flag }, 0 },
+  },
 };
 
 static const struct dis386 three_byte_table[][256] = {
@@ -12097,15 +12110,16 @@ print_insn (bfd_vma pc, disassemble_info
       threebyte = *codep;
       dp = &dis386_twobyte[threebyte];
       need_modrm = twobyte_has_modrm[*codep];
-      codep++;
     }
   else
     {
       dp = &dis386[*codep];
       need_modrm = onebyte_has_modrm[*codep];
-      codep++;
     }
 
+  condition_code = *codep & 0xf;
+  codep++;
+
   /* Save sizeflag for printing the extra prefixes later before updating
      it for mnemonic and operand processing.  The prefix names depend
      only on the address mode.  */
@@ -12828,6 +12842,11 @@ putop (const char *in_template, int size
 	    }
 	  break;
 	case 'C':
+	  if (l != 0 || len != 1)
+	    {
+	      SAVE_LAST (*p);
+	      break;
+	    }
 	  if (intel_syntax && !alt)
 	    break;
 	  if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
@@ -13043,14 +13062,22 @@ putop (const char *in_template, int size
 		    }
 		}
 	    }
-	  else
+	  else if (l != 1 || len != 2)
+	    {
+	      SAVE_LAST (*p);
+	    }
+	  else if (last[0] == 'C')
+	    {
+	      for (p = dis386[0x70 | condition_code].name + 1;
+		   ISLOWER(*p); ++p)
+		*obufp++ = *p;
+	      if ((sizeflag & SUFFIX_ALWAYS)
+		  || (prefixes & PREFIX_DATA)
+		  || (rex & REX_W))
+		goto case_P;
+	    }
+	  else if (last[0] == 'L')
 	    {
-	      if (l != 1 || len != 2 || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
-
 	      if ((prefixes & PREFIX_DATA)
 		  || (rex & REX_W)
 		  || (sizeflag & SUFFIX_ALWAYS))
@@ -13068,6 +13095,8 @@ putop (const char *in_template, int size
 		    }
 		}
 	    }
+	  else
+	    SAVE_LAST (*p);
 	  break;
 	case 'U':
 	  if (intel_syntax)
@@ -13321,6 +13350,16 @@ putop (const char *in_template, int size
 	    }
 	  break;
 	case '@':
+	  if (l == 1 && last[0] == 'C')
+	    {
+	      for (p = dis386[0x70 | condition_code].name + 1;
+		   ISLOWER(*p); ++p)
+		*obufp++ = *p;
+	      if (!((sizeflag & SUFFIX_ALWAYS))
+		  && !(prefixes & PREFIX_DATA)
+		  && !(rex & REX_W))
+		break;
+	    }
 	  if (intel_syntax)
 	    break;
 	  if (address_mode == mode_64bit
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -424,7 +424,8 @@ leave, 0, 0xc9, None, 1, Cpu64, DefaultS
          s:8, ns:9, p:a, pe:a, np:b, po:b, l:c, nge:c, nl:d, ge:d, le:e, ng:e, nle:f, g:f>
 
 // Conditional jumps.
-j<cc>, 1, 0x7<cc:opc>, None, 1, 0, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32|Disp32S }
+j<cc>, 1, 0x7<cc:opc>, None, 1, 0, Amd64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32|Disp32S }
+j<cc>, 1, 0x7<cc:opc>, None, 1, Cpu64, Intel64|Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
 
 // jcxz vs. jecxz is chosen on the basis of the address size prefix.
 jcxz, 1, 0xe3, None, 1, CpuNo64, JumpByte|Size16|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Disp8 }

  parent reply	other threads:[~2020-03-06  8:12 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06  8:09 [PATCH 0/6] x86: introduce "templated" insn templates Jan Beulich
2020-03-06  8:11 ` [PATCH 1/6] x86: allow opcode templates to be templated Jan Beulich
2020-03-06 14:42   ` H.J. Lu
2020-03-06 14:51     ` Jan Beulich
2020-03-06 15:38       ` H.J. Lu
2020-03-09  9:19     ` Jan Beulich
2020-03-09 12:15       ` H.J. Lu
2020-03-06  8:12 ` [PATCH 3/6] x86: use template for SSE floating point comparison insns Jan Beulich
2020-03-06 14:43   ` H.J. Lu
2020-03-06  8:12 ` Jan Beulich [this message]
2020-03-06 14:40   ` [PATCH 2/6] x86-64: Intel64 adjustments for conditional jumps H.J. Lu
2020-03-06 14:54     ` Jan Beulich
2020-03-06 15:35       ` H.J. Lu
2020-03-09  7:11         ` Jan Beulich
2020-03-09 12:13           ` H.J. Lu
2020-03-11  8:59             ` Jan Beulich
2020-03-11 10:32               ` H.J. Lu
2020-04-24  6:36             ` Jan Beulich
2020-04-24 12:58               ` H.J. Lu
2020-03-06  8:13 ` [PATCH 4/6] x86: use template for AVX/AVX512 floating point comparison insns Jan Beulich
2020-03-06 14:45   ` H.J. Lu
2020-03-06 14:57     ` Jan Beulich
2020-03-06 15:32       ` H.J. Lu
2020-03-06  8:13 ` [PATCH 5/6] x86: use template for XOP integer comparison, shift, and rotate insns Jan Beulich
2020-03-06 14:46   ` H.J. Lu
2020-03-06  8:14 ` [PATCH 6/6] x86: use template for AVX512 integer comparison insns Jan Beulich
2020-03-06 14:46   ` H.J. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=da820d1f-252e-0984-04ad-fc4cf135f12d@suse.com \
    --to=jbeulich@suse.com \
    --cc=binutils@sourceware.org \
    --cc=hjl.tools@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).