Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Sep 2017 19:04:08 +0000 (UTC)
From:      Ryan Libby <rlibby@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323192 - head/contrib/binutils/opcodes
Message-ID:  <201709051904.v85J48P2013715@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rlibby
Date: Tue Sep  5 19:04:07 2017
New Revision: 323192
URL: https://svnweb.freebsd.org/changeset/base/323192

Log:
  gnu binutils: FSGSBASE assembly/disassembly
  
  Enable the in-tree binutils to assemble and disassemble amd64 FSGSBASE
  instructions (rdfsbase, rdgsbase, wrfsbase, wrgsbase), used in the base
  system since r322763.
  
  This gives one last gasp for in-tree gcc, and provides a small
  enhancement for in-tree binutils objdump.
  
  Reviewed by:	dim, kib
  Approved by:	markj (mentor)
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D12222

Modified:
  head/contrib/binutils/opcodes/i386-dis.c
  head/contrib/binutils/opcodes/i386-opc.h
  head/contrib/binutils/opcodes/i386-opc.tbl
  head/contrib/binutils/opcodes/i386-tbl.h

Modified: head/contrib/binutils/opcodes/i386-dis.c
==============================================================================
--- head/contrib/binutils/opcodes/i386-dis.c	Tue Sep  5 18:13:11 2017	(r323191)
+++ head/contrib/binutils/opcodes/i386-dis.c	Tue Sep  5 19:04:07 2017	(r323192)
@@ -1302,7 +1302,7 @@ static const unsigned char twobyte_uses_REPZ_prefix[25
   /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
   /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
   /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
-  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* af */
   /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
   /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
   /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
@@ -1793,10 +1793,10 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP15 */
   {
-    { "fxsave",		{ Ev } },
-    { "fxrstor",	{ Ev } },
-    { "ldmxcsr",	{ Ev } },
-    { "stmxcsr",	{ Ev } },
+    { "fxsave",		{ { OP_0fae, v_mode } } },
+    { "fxrstor",	{ { OP_0fae, v_mode } } },
+    { "ldmxcsr",	{ { OP_0fae, v_mode } } },
+    { "stmxcsr",	{ { OP_0fae, v_mode } } },
     { "xsave",		{ Ev } },
     { "xrstor",		{ { OP_0fae, v_mode } } },
     { "xsaveopt",	{ { OP_0fae, v_mode } } },
@@ -5997,19 +5997,34 @@ OP_0fae (int bytemode, int sizeflag)
 {
   if (modrm.mod == 3)
     {
-      if (modrm.reg == 7)
-	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
-      else if (modrm.reg == 6)
-	strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
-      else if (modrm.reg == 5)
-	strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
-
-      if (modrm.reg < 5 || modrm.rm != 0)
+      if (modrm.reg >= 5 && modrm.reg <= 7 && modrm.rm == 0)
 	{
-	  BadOp ();	/* bad sfence, mfence, or lfence */
+	  if (modrm.reg == 7)
+	    strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+	  else if (modrm.reg == 6)
+	    strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
+	  else if (modrm.reg == 5)
+	    strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
+	  bytemode = 0;
+	}
+      else if (modrm.reg <= 3 && (prefixes & PREFIX_REPZ) != 0)
+	{
+	  if (modrm.reg == 0)
+	    strcpy (obuf + strlen (obuf) - sizeof ("fxsave") + 1, "rdfsbase");
+	  else if (modrm.reg == 1)
+	    strcpy (obuf + strlen (obuf) - sizeof ("fxrstor") + 1, "rdgsbase");
+	  else if (modrm.reg == 2)
+	    strcpy (obuf + strlen (obuf) - sizeof ("ldmxcsr") + 1, "wrfsbase");
+	  else if (modrm.reg == 3)
+	    strcpy (obuf + strlen (obuf) - sizeof ("stmxcsr") + 1, "wrgsbase");
+	  used_prefixes |= PREFIX_REPZ;
+	  bytemode = dq_mode;
+	}
+      else
+	{
+	  BadOp ();
 	  return;
 	}
-      bytemode = 0;
     }
 
   OP_E (bytemode, sizeflag);

Modified: head/contrib/binutils/opcodes/i386-opc.h
==============================================================================
--- head/contrib/binutils/opcodes/i386-opc.h	Tue Sep  5 18:13:11 2017	(r323191)
+++ head/contrib/binutils/opcodes/i386-opc.h	Tue Sep  5 19:04:07 2017	(r323192)
@@ -81,6 +81,7 @@ typedef struct template
 #define CpuPCLMUL   0x10000000	/* Carry-less Multiplication extensions */
 #define CpuRdRnd    0x20000000	/* Intel Random Number Generator extensions */
 #define CpuSMAP     0x40000000	/* Intel Supervisor Mode Access Prevention */
+#define CpuFSGSBase 0x80000000	/* Read/write fs/gs segment base registers */
 
 /* SSE4.1/4.2 Instructions required */
 #define CpuSSE4	     (CpuSSE4_1|CpuSSE4_2)
@@ -89,7 +90,8 @@ typedef struct template
 #define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
 	|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \
 	|Cpu3dnow|Cpu3dnowA|CpuK6|CpuPadLock|CpuSVME|CpuSSSE3|CpuSSE4_1 \
-	|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP)
+	|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP \
+	|CpuFSGSBase)
 
   /* the bits in opcode_modifier are used to generate the final opcode from
      the base_opcode.  These bits also are used to detect alternate forms of

Modified: head/contrib/binutils/opcodes/i386-opc.tbl
==============================================================================
--- head/contrib/binutils/opcodes/i386-opc.tbl	Tue Sep  5 18:13:11 2017	(r323191)
+++ head/contrib/binutils/opcodes/i386-opc.tbl	Tue Sep  5 19:04:07 2017	(r323192)
@@ -1525,3 +1525,13 @@ pclmulhqhqdq, 2, 0x660f3a44, 0x11, CpuPCLMUL, Modrm|Ig
 // Intel Random Number Generator extensions
 rdrand, 1, 0x0fc7, 0x6, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
 rdseed, 1, 0x0fc7, 0x7, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
+
+// Intel Supervisor Mode Access Prevention extensions
+clac, 0, 0x0f01, 0xca, CpuSMAP, NoSuf|ImmExt, { 0 }
+stac, 0, 0x0f01, 0xcb, CpuSMAP, NoSuf|ImmExt, { 0 }
+
+// Read/write fs/gs segment base registers
+rdfsbase, 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
+rdgsbase, 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
+wrfsbase, 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
+wrgsbase, 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }

Modified: head/contrib/binutils/opcodes/i386-tbl.h
==============================================================================
--- head/contrib/binutils/opcodes/i386-tbl.h	Tue Sep  5 18:13:11 2017	(r323191)
+++ head/contrib/binutils/opcodes/i386-tbl.h	Tue Sep  5 19:04:07 2017	(r323192)
@@ -4400,6 +4400,20 @@ const template i386_optab[] =
     NoSuf|ImmExt, { 0, 0, 0 } },
   {"stac", 0, 0x0f01, 0xcb, CpuSMAP,
     NoSuf|ImmExt, { 0, 0, 0 } },
+
+  /* Read/write fs/gs segment base registers */
+  {"rdfsbase", 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64,
+    Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
+    { Reg32|Reg64 } },
+  {"rdgsbase", 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64,
+    Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
+    { Reg32|Reg64 } },
+  {"wrfsbase", 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64,
+    Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
+    { Reg32|Reg64 } },
+  {"wrgsbase", 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64,
+    Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
+    { Reg32|Reg64 } },
   
   { NULL, 0, 0, 0, 0, 0, { 0 } }
 };



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709051904.v85J48P2013715>