public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: Update x86 disassembler
@ 2007-08-29 15:15 H.J. Lu
  0 siblings, 0 replies; 4+ messages in thread
From: H.J. Lu @ 2007-08-29 15:15 UTC (permalink / raw)
  To: binutils

This patch adds more tables to x86 disassembler, uses separate
prefix strings, supports recursive dis386. Fix invalid instructions
like:

   0:   0f 73 fe 02             pslldq $0x2,%mm6
   4:   0f 73 de 02             psrldq $0x2,%mm6

I will check it in shortly.


H.J.
----
gas/testsuite/

2007-08-28  H.J. Lu  <hongjiu.lu@intel.com>

	* gas/i386/i386.exp: Run reg and reg-intel.

	* gas/i386/katmai.d: Update bad instructions.

	* gas/i386/reg-intel.d: New.
	* gas/i386/reg.d: Likewise.
	* gas/i386/reg.s: Likewise.

opcodes/

2007-08-28  H.J. Lu  <hongjiu.lu@intel.com>

	* i386-dis.c (OP_Skip_MODRM): New.
	(OP_Monitor): Likewise.
	(OP_Mwait): Likewise.
	(Mb): Likewise.
	(Skip_MODRM): Likewise.
	(USE_OPC_EXT_TABLE): Likewise.
	(USE_OPC_EXT_RM_TABLE): Likewise.
	(PREGRP98...PREGRP100): Likewise.
	(OPC_EXT_0...OPC_EXT_24): Likewise.
	(OPC_EXT_RM_0...OPC_EXT_RM_4): Likewise.
	(lock_prefix): Likewise.
	(data_prefix): Likewise.
	(addr_prefix): Likewise.
	(repz_prefix): Likewise.
	(repnz_prefix): Likewise.
	(opc_ext_table): Likewise.
	(opc_ext_rm_table): Likewise.
	(get_valid_dis386): Likewise.
	(OP_VMX): Removed.
	(OP_0fae): Likewise.
	(PNI_Fixup): Likewise.
	(VMX_Fixup): Likewise.
	(VM): Likewise.
	(twobyte_uses_DATA_prefix): Likewise.
	(twobyte_uses_REPNZ_prefix): Likewise.
	(twobyte_uses_REPZ_prefix): Likewise.
	(threebyte_0x38_uses_DATA_prefix): Likewise.
	(threebyte_0x38_uses_REPNZ_prefix): Likewise.
	(threebyte_0x38_uses_REPZ_prefix): Likewise.
	(threebyte_0x3a_uses_DATA_prefix): Likewise.
	(threebyte_0x3a_uses_REPNZ_prefix): Likewise.
	(threebyte_0x3a_uses_REPZ_prefix): Likewise.
	(grps): Use OPC_EXT_0...OPC_EXT_24.
	(prefix_user_table): Use PREGRP98.
	(print_insn): Remove uses_DATA_prefix, uses_LOCK_prefix,
	uses_REPNZ_prefix and uses_REPZ_prefix.  Initialize
	repz_prefix, repnz_prefix, lock_prefix, addr_prefix and
	data_prefix based on prefixes.  Call get_valid_dis386 to
	get a pointer to the valid dis386.  Print out prefixes if
	they aren't NULL.
	(OP_C): Clear lock_prefix if PREFIX_LOCK is used.
	(REP_Fixup): Set repz_prefix to "rep " when seeing
	PREFIX_REPZ.

--- binutils/gas/testsuite/gas/i386/i386.exp.table	2007-08-28 21:59:04.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/i386.exp	2007-08-29 06:51:06.000000000 -0700
@@ -90,6 +90,8 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "simd-intel"
     run_dump_test "mem"
     run_dump_test "mem-intel"
+    run_dump_test "reg"
+    run_dump_test "reg-intel"
 
     # These tests require support for 8 and 16 bit relocs,
     # so we only run them for ELF and COFF targets.
--- binutils/gas/testsuite/gas/i386/katmai.d.table	2004-03-12 05:06:50.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/katmai.d	2007-08-28 22:42:57.000000000 -0700
@@ -165,8 +165,7 @@ Disassembly of section .text:
  246:	90 [ 	]*nop    
  247:	90 [ 	]*nop    
  248:	65 [ 	]*gs
- 249:	0f [ 	]*sfence.*\(bad\).*
- 24a:	ae [ 	]*scas   %es:\(%edi\),%al
+ 249:	0f ae[ 	]*\(bad\).*
  24b:	ff 00 [ 	]*incl   \(%eax\)
  24d:	00 00 [ 	]*add    %al,\(%eax\)
 	...
--- binutils/gas/testsuite/gas/i386/reg-intel.d.table	2007-08-29 06:56:57.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/reg-intel.d	2007-08-29 06:50:44.000000000 -0700
@@ -0,0 +1,47 @@
+#source: reg.s
+#as: -J
+#objdump: -dw -Mintel
+#name: i386 reg (Intel mode)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 71 d6 02          	psrlw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 d6 02       	psrlw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 71 e6 02          	psraw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 e6 02       	psraw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 71 f6 02          	psllw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 f6 02       	psllw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 d6 02          	psrld  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 d6 02       	psrld  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 e6 02          	psrad  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 e6 02       	psrad  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 f6 02          	pslld  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 f6 02       	pslld  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 73 d6 02          	psrlq  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 d6 02       	psrlq  xmm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 de 02       	psrldq xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 73 f6 02          	psllq  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 f6 02       	psllq  xmm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 fe 02       	pslldq xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 71 d6 02          	psrlw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 d6 02       	psrlw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 71 e6 02          	psraw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 e6 02       	psraw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 71 f6 02          	psllw  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 71 f6 02       	psllw  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 d6 02          	psrld  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 d6 02       	psrld  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 e6 02          	psrad  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 e6 02       	psrad  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 72 f6 02          	pslld  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 72 f6 02       	pslld  xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 73 d6 02          	psrlq  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 d6 02       	psrlq  xmm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 de 02       	psrldq xmm6,0x2
+[ 	]*[a-f0-9]+:	0f 73 f6 02          	psllq  mm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 f6 02       	psllq  xmm6,0x2
+[ 	]*[a-f0-9]+:	66 0f 73 fe 02       	pslldq xmm6,0x2
+#pass
--- binutils/gas/testsuite/gas/i386/reg.d.table	2007-08-29 06:57:01.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/reg.d	2007-08-29 06:49:48.000000000 -0700
@@ -0,0 +1,45 @@
+#objdump: -dw
+#name: i386 reg
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 71 d6 02          	psrlw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 d6 02       	psrlw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 71 e6 02          	psraw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 e6 02       	psraw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 71 f6 02          	psllw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 f6 02       	psllw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 d6 02          	psrld  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 d6 02       	psrld  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 e6 02          	psrad  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 e6 02       	psrad  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 f6 02          	pslld  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 f6 02       	pslld  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 73 d6 02          	psrlq  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 73 d6 02       	psrlq  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	66 0f 73 de 02       	psrldq \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 73 f6 02          	psllq  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 73 f6 02       	psllq  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	66 0f 73 fe 02       	pslldq \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 71 d6 02          	psrlw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 d6 02       	psrlw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 71 e6 02          	psraw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 e6 02       	psraw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 71 f6 02          	psllw  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 71 f6 02       	psllw  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 d6 02          	psrld  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 d6 02       	psrld  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 e6 02          	psrad  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 e6 02       	psrad  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 72 f6 02          	pslld  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 72 f6 02       	pslld  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 73 d6 02          	psrlq  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 73 d6 02       	psrlq  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	66 0f 73 de 02       	psrldq \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	0f 73 f6 02          	psllq  \$0x2,%mm6
+[ 	]*[a-f0-9]+:	66 0f 73 f6 02       	psllq  \$0x2,%xmm6
+[ 	]*[a-f0-9]+:	66 0f 73 fe 02       	pslldq \$0x2,%xmm6
+#pass
--- binutils/gas/testsuite/gas/i386/reg.s.table	2007-08-29 06:57:04.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/reg.s	2007-08-29 06:48:10.000000000 -0700
@@ -0,0 +1,44 @@
+# Check instructions with one register operand
+
+	.text
+_start:
+psrlw $2, %mm6
+psrlw $2, %xmm6
+psraw $2, %mm6
+psraw $2, %xmm6
+psllw $2, %mm6
+psllw $2, %xmm6
+psrld $2, %mm6
+psrld $2, %xmm6
+psrad $2, %mm6
+psrad $2, %xmm6
+pslld $2, %mm6
+pslld $2, %xmm6
+psrlq $2, %mm6
+psrlq $2, %xmm6
+psrldq $2, %xmm6
+psllq $2, %mm6
+psllq $2, %xmm6
+pslldq $2, %xmm6
+
+.intel_syntax noprefix
+psrlw mm6, 2
+psrlw xmm6, 2
+psraw mm6, 2
+psraw xmm6, 2
+psllw mm6, 2
+psllw xmm6, 2
+psrld mm6, 2
+psrld xmm6, 2
+psrad mm6, 2
+psrad xmm6, 2
+pslld mm6, 2
+pslld xmm6, 2
+psrlq mm6, 2
+psrlq xmm6, 2
+psrldq xmm6, 2
+psllq mm6, 2
+psllq xmm6, 2
+pslldq xmm6, 2
+
+.p2align 4,0
--- binutils/opcodes/i386-dis.c.table	2007-08-28 21:59:03.000000000 -0700
+++ binutils/opcodes/i386-dis.c	2007-08-29 07:13:14.000000000 -0700
@@ -60,6 +60,7 @@ static bfd_signed_vma get32 (void);
 static bfd_signed_vma get32s (void);
 static int get16 (void);
 static void set_op (bfd_vma, int);
+static void OP_Skip_MODRM (int, int);
 static void OP_REG (int, int);
 static void OP_IMREG (int, int);
 static void OP_I (int, int);
@@ -86,19 +87,17 @@ static void OP_MXC (int,int);
 static void OP_MS (int, int);
 static void OP_XS (int, int);
 static void OP_M (int, int);
-static void OP_VMX (int, int);
-static void OP_0fae (int, int);
 static void OP_0f07 (int, int);
+static void OP_Monitor (int, int);
+static void OP_Mwait (int, int);
 static void NOP_Fixup1 (int, int);
 static void NOP_Fixup2 (int, int);
 static void OP_3DNowSuffix (int, int);
 static void OP_SIMD_Suffix (int, int);
 static void SIMD_Fixup (int, int);
-static void PNI_Fixup (int, int);
 static void SVME_Fixup (int, int);
 static void INVLPG_Fixup (int, int);
 static void BadOp (void);
-static void VMX_Fixup (int, int);
 static void REP_Fixup (int, int);
 static void CMPXCHG8B_Fixup (int, int);
 static void XMM_Fixup (int, int);
@@ -215,6 +214,7 @@ fetch_data (struct disassemble_info *inf
 #define Ew { OP_E, w_mode }
 #define M { OP_M, 0 }		/* lea, lgdt, etc. */
 #define Ma { OP_M, v_mode }
+#define Mb { OP_M, b_mode }
 #define Md { OP_M, d_mode }
 #define Mp { OP_M, f_mode }		/* 32 or 48 bit memory operand for LDS, LES etc */
 #define Mq { OP_M, q_mode }
@@ -238,6 +238,7 @@ fetch_data (struct disassemble_info *inf
 #define Cm { OP_C, m_mode }
 #define Dm { OP_D, m_mode }
 #define Td { OP_T, d_mode }
+#define Skip_MODRM { OP_Skip_MODRM, 0 }
 
 #define RMeAX { OP_REG, eAX_reg }
 #define RMeBX { OP_REG, eBX_reg }
@@ -320,7 +321,6 @@ fetch_data (struct disassemble_info *inf
 #define XS { OP_XS, v_mode }
 #define EMCq { OP_EMC, q_mode }
 #define MXC { OP_MXC, 0 }
-#define VM { OP_VMX, q_mode }
 #define OPSUF { OP_3DNowSuffix, 0 }
 #define OPSIMD { OP_SIMD_Suffix, 0 }
 #define XMM0 { XMM_Fixup, 0 }
@@ -414,6 +414,8 @@ fetch_data (struct disassemble_info *inf
 #define USE_PREFIX_USER_TABLE 3
 #define X86_64_SPECIAL 4
 #define IS_3BYTE_OPCODE 5
+#define USE_OPC_EXT_TABLE 6
+#define USE_OPC_EXT_RM_TABLE 7
 
 #define FLOAT	  NULL, { { NULL, FLOATCODE } }
 
@@ -544,6 +546,9 @@ fetch_data (struct disassemble_info *inf
 #define PREGRP95  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
 #define PREGRP96  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
 #define PREGRP97  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
+#define PREGRP98  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
+#define PREGRP99  NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
+#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
 
 
 #define X86_64_0  NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
@@ -554,6 +559,38 @@ fetch_data (struct disassemble_info *inf
 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
 
+#define OPC_EXT_0  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } }
+#define OPC_EXT_1  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } }
+#define OPC_EXT_2  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 2 } }
+#define OPC_EXT_3  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 3 } }
+#define OPC_EXT_4  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 4 } }
+#define OPC_EXT_5  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 5 } }
+#define OPC_EXT_6  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 6 } }
+#define OPC_EXT_7  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 7 } }
+#define OPC_EXT_8  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 8 } }
+#define OPC_EXT_9  NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 9 } }
+#define OPC_EXT_10 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 10 } }
+#define OPC_EXT_11 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 11 } }
+#define OPC_EXT_12 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 12 } }
+#define OPC_EXT_13 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 13 } }
+#define OPC_EXT_14 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 14 } }
+#define OPC_EXT_15 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 15 } }
+#define OPC_EXT_16 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 16 } }
+#define OPC_EXT_17 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 17 } }
+#define OPC_EXT_18 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 18 } }
+#define OPC_EXT_19 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 19 } }
+#define OPC_EXT_20 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 20 } }
+#define OPC_EXT_21 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 21 } }
+#define OPC_EXT_22 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 22 } }
+#define OPC_EXT_23 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 23 } }
+#define OPC_EXT_24 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 24 } }
+
+#define OPC_EXT_RM_0  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } }
+#define OPC_EXT_RM_1  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } }
+#define OPC_EXT_RM_2  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 2 } }
+#define OPC_EXT_RM_3  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } }
+#define OPC_EXT_RM_4  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } }
+
 typedef void (*op_rtn) (int bytemode, int sizeflag);
 
 struct dis386 {
@@ -1234,225 +1271,17 @@ static const unsigned char twobyte_has_m
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
 
-static const unsigned char twobyte_uses_DATA_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
-  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-static const unsigned char twobyte_uses_REPZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
-  /* 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 */
-  /* 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 */
-  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 38 XX uses DATA prefix.  */
-static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
-  /* 10 */ 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0, /* 1f */
-  /* 20 */ 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0, /* 2f */
-  /* 30 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* 3f */
-  /* 40 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 38 XX uses REPNZ prefix.  */
-static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 38 XX uses REPZ prefix.  */
-static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 3a XX uses DATA prefix.  */
-static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, /* 0f */
-  /* 10 */ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 3a XX uses REPNZ prefix.  */
-static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
-/* This is used to determine if opcode 0f 3a XX uses REPZ prefix.  */
-static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-  /*       -------------------------------        */
-  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
-  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
-  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
-  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
-  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
-  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
-  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
-  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
-  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
-  /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
-  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
-  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
-  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
-  /*       -------------------------------        */
-  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
-};
-
 static char obuf[100];
 static char *obufp;
 static char scratchbuf[100];
 static unsigned char *start_codep;
 static unsigned char *insn_codep;
 static unsigned char *codep;
+static const char *lock_prefix;
+static const char *data_prefix;
+static const char *addr_prefix;
+static const char *repz_prefix;
+static const char *repnz_prefix;
 static disassemble_info *the_info;
 static struct
   {
@@ -1696,8 +1525,8 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP7 */
   {
-    { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
-    { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
+    { OPC_EXT_0 },
+    { OPC_EXT_1 },
     { "lgdt{Q|Q||}",	 { M } },
     { "lidt{Q|Q||}",	 { { SVME_Fixup, 0 } } },
     { "smswD",	{ Sv } },
@@ -1724,8 +1553,8 @@ static const struct dis386 grps[][8] = {
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
-    { "",	{ VM } },		/* See OP_VMX.  */
-    { "vmptrst", { Mq } },
+    { OPC_EXT_2 },
+    { OPC_EXT_3 },
   },
   /* GRP11_C6 */
   {
@@ -1753,56 +1582,56 @@ static const struct dis386 grps[][8] = {
   {
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
-    { "psrlw",	{ MS, Ib } },
+    { OPC_EXT_4 },
     { "(bad)",	{ XX } },
-    { "psraw",	{ MS, Ib } },
+    { OPC_EXT_5 },
     { "(bad)",	{ XX } },
-    { "psllw",	{ MS, Ib } },
+    { OPC_EXT_6 },
     { "(bad)",	{ XX } },
   },
   /* GRP13 */
   {
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
-    { "psrld",	{ MS, Ib } },
+    { OPC_EXT_7 },
     { "(bad)",	{ XX } },
-    { "psrad",	{ MS, Ib } },
+    { OPC_EXT_8 },
     { "(bad)",	{ XX } },
-    { "pslld",	{ MS, Ib } },
+    { OPC_EXT_9 },
     { "(bad)",	{ XX } },
   },
   /* GRP14 */
   {
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
-    { "psrlq",	{ MS, Ib } },
-    { "psrldq",	{ MS, Ib } },
+    { OPC_EXT_10 },
+    { OPC_EXT_11 },
     { "(bad)",	{ XX } },
     { "(bad)",	{ XX } },
-    { "psllq",	{ MS, Ib } },
-    { "pslldq",	{ MS, Ib } },
+    { OPC_EXT_12 },
+    { OPC_EXT_13 },
   },
   /* GRP15 */
   {
-    { "fxsave",		{ M } },
-    { "fxrstor",	{ M } },
-    { "ldmxcsr",	{ Md } },
-    { "stmxcsr",	{ Md } },
-    { "(bad)",		{ XX } },
-    { "lfence",		{ { OP_0fae, 0 } } },
-    { "mfence",		{ { OP_0fae, 0 } } },
-    { "clflush",	{ { OP_0fae, b_mode } } },
+    { OPC_EXT_14 },
+    { OPC_EXT_15 },
+    { OPC_EXT_16 },
+    { OPC_EXT_17 },
+    { "(bad)",	{ XX } },
+    { OPC_EXT_18 },
+    { OPC_EXT_19 },
+    { OPC_EXT_20 },
   },
   /* GRP16 */
   {
-    { "prefetchnta",	{ Ev } },
-    { "prefetcht0",	{ Ev } },
-    { "prefetcht1",	{ Ev } },
-    { "prefetcht2",	{ Ev } },
-    { "(bad)",		{ XX } },
-    { "(bad)",		{ XX } },
-    { "(bad)",		{ XX } },
-    { "(bad)",		{ XX } },
+    { OPC_EXT_21 },
+    { OPC_EXT_22 },
+    { OPC_EXT_23 },
+    { OPC_EXT_24 },
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
   },
   /* GRPAMD */
   {
@@ -2590,6 +2419,30 @@ static const struct dis386 prefix_user_t
     { "punpckldq",{ MX, EMx } },
     { "(bad)",	{ XX } },
   },
+
+  /* PREGRP98 */
+  {
+    { "vmptrld",{ Mq } },
+    { "vmxon",	{ Mq } },
+    { "vmclear",{ Mq } },
+    { "(bad)",	{ XX } },
+  },
+
+  /* PREGRP99 */
+  {
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+    { "psrldq",	{ MS, Ib } },
+    { "(bad)",	{ XX } },
+  },
+
+  /* PREGRP99 */
+  {
+    { "(bad)",	{ XX } },
+    { "(bad)",	{ XX } },
+    { "pslldq",	{ MS, Ib } },
+    { "(bad)",	{ XX } },
+  },
 };
 
 static const struct dis386 x86_64_table[][2] = {
@@ -3196,6 +3049,192 @@ static const struct dis386 three_byte_ta
   }
 };
 
+static const struct dis386 opc_ext_table[][2] = {
+  {
+    /* OPC_EXT_0 */
+    { "sgdt{Q|IQ||}",	{ M } },
+    { OPC_EXT_RM_0 },
+  },
+  {
+    /* OPC_EXT_1 */
+    { "sidt{Q|IQ||}",	{ M } },
+    { OPC_EXT_RM_1 },
+  },
+  {
+    /* OPC_EXT_2 */
+    { PREGRP98 },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_3 */
+    { "vmptrst",	{ Mq } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_4 */
+    { "(bad)",		{ XX } },
+    { "psrlw",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_5 */
+    { "(bad)",		{ XX } },
+    { "psraw",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_6 */
+    { "(bad)",		{ XX } },
+    { "psllw",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_7 */
+    { "(bad)",		{ XX } },
+    { "psrld",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_8 */
+    { "(bad)",		{ XX } },
+    { "psrad",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_9 */
+    { "(bad)",		{ XX } },
+    { "pslld",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_10 */
+    { "(bad)",		{ XX } },
+    { "psrlq",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_11 */
+    { "(bad)",		{ XX } },
+    { PREGRP99 },
+  },
+  {
+    /* OPC_EXT_12 */
+    { "(bad)",		{ XX } },
+    { "psllq",		{ MS, Ib } },
+  },
+  {
+    /* OPC_EXT_13 */
+    { "(bad)",		{ XX } },
+    { PREGRP100 },
+  },
+  {
+    /* OPC_EXT_14 */
+    { "fxsave",		{ M } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_15 */
+    { "fxrstor",	{ M } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_16 */
+    { "ldmxcsr",	{ Md } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_17 */
+    { "stmxcsr",	{ Md } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_18 */
+    { "(bad)",		{ XX } },
+    { OPC_EXT_RM_2 },
+  },
+  {
+    /* OPC_EXT_19 */
+    { "(bad)",		{ XX } },
+    { OPC_EXT_RM_3 },
+  },
+  {
+    /* OPC_EXT_20 */
+    { "clflush",	{ Mb } },
+    { OPC_EXT_RM_4 },
+  },
+  {
+    /* OPC_EXT_21 */
+    { "prefetchnta",	{ Mb } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_22 */
+    { "prefetcht0",	{ Mb } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_23 */
+    { "prefetcht1",	{ Mb } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_24 */
+    { "prefetcht2",	{ Mb } },
+    { "(bad)",		{ XX } },
+  },
+};
+
+static const struct dis386 opc_ext_rm_table[][8] = {
+  {
+    /* OPC_EXT_RM_0 */
+    { "(bad)",		{ XX } },
+    { "vmcall",		{ Skip_MODRM } },
+    { "vmlaunch",	{ Skip_MODRM } },
+    { "vmresume",	{ Skip_MODRM } },
+    { "vmxoff",		{ Skip_MODRM } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_RM_1 */
+    { "monitor",	{ { OP_Monitor, 0 } } },
+    { "mwait",		{ { OP_Mwait, 0 } } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_RM_2 */
+    { "lfence",		{ Skip_MODRM } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_RM_3 */
+    { "mfence",		{ Skip_MODRM } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+  },
+  {
+    /* OPC_EXT_RM_4 */
+    { "sfence",		{ Skip_MODRM } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+    { "(bad)",		{ XX } },
+  },
+};
+
 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
 
 static void
@@ -3440,6 +3479,79 @@ with the -M switch (multiple options sho
   fprintf (stream, _("  suffix      Always display instruction suffix in AT&T syntax\n"));
 }
 
+/* Get a pointer to struct dis386 with a valid name.  */
+
+static const struct dis386 *
+get_valid_dis386 (const struct dis386 *dp)
+{
+  int index;
+
+  if (dp->name != NULL)
+    return dp;
+
+  switch (dp->op[0].bytemode)
+    {
+    case USE_GROUPS:
+      dp = &grps[dp->op[1].bytemode][modrm.reg];
+      break;
+
+    case USE_PREFIX_USER_TABLE:
+      index = 0;
+      used_prefixes |= (prefixes & PREFIX_REPZ);
+      if (prefixes & PREFIX_REPZ)
+	{
+	  index = 1;
+	  repz_prefix = NULL;
+	}
+      else
+	{
+	  /* We should check PREFIX_REPNZ and PREFIX_REPZ before
+	     PREFIX_DATA.  */
+	  used_prefixes |= (prefixes & PREFIX_REPNZ);
+	  if (prefixes & PREFIX_REPNZ)
+	    {
+	      index = 3;
+	      repnz_prefix = NULL;
+	    }
+	  else
+	    {
+	      used_prefixes |= (prefixes & PREFIX_DATA);
+	      if (prefixes & PREFIX_DATA)
+		{
+		  index = 2;
+		  data_prefix = NULL;
+		}
+	    }
+	}
+      dp = &prefix_user_table[dp->op[1].bytemode][index];
+      break;
+
+    case X86_64_SPECIAL:
+      index = address_mode == mode_64bit ? 1 : 0;
+      dp = &x86_64_table[dp->op[1].bytemode][index];
+      break;
+
+    case USE_OPC_EXT_TABLE:
+      index = modrm.mod == 0x3 ? 1 : 0;
+      dp = &opc_ext_table[dp->op[1].bytemode][index];
+      break;
+
+    case USE_OPC_EXT_RM_TABLE:
+      index = modrm.rm;
+      dp = &opc_ext_rm_table[dp->op[1].bytemode][index];
+      break;
+
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return NULL;
+    }
+
+  if (dp->name != NULL)
+    return dp;
+  else
+    return get_valid_dis386 (dp);
+}
+
 static int
 print_insn (bfd_vma pc, disassemble_info *info)
 {
@@ -3447,12 +3559,12 @@ print_insn (bfd_vma pc, disassemble_info
   int i;
   char *op_txt[MAX_OPERANDS];
   int needcomma;
-  unsigned char uses_DATA_prefix, uses_LOCK_prefix;
-  unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
   int sizeflag;
   const char *p;
   struct dis_private priv;
   unsigned char op;
+  char prefix_obuf[32];
+  char *prefix_obufp;
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
       || info->mach == bfd_mach_x86_64)
@@ -3637,75 +3749,60 @@ print_insn (bfd_vma pc, disassemble_info
       threebyte = *++codep;
       dp = &dis386_twobyte[threebyte];
       need_modrm = twobyte_has_modrm[*codep];
-      uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
-      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
-      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
-      uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
       codep++;
       if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
 	{
 	  FETCH_DATA (info, codep + 2);
 	  op = *codep++;
-	  switch (threebyte)
-	    {
-	    case 0x38:
-	      uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
-	      uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
-	      uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
-	      break;
-	    case 0x3a:
-	      uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
-	      uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
-	      uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
-	      break;
-	    default:
-	      break;
-	    }
 	}
     }
   else
     {
       dp = &dis386[*codep];
       need_modrm = onebyte_has_modrm[*codep];
-      uses_DATA_prefix = 0;
-      uses_REPNZ_prefix = 0;
-      /* pause is 0xf3 0x90.  */
-      uses_REPZ_prefix = *codep == 0x90;
-      uses_LOCK_prefix = 0;
       codep++;
     }
 
-  if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
+  if ((prefixes & PREFIX_REPZ))
     {
-      oappend ("repz ");
+      repz_prefix = "repz ";
       used_prefixes |= PREFIX_REPZ;
     }
-  if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
+  else
+    repz_prefix = NULL;
+
+  if ((prefixes & PREFIX_REPNZ))
     {
-      oappend ("repnz ");
+      repnz_prefix = "repnz ";
       used_prefixes |= PREFIX_REPNZ;
     }
+  else
+    repnz_prefix = NULL;
 
-  if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
+  if ((prefixes & PREFIX_LOCK))
     {
-      oappend ("lock ");
+      lock_prefix = "lock ";
       used_prefixes |= PREFIX_LOCK;
     }
+  else
+    lock_prefix = NULL;
 
+  addr_prefix = NULL;
   if (prefixes & PREFIX_ADDR)
     {
       sizeflag ^= AFLAG;
       if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
 	{
 	  if ((sizeflag & AFLAG) || address_mode == mode_64bit)
-	    oappend ("addr32 ");
+	    addr_prefix = "addr32 ";
 	  else
-	    oappend ("addr16 ");
+	    addr_prefix = "addr16 ";
 	  used_prefixes |= PREFIX_ADDR;
 	}
     }
 
-  if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
+  data_prefix = NULL;
+  if ((prefixes & PREFIX_DATA))
     {
       sizeflag ^= DFLAG;
       if (dp->op[2].bytemode == cond_jump_mode
@@ -3713,9 +3810,9 @@ print_insn (bfd_vma pc, disassemble_info
 	  && !intel_syntax)
 	{
 	  if (sizeflag & DFLAG)
-	    oappend ("data32 ");
+	    data_prefix = "data32 ";
 	  else
-	    oappend ("data16 ");
+	    data_prefix = "data16 ";
 	  used_prefixes |= PREFIX_DATA;
 	}
     }
@@ -3741,49 +3838,8 @@ print_insn (bfd_vma pc, disassemble_info
     }
   else
     {
-      int index;
-      if (dp->name == NULL)
-	{
-	  switch (dp->op[0].bytemode)
-	    {
-	    case USE_GROUPS:
-	      dp = &grps[dp->op[1].bytemode][modrm.reg];
-	      break;
-
-	    case USE_PREFIX_USER_TABLE:
-	      index = 0;
-	      used_prefixes |= (prefixes & PREFIX_REPZ);
-	      if (prefixes & PREFIX_REPZ)
-		index = 1;
-	      else
-		{
-		  /* We should check PREFIX_REPNZ and PREFIX_REPZ
-		     before PREFIX_DATA.  */
-		  used_prefixes |= (prefixes & PREFIX_REPNZ);
-		  if (prefixes & PREFIX_REPNZ)
-		    index = 3;
-		  else
-		    {
-		      used_prefixes |= (prefixes & PREFIX_DATA);
-		      if (prefixes & PREFIX_DATA)
-			index = 2;
-		    }
-		}
-	      dp = &prefix_user_table[dp->op[1].bytemode][index];
-	      break;
-
-	    case X86_64_SPECIAL:
-	      index = address_mode == mode_64bit ? 1 : 0;
-	      dp = &x86_64_table[dp->op[1].bytemode][index];
-	      break;
-
-	    default:
-	      oappend (INTERNAL_DISASSEMBLER_ERROR);
-	      break;
-	    }
-	}
-
-      if (dp->name != NULL && putop (dp->name, sizeflag) == 0)
+      dp = get_valid_dis386 (dp);
+      if (dp != NULL && putop (dp->name, sizeflag) == 0)
         {
 	  for (i = 0; i < MAX_OPERANDS; ++i)
 	    {
@@ -3818,8 +3874,24 @@ print_insn (bfd_vma pc, disassemble_info
       (*info->fprintf_func) (info->stream, "%s ", name);
     }
 
+  prefix_obuf[0] = 0;
+  prefix_obufp = prefix_obuf;
+  if (lock_prefix)
+    prefix_obufp = stpcpy (prefix_obufp, lock_prefix);
+  if (repz_prefix)
+    prefix_obufp = stpcpy (prefix_obufp, repz_prefix);
+  if (repnz_prefix)
+    prefix_obufp = stpcpy (prefix_obufp, repnz_prefix);
+  if (addr_prefix)
+    prefix_obufp = stpcpy (prefix_obufp, addr_prefix);
+  if (data_prefix)
+    prefix_obufp = stpcpy (prefix_obufp, data_prefix);
+
+  if (prefix_obuf[0] != 0)
+    (*info->fprintf_func) (info->stream, "%s", prefix_obuf);
+
   obufp = obuf + strlen (obuf);
-  for (i = strlen (obuf); i < 6; i++)
+  for (i = strlen (obuf) + strlen (prefix_obuf); i < 6; i++)
     oappend (" ");
   oappend (" ");
   (*info->fprintf_func) (info->stream, "%s", obuf);
@@ -4190,6 +4262,15 @@ static char *fgrps[][8] = {
 };
 
 static void
+OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED,
+	       int sizeflag ATTRIBUTE_UNUSED)
+{
+  /* Skip mod/rm byte.  */
+  MODRM_CHECK;
+  codep++;
+}
+
+static void
 dofloat (int sizeflag)
 {
   const struct dis386 *dp;
@@ -5714,6 +5795,7 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int si
     }
   else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
     {
+      lock_prefix = NULL;
       used_prefixes |= PREFIX_LOCK;
       add = 8;
     }
@@ -5903,33 +5985,6 @@ OP_0f07 (int bytemode, int sizeflag)
     OP_E (bytemode, sizeflag);
 }
 
-static void
-OP_0fae (int bytemode, int sizeflag)
-{
-  if (modrm.mod == 3)
-    {
-      if (modrm.reg == 7)
-	{
-	  bytemode = 0;
-	  strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1,
-		  "sfence");
-	}
-
-      if (modrm.reg < 5 || modrm.rm != 0)
-	{
-	  BadOp ();	/* bad sfence, mfence, or lfence */
-	  return;
-	}
-    }
-  else if (modrm.reg != 7)
-    {
-      BadOp ();		/* bad clflush */
-      return;
-    }
-
-  OP_E (bytemode, sizeflag);
-}
-
 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
    32bit mode and "xchg %rax,%rax" in 64bit mode.  */
 
@@ -6115,67 +6170,53 @@ SIMD_Fixup (int extrachar, int sizeflag 
 }
 
 static void
-PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+OP_Mwait (int bytemode ATTRIBUTE_UNUSED,
+	  int sizeflag ATTRIBUTE_UNUSED)
+{
+  /* mwait %eax,%ecx  */
+  if (!intel_syntax)
+    {
+      const char **names = (address_mode == mode_64bit
+			    ? names64 : names32);
+      strcpy (op_out[0], names[0]);
+      strcpy (op_out[1], names[1]);
+      two_source_ops = 1;
+    }
+  /* Skip mod/rm byte.  */
+  MODRM_CHECK;
+  codep++;
+}
+
+static void
+OP_Monitor (int bytemode ATTRIBUTE_UNUSED,
+	    int sizeflag ATTRIBUTE_UNUSED)
 {
-  if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
+  /* monitor %eax,%ecx,%edx"  */
+  if (!intel_syntax)
     {
-      /* Override "sidt".  */
-      size_t olen = strlen (obuf);
-      char *p = obuf + olen - 4;
+      const char **op1_names;
       const char **names = (address_mode == mode_64bit
 			    ? names64 : names32);
 
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'i')
-	--p;
-
-      /* Remove "addr16/addr32" if we aren't in Intel mode.  */
-      if (!intel_syntax
-	  && (prefixes & PREFIX_ADDR)
-	  && olen >= (4 + 7)
-	  && *(p - 1) == ' '
-	  && CONST_STRNEQ (p - 7, "addr")
-	  && (CONST_STRNEQ (p - 3, "16")
-	      || CONST_STRNEQ (p - 3, "32")))
-	p -= 7;
-
-      if (modrm.rm)
-	{
-	  /* mwait %eax,%ecx  */
-	  strcpy (p, "mwait");
-	  if (!intel_syntax)
-	    strcpy (op_out[0], names[0]);
-	}
+      if (!(prefixes & PREFIX_ADDR))
+	op1_names = (address_mode == mode_16bit
+		     ? names16 : names);
       else
 	{
-	  /* monitor %eax,%ecx,%edx"  */
-	  strcpy (p, "monitor");
-	  if (!intel_syntax)
-	    {
-	      const char **op1_names;
-	      if (!(prefixes & PREFIX_ADDR))
-		op1_names = (address_mode == mode_16bit
-			     ? names16 : names);
-	      else
-		{
-		  op1_names = (address_mode != mode_32bit
-			       ? names32 : names16);
-		  used_prefixes |= PREFIX_ADDR;
-		}
-	      strcpy (op_out[0], op1_names[0]);
-	      strcpy (op_out[2], names[2]);
-	    }
-	}
-      if (!intel_syntax)
-	{
-	  strcpy (op_out[1], names[1]);
-	  two_source_ops = 1;
+	  /* Remove "addr16/addr32".  */
+	  addr_prefix = NULL;
+	  op1_names = (address_mode != mode_32bit
+		       ? names32 : names16);
+	  used_prefixes |= PREFIX_ADDR;
 	}
-
-      codep++;
+      strcpy (op_out[0], op1_names[0]);
+      strcpy (op_out[1], names[1]);
+      strcpy (op_out[2], names[2]);
+      two_source_ops = 1;
     }
-  else
-    OP_M (0, sizeflag);
+  /* Skip mod/rm byte.  */
+  MODRM_CHECK;
+  codep++;
 }
 
 static void
@@ -6279,108 +6320,12 @@ BadOp (void)
 }
 
 static void
-VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (modrm.mod == 3
-      && modrm.reg == 0
-      && modrm.rm >=1
-      && modrm.rm <= 4)
-    {
-      /* Override "sgdt".  */
-      char *p = obuf + strlen (obuf) - 4;
-
-      /* We might have a suffix when disassembling with -Msuffix.  */
-      if (*p == 'g')
-	--p;
-
-      switch (modrm.rm)
-	{
-	case 1:
-	  strcpy (p, "vmcall");
-	  break;
-	case 2:
-	  strcpy (p, "vmlaunch");
-	  break;
-	case 3:
-	  strcpy (p, "vmresume");
-	  break;
-	case 4:
-	  strcpy (p, "vmxoff");
-	  break;
-	}
-
-      codep++;
-    }
-  else
-    OP_E (0, sizeflag);
-}
-
-static void
-OP_VMX (int bytemode, int sizeflag)
-{
-  used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
-  if (prefixes & PREFIX_DATA)
-    strcpy (obuf, "vmclear");
-  else if (prefixes & PREFIX_REPZ)
-    strcpy (obuf, "vmxon");
-  else
-    strcpy (obuf, "vmptrld");
-  OP_E (bytemode, sizeflag);
-}
-
-static void
 REP_Fixup (int bytemode, int sizeflag)
 {
   /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
      lods and stos.  */
-  size_t ilen = 0;
-
   if (prefixes & PREFIX_REPZ)
-    switch (*insn_codep)
-      {
-      case 0x6e:	/* outsb */
-      case 0x6f:	/* outsw/outsl */
-      case 0xa4:	/* movsb */
-      case 0xa5:	/* movsw/movsl/movsq */
-	if (!intel_syntax)
-	  ilen = 5;
-	else
-	  ilen = 4;
-	break;
-      case 0xaa:	/* stosb */
-      case 0xab:	/* stosw/stosl/stosq */
-      case 0xac:	/* lodsb */
-      case 0xad:	/* lodsw/lodsl/lodsq */
-	if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
-	  ilen = 5;
-	else
-	  ilen = 4;
-	break;
-      case 0x6c:	/* insb */
-      case 0x6d:	/* insl/insw */
-	if (!intel_syntax)
-	  ilen = 4;
-	else
-	  ilen = 3;
-	break;
-      default:
-	abort ();
-	break;
-      }
-
-  if (ilen != 0)
-    {
-      size_t olen;
-      char *p;
-
-      olen = strlen (obuf);
-      p = obuf + olen - ilen - 1 - 4;
-      /* Handle "repz [addr16|addr32]".  */
-      if ((prefixes & PREFIX_ADDR))
-	p -= 1 + 6;
-
-      memmove (p + 3, p + 4, olen - (p + 3 - obuf));
-    }
+    repz_prefix = "rep ";
 
   switch (bytemode)
     {

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: Update x86 disassembler
  2007-10-10 17:29 ` Olivier Galibert
@ 2007-10-10 18:11   ` H.J. Lu
  0 siblings, 0 replies; 4+ messages in thread
From: H.J. Lu @ 2007-10-10 18:11 UTC (permalink / raw)
  To: Olivier Galibert, binutils

On Wed, Oct 10, 2007 at 06:35:47PM +0200, Olivier Galibert wrote:
> On Wed, Oct 10, 2007 at 09:23:36AM -0700, H.J. Lu wrote:
> > I am checking in this patch to update x86 disassembler.
> 
> Isn't that pretty much what enum was designed for?
> 

Probably. But I won't want to worry about if DREX_OC1 + q_mode is
a valid enum.


H.J.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PATCH: Update x86 disassembler
  2007-10-10 16:35 H.J. Lu
@ 2007-10-10 17:29 ` Olivier Galibert
  2007-10-10 18:11   ` H.J. Lu
  0 siblings, 1 reply; 4+ messages in thread
From: Olivier Galibert @ 2007-10-10 17:29 UTC (permalink / raw)
  To: binutils

On Wed, Oct 10, 2007 at 09:23:36AM -0700, H.J. Lu wrote:
> I am checking in this patch to update x86 disassembler.

Isn't that pretty much what enum was designed for?

  OG.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* PATCH: Update x86 disassembler
@ 2007-10-10 16:35 H.J. Lu
  2007-10-10 17:29 ` Olivier Galibert
  0 siblings, 1 reply; 4+ messages in thread
From: H.J. Lu @ 2007-10-10 16:35 UTC (permalink / raw)
  To: binutils

I am checking in this patch to update x86 disassembler.


H.J.
---
2007-10-10  H.J. Lu  <hongjiu.lu@intel.com>

	* i386-dis.c (v_mode): Defined as previous one + 1.
	(w_mode): Likewise.
	(d_mode): Likewise.
	(q_mode): Likewise.
	(t_mode): Likewise.
	(x_mode): Likewise.
	(m_mode): Likewise.
	(cond_jump_mode): Likewise.
	(loop_jcxz_mode): Likewise.
	(dq_mode): Likewise.
	(dqw_mode): Likewise.
	(f_mode): Likewise.
	(const_1_mode): Likewise.
	(stack_v_mode): Likewise.
	(z_mode): Likewise.
	(o_mode): Likewise.
	(dqb_mode): Likewise.
	(dqd_mode): Likewise.
	(es_reg): Likewise.
	(cs_reg): Likewise.
	(ss_reg): Likewise.
	(ds_reg): Likewise.
	(fs_reg): Likewise.
	(gs_reg): Likewise.
	(eAX_reg): Likewise.
	(eCX_reg): Likewise.
	(eDX_reg): Likewise.
	(eBX_reg): Likewise.
	(eSP_reg): Likewise.
	(eBP_reg): Likewise.
	(eSI_reg): Likewise.
	(eDI_reg): Likewise.
	(al_reg): Likewise.
	(cl_reg): Likewise.
	(dl_reg): Likewise.
	(bl_reg): Likewise.
	(ah_reg): Likewise.
	(ch_reg): Likewise.
	(dh_reg): Likewise.
	(bh_reg): Likewise.
	(ax_reg): Likewise.
	(cx_reg): Likewise.
	(dx_reg): Likewise.
	(bx_reg): Likewise.
	(sp_reg): Likewise.
	(bp_reg): Likewise.
	(si_reg): Likewise.
	(di_reg): Likewise.
	(rAX_reg): Likewise.
	(rCX_reg): Likewise.
	(rDX_reg): Likewise.
	(rBX_reg): Likewise.
	(rSP_reg): Likewise.
	(rBP_reg): Likewise.
	(rSI_reg): Likewise.
	(rDI_reg): Likewise.
	(z_mode_ax_reg): Likewise.
	(indir_dx_reg): Likewise.
	(DREX_OC1): Updated.
	(DREX_NO_OC0): Likewise.
	(DREX_MASK): Likewise.
	(MAX_BYTEMODE): New.  Issue an error if MAX_BYTEMODE is not
	less than DREX_OC1.

--- i386-dis.c.ext	2007-10-10 08:49:16.000000000 -0700
+++ i386-dis.c	2007-10-10 09:12:40.000000000 -0700
@@ -361,76 +361,99 @@ fetch_data (struct disassemble_info *inf
 #define AFLAG 2
 #define DFLAG 1
 
-#define b_mode 1  /* byte operand */
-#define v_mode 2  /* operand size depends on prefixes */
-#define w_mode 3  /* word operand */
-#define d_mode 4  /* double word operand  */
-#define q_mode 5  /* quad word operand */
-#define t_mode 6  /* ten-byte operand */
-#define x_mode 7  /* 16-byte XMM operand */
-#define m_mode 8  /* d_mode in 32bit, q_mode in 64bit mode.  */
-#define cond_jump_mode 9
-#define loop_jcxz_mode 10
-#define dq_mode 11 /* operand size depends on REX prefixes.  */
-#define dqw_mode 12 /* registers like dq_mode, memory like w_mode.  */
-#define f_mode 13 /* 4- or 6-byte pointer operand */
-#define const_1_mode 14
-#define stack_v_mode 15 /* v_mode for stack-related opcodes.  */
-#define z_mode 16 /* non-quad operand size depends on prefixes */
-#define o_mode 17  /* 16-byte operand */
-#define dqb_mode 18 /* registers like dq_mode, memory like b_mode.  */
-#define dqd_mode 19 /* registers like dq_mode, memory like d_mode.  */
-
-/* Flags that are OR'ed into the bytemode field to pass extra information.  */
-#define DREX_OC1	0x4000	/* OC1 bit set */
-#define DREX_NO_OC0	0x2000	/* OC0 bit not used */
-#define DREX_MASK	0x6000	/* mask to delete */
-
-#define es_reg 100
-#define cs_reg 101
-#define ss_reg 102
-#define ds_reg 103
-#define fs_reg 104
-#define gs_reg 105
-
-#define eAX_reg 108
-#define eCX_reg 109
-#define eDX_reg 110
-#define eBX_reg 111
-#define eSP_reg 112
-#define eBP_reg 113
-#define eSI_reg 114
-#define eDI_reg 115
-
-#define al_reg 116
-#define cl_reg 117
-#define dl_reg 118
-#define bl_reg 119
-#define ah_reg 120
-#define ch_reg 121
-#define dh_reg 122
-#define bh_reg 123
-
-#define ax_reg 124
-#define cx_reg 125
-#define dx_reg 126
-#define bx_reg 127
-#define sp_reg 128
-#define bp_reg 129
-#define si_reg 130
-#define di_reg 131
-
-#define rAX_reg 132
-#define rCX_reg 133
-#define rDX_reg 134
-#define rBX_reg 135
-#define rSP_reg 136
-#define rBP_reg 137
-#define rSI_reg 138
-#define rDI_reg 139
+/* byte operand */
+#define b_mode			1
+/* operand size depends on prefixes */
+#define v_mode 			(b_mode + 1)
+/* word operand */
+#define w_mode			(v_mode + 1)
+/* double word operand  */
+#define d_mode			(w_mode + 1)
+/* quad word operand */
+#define q_mode			(d_mode + 1)
+/* ten-byte operand */
+#define t_mode			(q_mode + 1)
+/* 16-byte XMM operand */
+#define x_mode			(t_mode + 1)
+/* d_mode in 32bit, q_mode in 64bit mode.  */
+#define m_mode			(x_mode + 1)
+#define cond_jump_mode		(m_mode + 1)
+#define loop_jcxz_mode		(cond_jump_mode + 1)
+/* operand size depends on REX prefixes.  */
+#define dq_mode			(loop_jcxz_mode + 1)
+/* registers like dq_mode, memory like w_mode.  */
+#define dqw_mode		(dq_mode + 1)
+/* 4- or 6-byte pointer operand */
+#define f_mode			(dqw_mode + 1)
+#define const_1_mode		(f_mode + 1)
+/* v_mode for stack-related opcodes.  */
+#define stack_v_mode		(const_1_mode + 1)
+/* non-quad operand size depends on prefixes */
+#define z_mode			(stack_v_mode + 1)
+/* 16-byte operand */
+#define o_mode			(z_mode + 1)
+/* registers like dq_mode, memory like b_mode.  */
+#define dqb_mode		(o_mode + 1)
+/* registers like dq_mode, memory like d_mode.  */
+#define dqd_mode		(dqb_mode + 1)
+
+#define es_reg			(dqd_mode + 1)
+#define cs_reg			(es_reg + 1)
+#define ss_reg			(cs_reg + 1)
+#define ds_reg			(ss_reg + 1)
+#define fs_reg			(ds_reg + 1)
+#define gs_reg			(fs_reg + 1)
+
+#define eAX_reg			(gs_reg + 1)
+#define eCX_reg			(eAX_reg + 1)
+#define eDX_reg			(eCX_reg + 1)
+#define eBX_reg			(eDX_reg + 1)
+#define eSP_reg			(eBX_reg + 1)
+#define eBP_reg			(eSP_reg + 1)
+#define eSI_reg			(eBP_reg + 1)
+#define eDI_reg			(eSI_reg + 1)
+
+#define al_reg			(eDI_reg + 1)
+#define cl_reg			(al_reg + 1)
+#define dl_reg			(cl_reg + 1)
+#define bl_reg			(dl_reg + 1)
+#define ah_reg			(bl_reg + 1)
+#define ch_reg			(ah_reg + 1)
+#define dh_reg			(ch_reg + 1)
+#define bh_reg			(dh_reg + 1)
+
+#define ax_reg			(bh_reg + 1)
+#define cx_reg			(ax_reg + 1)
+#define dx_reg			(cx_reg + 1)
+#define bx_reg			(dx_reg + 1)
+#define sp_reg			(bx_reg + 1)
+#define bp_reg			(sp_reg + 1)
+#define si_reg			(bp_reg + 1)
+#define di_reg			(si_reg + 1)
+
+#define rAX_reg			(di_reg + 1)
+#define rCX_reg			(rAX_reg + 1)
+#define rDX_reg			(rCX_reg + 1)
+#define rBX_reg			(rDX_reg + 1)
+#define rSP_reg			(rBX_reg + 1)
+#define rBP_reg			(rSP_reg + 1)
+#define rSI_reg			(rBP_reg + 1)
+#define rDI_reg			(rSI_reg + 1)
+
+#define z_mode_ax_reg		(rDI_reg + 1)
+#define indir_dx_reg		(z_mode_ax_reg + 1)
+
+#define MAX_BYTEMODE	indir_dx_reg
+
+/* Flags that are OR'ed into the bytemode field to pass extra
+   information.  */
+#define DREX_OC1		0x10000	/* OC1 bit set */
+#define DREX_NO_OC0		0x20000	/* OC0 bit not used */
+#define DREX_MASK		0x40000	/* mask to delete */
 
-#define z_mode_ax_reg 149
-#define indir_dx_reg 150
+#if MAX_BYTEMODE >= DREX_OC1
+#error MAX_BYTEMODE must be less than DREX_OC1
+#endif
 
 #define FLOATCODE 1
 #define USE_REG_TABLE 2

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-10-10 17:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-29 15:15 PATCH: Update x86 disassembler H.J. Lu
2007-10-10 16:35 H.J. Lu
2007-10-10 17:29 ` Olivier Galibert
2007-10-10 18:11   ` H.J. Lu

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).