6258 lines
170 KiB
Diff
6258 lines
170 KiB
Diff
|
|
From 39fb369834a39e80d9bee9c55f029c543a7d797c Mon Sep 17 00:00:00 2001
|
||
|
|
From: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
|
||
|
|
Date: Tue, 4 Jan 2022 23:07:26 -0800
|
||
|
|
Subject: [PATCH] opcodes: Make i386-dis.c thread-safe
|
||
|
|
|
||
|
|
Improve thread safety in print_insn_i386_att, print_insn_i386_intel and
|
||
|
|
print_insn_i386 by removing the use of static variables.
|
||
|
|
|
||
|
|
Tested on x86_64-pc-linux-gnu.
|
||
|
|
|
||
|
|
2022-01-04 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
|
||
|
|
|
||
|
|
* i386-dis.c: Make print_insn_i386_att, print_insn_i386_intel
|
||
|
|
and print_insn_i386 thread-safe
|
||
|
|
|
||
|
|
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
|
||
|
|
index 08eb810d5df..4e0e1559339 100644
|
||
|
|
--- a/opcodes/i386-dis.c
|
||
|
|
+++ b/opcodes/i386-dis.c
|
||
|
|
@@ -40,81 +40,82 @@
|
||
|
|
#include "safe-ctype.h"
|
||
|
|
|
||
|
|
#include <setjmp.h>
|
||
|
|
-
|
||
|
|
-static int print_insn (bfd_vma, disassemble_info *);
|
||
|
|
-static void dofloat (int);
|
||
|
|
-static void OP_ST (int, int);
|
||
|
|
-static void OP_STi (int, int);
|
||
|
|
-static int putop (const char *, int);
|
||
|
|
-static void oappend (const char *);
|
||
|
|
-static void append_seg (void);
|
||
|
|
-static void OP_indirE (int, int);
|
||
|
|
-static void print_operand_value (char *, int, bfd_vma);
|
||
|
|
-static void OP_E_memory (int, int);
|
||
|
|
-static void print_displacement (char *, bfd_vma);
|
||
|
|
-static void OP_E (int, int);
|
||
|
|
-static void OP_G (int, int);
|
||
|
|
-static bfd_vma get64 (void);
|
||
|
|
-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);
|
||
|
|
-static void OP_I64 (int, int);
|
||
|
|
-static void OP_sI (int, int);
|
||
|
|
-static void OP_J (int, int);
|
||
|
|
-static void OP_SEG (int, int);
|
||
|
|
-static void OP_DIR (int, int);
|
||
|
|
-static void OP_OFF (int, int);
|
||
|
|
-static void OP_OFF64 (int, int);
|
||
|
|
-static void ptr_reg (int, int);
|
||
|
|
-static void OP_ESreg (int, int);
|
||
|
|
-static void OP_DSreg (int, int);
|
||
|
|
-static void OP_C (int, int);
|
||
|
|
-static void OP_D (int, int);
|
||
|
|
-static void OP_T (int, int);
|
||
|
|
-static void OP_MMX (int, int);
|
||
|
|
-static void OP_XMM (int, int);
|
||
|
|
-static void OP_EM (int, int);
|
||
|
|
-static void OP_EX (int, int);
|
||
|
|
-static void OP_EMC (int,int);
|
||
|
|
-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_VEX (int, int);
|
||
|
|
-static void OP_VexR (int, int);
|
||
|
|
-static void OP_VexW (int, int);
|
||
|
|
-static void OP_Rounding (int, int);
|
||
|
|
-static void OP_REG_VexI4 (int, int);
|
||
|
|
-static void OP_VexI4 (int, int);
|
||
|
|
-static void PCLMUL_Fixup (int, int);
|
||
|
|
-static void VPCMP_Fixup (int, int);
|
||
|
|
-static void VPCOM_Fixup (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 CMP_Fixup (int, int);
|
||
|
|
-static void BadOp (void);
|
||
|
|
-static void REP_Fixup (int, int);
|
||
|
|
-static void SEP_Fixup (int, int);
|
||
|
|
-static void BND_Fixup (int, int);
|
||
|
|
-static void NOTRACK_Fixup (int, int);
|
||
|
|
-static void HLE_Fixup1 (int, int);
|
||
|
|
-static void HLE_Fixup2 (int, int);
|
||
|
|
-static void HLE_Fixup3 (int, int);
|
||
|
|
-static void CMPXCHG8B_Fixup (int, int);
|
||
|
|
-static void XMM_Fixup (int, int);
|
||
|
|
-static void FXSAVE_Fixup (int, int);
|
||
|
|
-
|
||
|
|
-static void MOVSXD_Fixup (int, int);
|
||
|
|
-static void DistinctDest_Fixup (int, int);
|
||
|
|
+typedef struct instr_info instr_info;
|
||
|
|
+
|
||
|
|
+static int print_insn (bfd_vma, instr_info *);
|
||
|
|
+static void dofloat (instr_info *, int);
|
||
|
|
+static void OP_ST (instr_info *, int, int);
|
||
|
|
+static void OP_STi (instr_info *, int, int);
|
||
|
|
+static int putop (instr_info *, const char *, int);
|
||
|
|
+static void oappend (instr_info *, const char *);
|
||
|
|
+static void append_seg (instr_info *);
|
||
|
|
+static void OP_indirE (instr_info *, int, int);
|
||
|
|
+static void print_operand_value (instr_info *, char *, int, bfd_vma);
|
||
|
|
+static void OP_E_memory (instr_info *, int, int);
|
||
|
|
+static void print_displacement (instr_info *, char *, bfd_vma);
|
||
|
|
+static void OP_E (instr_info *, int, int);
|
||
|
|
+static void OP_G (instr_info *, int, int);
|
||
|
|
+static bfd_vma get64 (instr_info *);
|
||
|
|
+static bfd_signed_vma get32 (instr_info *);
|
||
|
|
+static bfd_signed_vma get32s (instr_info *);
|
||
|
|
+static int get16 (instr_info *);
|
||
|
|
+static void set_op (instr_info *, bfd_vma, int);
|
||
|
|
+static void OP_Skip_MODRM (instr_info *, int, int);
|
||
|
|
+static void OP_REG (instr_info *, int, int);
|
||
|
|
+static void OP_IMREG (instr_info *, int, int);
|
||
|
|
+static void OP_I (instr_info *, int, int);
|
||
|
|
+static void OP_I64 (instr_info *, int, int);
|
||
|
|
+static void OP_sI (instr_info *, int, int);
|
||
|
|
+static void OP_J (instr_info *, int, int);
|
||
|
|
+static void OP_SEG (instr_info *, int, int);
|
||
|
|
+static void OP_DIR (instr_info *, int, int);
|
||
|
|
+static void OP_OFF (instr_info *, int, int);
|
||
|
|
+static void OP_OFF64 (instr_info *, int, int);
|
||
|
|
+static void ptr_reg (instr_info *, int, int);
|
||
|
|
+static void OP_ESreg (instr_info *, int, int);
|
||
|
|
+static void OP_DSreg (instr_info *, int, int);
|
||
|
|
+static void OP_C (instr_info *, int, int);
|
||
|
|
+static void OP_D (instr_info *, int, int);
|
||
|
|
+static void OP_T (instr_info *, int, int);
|
||
|
|
+static void OP_MMX (instr_info *, int, int);
|
||
|
|
+static void OP_XMM (instr_info *, int, int);
|
||
|
|
+static void OP_EM (instr_info *, int, int);
|
||
|
|
+static void OP_EX (instr_info *, int, int);
|
||
|
|
+static void OP_EMC (instr_info *, int,int);
|
||
|
|
+static void OP_MXC (instr_info *, int,int);
|
||
|
|
+static void OP_MS (instr_info *, int, int);
|
||
|
|
+static void OP_XS (instr_info *, int, int);
|
||
|
|
+static void OP_M (instr_info *, int, int);
|
||
|
|
+static void OP_VEX (instr_info *, int, int);
|
||
|
|
+static void OP_VexR (instr_info *, int, int);
|
||
|
|
+static void OP_VexW (instr_info *, int, int);
|
||
|
|
+static void OP_Rounding (instr_info *, int, int);
|
||
|
|
+static void OP_REG_VexI4 (instr_info *, int, int);
|
||
|
|
+static void OP_VexI4 (instr_info *, int, int);
|
||
|
|
+static void PCLMUL_Fixup (instr_info *, int, int);
|
||
|
|
+static void VPCMP_Fixup (instr_info *, int, int);
|
||
|
|
+static void VPCOM_Fixup (instr_info *, int, int);
|
||
|
|
+static void OP_0f07 (instr_info *, int, int);
|
||
|
|
+static void OP_Monitor (instr_info *, int, int);
|
||
|
|
+static void OP_Mwait (instr_info *, int, int);
|
||
|
|
+static void NOP_Fixup1 (instr_info *, int, int);
|
||
|
|
+static void NOP_Fixup2 (instr_info *, int, int);
|
||
|
|
+static void OP_3DNowSuffix (instr_info *, int, int);
|
||
|
|
+static void CMP_Fixup (instr_info *, int, int);
|
||
|
|
+static void BadOp (instr_info *);
|
||
|
|
+static void REP_Fixup (instr_info *, int, int);
|
||
|
|
+static void SEP_Fixup (instr_info *, int, int);
|
||
|
|
+static void BND_Fixup (instr_info *, int, int);
|
||
|
|
+static void NOTRACK_Fixup (instr_info *, int, int);
|
||
|
|
+static void HLE_Fixup1 (instr_info *, int, int);
|
||
|
|
+static void HLE_Fixup2 (instr_info *, int, int);
|
||
|
|
+static void HLE_Fixup3 (instr_info *, int, int);
|
||
|
|
+static void CMPXCHG8B_Fixup (instr_info *, int, int);
|
||
|
|
+static void XMM_Fixup (instr_info *, int, int);
|
||
|
|
+static void FXSAVE_Fixup (instr_info *, int, int);
|
||
|
|
+
|
||
|
|
+static void MOVSXD_Fixup (instr_info *, int, int);
|
||
|
|
+static void DistinctDest_Fixup (instr_info *, int, int);
|
||
|
|
|
||
|
|
struct dis_private {
|
||
|
|
/* Points to first byte not fetched. */
|
||
|
|
@@ -132,15 +133,137 @@ enum address_mode
|
||
|
|
mode_64bit
|
||
|
|
};
|
||
|
|
|
||
|
|
-enum address_mode address_mode;
|
||
|
|
+enum x86_64_isa
|
||
|
|
+{
|
||
|
|
+ amd64 = 1,
|
||
|
|
+ intel64
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+struct instr_info
|
||
|
|
+{
|
||
|
|
+ enum address_mode address_mode;
|
||
|
|
+
|
||
|
|
+ /* Flags for the prefixes for the current instruction. See below. */
|
||
|
|
+ int prefixes;
|
||
|
|
+
|
||
|
|
+ /* REX prefix the current instruction. See below. */
|
||
|
|
+ int rex;
|
||
|
|
+ /* Bits of REX we've already used. */
|
||
|
|
+ int rex_used;
|
||
|
|
+
|
||
|
|
+ /* Flags for ins->prefixes which we somehow handled when printing the
|
||
|
|
+ current instruction. */
|
||
|
|
+ int used_prefixes;
|
||
|
|
+
|
||
|
|
+ /* Flags for EVEX bits which we somehow handled when printing the
|
||
|
|
+ current instruction. */
|
||
|
|
+ int evex_used;
|
||
|
|
+
|
||
|
|
+ char obuf[100];
|
||
|
|
+ char *obufp;
|
||
|
|
+ char *mnemonicendp;
|
||
|
|
+ char scratchbuf[100];
|
||
|
|
+ unsigned char *start_codep;
|
||
|
|
+ unsigned char *insn_codep;
|
||
|
|
+ unsigned char *codep;
|
||
|
|
+ unsigned char *end_codep;
|
||
|
|
+ int last_lock_prefix;
|
||
|
|
+ int last_repz_prefix;
|
||
|
|
+ int last_repnz_prefix;
|
||
|
|
+ int last_data_prefix;
|
||
|
|
+ int last_addr_prefix;
|
||
|
|
+ int last_rex_prefix;
|
||
|
|
+ int last_seg_prefix;
|
||
|
|
+ int fwait_prefix;
|
||
|
|
+ /* The active segment register prefix. */
|
||
|
|
+ int active_seg_prefix;
|
||
|
|
+
|
||
|
|
+#define MAX_CODE_LENGTH 15
|
||
|
|
+ /* We can up to 14 ins->prefixes since the maximum instruction length is
|
||
|
|
+ 15bytes. */
|
||
|
|
+ int all_prefixes[MAX_CODE_LENGTH - 1];
|
||
|
|
+ disassemble_info *info;
|
||
|
|
+
|
||
|
|
+ struct
|
||
|
|
+ {
|
||
|
|
+ int mod;
|
||
|
|
+ int reg;
|
||
|
|
+ int rm;
|
||
|
|
+ }
|
||
|
|
+ modrm;
|
||
|
|
+ unsigned char need_modrm;
|
||
|
|
+
|
||
|
|
+ struct
|
||
|
|
+ {
|
||
|
|
+ int scale;
|
||
|
|
+ int index;
|
||
|
|
+ int base;
|
||
|
|
+ }
|
||
|
|
+ sib;
|
||
|
|
+
|
||
|
|
+ struct
|
||
|
|
+ {
|
||
|
|
+ int register_specifier;
|
||
|
|
+ int length;
|
||
|
|
+ int prefix;
|
||
|
|
+ int w;
|
||
|
|
+ int evex;
|
||
|
|
+ int r;
|
||
|
|
+ int v;
|
||
|
|
+ int mask_register_specifier;
|
||
|
|
+ int zeroing;
|
||
|
|
+ int ll;
|
||
|
|
+ int b;
|
||
|
|
+ int no_broadcast;
|
||
|
|
+ }
|
||
|
|
+ vex;
|
||
|
|
+ unsigned char need_vex;
|
||
|
|
+
|
||
|
|
+ const char **names64;
|
||
|
|
+ const char **names32;
|
||
|
|
+ const char **names16;
|
||
|
|
+ const char **names8;
|
||
|
|
+ const char **names8rex;
|
||
|
|
+ const char **names_seg;
|
||
|
|
+ const char *index64;
|
||
|
|
+ const char *index32;
|
||
|
|
+ const char **index16;
|
||
|
|
+ const char **names_bnd;
|
||
|
|
+ const char **names_mm;
|
||
|
|
+ const char **names_xmm;
|
||
|
|
+ const char **names_ymm;
|
||
|
|
+ const char **names_zmm;
|
||
|
|
+ const char **names_tmm;
|
||
|
|
+ const char **names_mask;
|
||
|
|
+
|
||
|
|
+ /* Remember if the current op is a jump instruction. */
|
||
|
|
+ bool op_is_jump;
|
||
|
|
+
|
||
|
|
+ char op_out[MAX_OPERANDS][100];
|
||
|
|
+ int op_ad, op_index[MAX_OPERANDS];
|
||
|
|
+ int two_source_ops;
|
||
|
|
+ bfd_vma op_address[MAX_OPERANDS];
|
||
|
|
+ bfd_vma op_riprel[MAX_OPERANDS];
|
||
|
|
+ bfd_vma start_pc;
|
||
|
|
+
|
||
|
|
+ /* On the 386's of 1988, the maximum length of an instruction is 15 bytes.
|
||
|
|
+ * (see topic "Redundant ins->prefixes" in the "Differences from 8086"
|
||
|
|
+ * section of the "Virtual 8086 Mode" chapter.)
|
||
|
|
+ * 'pc' should be the address of this instruction, it will
|
||
|
|
+ * be used to print the target address if this is a relative jump or call
|
||
|
|
+ * The function returns the length of this instruction in bytes.
|
||
|
|
+ */
|
||
|
|
+ char intel_syntax;
|
||
|
|
+ char intel_mnemonic;
|
||
|
|
+ char open_char;
|
||
|
|
+ char close_char;
|
||
|
|
+ char separator_char;
|
||
|
|
+ char scale_char;
|
||
|
|
+
|
||
|
|
+ enum x86_64_isa isa64;
|
||
|
|
|
||
|
|
-/* Flags for the prefixes for the current instruction. See below. */
|
||
|
|
-static int prefixes;
|
||
|
|
+};
|
||
|
|
|
||
|
|
-/* REX prefix the current instruction. See below. */
|
||
|
|
-static int rex;
|
||
|
|
-/* Bits of REX we've already used. */
|
||
|
|
-static int rex_used;
|
||
|
|
/* Mark parts used in the REX prefix. When we are testing for
|
||
|
|
empty prefix (for 8bit register REX extension), just mask it
|
||
|
|
out. Otherwise test for REX bit is excuse for existence of REX
|
||
|
|
@@ -149,21 +272,15 @@ static int rex_used;
|
||
|
|
{ \
|
||
|
|
if (value) \
|
||
|
|
{ \
|
||
|
|
- if ((rex & value)) \
|
||
|
|
- rex_used |= (value) | REX_OPCODE; \
|
||
|
|
+ if ((ins->rex & value)) \
|
||
|
|
+ ins->rex_used |= (value) | REX_OPCODE; \
|
||
|
|
} \
|
||
|
|
else \
|
||
|
|
- rex_used |= REX_OPCODE; \
|
||
|
|
+ ins->rex_used |= REX_OPCODE; \
|
||
|
|
}
|
||
|
|
|
||
|
|
-/* Flags for prefixes which we somehow handled when printing the
|
||
|
|
- current instruction. */
|
||
|
|
-static int used_prefixes;
|
||
|
|
|
||
|
|
-/* Flags for EVEX bits which we somehow handled when printing the
|
||
|
|
- current instruction. */
|
||
|
|
#define EVEX_b_used 1
|
||
|
|
-static int evex_used;
|
||
|
|
|
||
|
|
/* Flags stored in PREFIXES. */
|
||
|
|
#define PREFIX_REPZ 1
|
||
|
|
@@ -1665,7 +1782,7 @@ enum
|
||
|
|
EVEX_W_MAP6_13_P_2,
|
||
|
|
};
|
||
|
|
|
||
|
|
-typedef void (*op_rtn) (int bytemode, int sizeflag);
|
||
|
|
+typedef void (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
|
||
|
|
|
||
|
|
struct dis386 {
|
||
|
|
const char *name;
|
||
|
|
@@ -2371,61 +2488,6 @@ static const unsigned char twobyte_has_modrm[256] = {
|
||
|
|
/* 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 *mnemonicendp;
|
||
|
|
-static char scratchbuf[100];
|
||
|
|
-static unsigned char *start_codep;
|
||
|
|
-static unsigned char *insn_codep;
|
||
|
|
-static unsigned char *codep;
|
||
|
|
-static unsigned char *end_codep;
|
||
|
|
-static int last_lock_prefix;
|
||
|
|
-static int last_repz_prefix;
|
||
|
|
-static int last_repnz_prefix;
|
||
|
|
-static int last_data_prefix;
|
||
|
|
-static int last_addr_prefix;
|
||
|
|
-static int last_rex_prefix;
|
||
|
|
-static int last_seg_prefix;
|
||
|
|
-static int fwait_prefix;
|
||
|
|
-/* The active segment register prefix. */
|
||
|
|
-static int active_seg_prefix;
|
||
|
|
-#define MAX_CODE_LENGTH 15
|
||
|
|
-/* We can up to 14 prefixes since the maximum instruction length is
|
||
|
|
- 15bytes. */
|
||
|
|
-static int all_prefixes[MAX_CODE_LENGTH - 1];
|
||
|
|
-static disassemble_info *the_info;
|
||
|
|
-static struct
|
||
|
|
- {
|
||
|
|
- int mod;
|
||
|
|
- int reg;
|
||
|
|
- int rm;
|
||
|
|
- }
|
||
|
|
-modrm;
|
||
|
|
-static unsigned char need_modrm;
|
||
|
|
-static struct
|
||
|
|
- {
|
||
|
|
- int scale;
|
||
|
|
- int index;
|
||
|
|
- int base;
|
||
|
|
- }
|
||
|
|
-sib;
|
||
|
|
-static struct
|
||
|
|
- {
|
||
|
|
- int register_specifier;
|
||
|
|
- int length;
|
||
|
|
- int prefix;
|
||
|
|
- int w;
|
||
|
|
- int evex;
|
||
|
|
- int r;
|
||
|
|
- int v;
|
||
|
|
- int mask_register_specifier;
|
||
|
|
- int zeroing;
|
||
|
|
- int ll;
|
||
|
|
- int b;
|
||
|
|
- int no_broadcast;
|
||
|
|
- }
|
||
|
|
-vex;
|
||
|
|
-static unsigned char need_vex;
|
||
|
|
|
||
|
|
struct op
|
||
|
|
{
|
||
|
|
@@ -2436,18 +2498,7 @@ struct op
|
||
|
|
/* If we are accessing mod/rm/reg without need_modrm set, then the
|
||
|
|
values are stale. Hitting this abort likely indicates that you
|
||
|
|
need to update onebyte_has_modrm or twobyte_has_modrm. */
|
||
|
|
-#define MODRM_CHECK if (!need_modrm) abort ()
|
||
|
|
-
|
||
|
|
-static const char **names64;
|
||
|
|
-static const char **names32;
|
||
|
|
-static const char **names16;
|
||
|
|
-static const char **names8;
|
||
|
|
-static const char **names8rex;
|
||
|
|
-static const char **names_seg;
|
||
|
|
-static const char *index64;
|
||
|
|
-static const char *index32;
|
||
|
|
-static const char **index16;
|
||
|
|
-static const char **names_bnd;
|
||
|
|
+#define MODRM_CHECK if (!ins->need_modrm) abort ()
|
||
|
|
|
||
|
|
static const char *intel_names64[] = {
|
||
|
|
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
|
||
|
|
@@ -2505,7 +2556,6 @@ static const char *att_index16[] = {
|
||
|
|
"%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_mm;
|
||
|
|
static const char *intel_names_mm[] = {
|
||
|
|
"mm0", "mm1", "mm2", "mm3",
|
||
|
|
"mm4", "mm5", "mm6", "mm7"
|
||
|
|
@@ -2523,7 +2573,6 @@ static const char *att_names_bnd[] = {
|
||
|
|
"%bnd0", "%bnd1", "%bnd2", "%bnd3"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_xmm;
|
||
|
|
static const char *intel_names_xmm[] = {
|
||
|
|
"xmm0", "xmm1", "xmm2", "xmm3",
|
||
|
|
"xmm4", "xmm5", "xmm6", "xmm7",
|
||
|
|
@@ -2545,7 +2594,6 @@ static const char *att_names_xmm[] = {
|
||
|
|
"%xmm28", "%xmm29", "%xmm30", "%xmm31"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_ymm;
|
||
|
|
static const char *intel_names_ymm[] = {
|
||
|
|
"ymm0", "ymm1", "ymm2", "ymm3",
|
||
|
|
"ymm4", "ymm5", "ymm6", "ymm7",
|
||
|
|
@@ -2567,7 +2615,6 @@ static const char *att_names_ymm[] = {
|
||
|
|
"%ymm28", "%ymm29", "%ymm30", "%ymm31"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_zmm;
|
||
|
|
static const char *intel_names_zmm[] = {
|
||
|
|
"zmm0", "zmm1", "zmm2", "zmm3",
|
||
|
|
"zmm4", "zmm5", "zmm6", "zmm7",
|
||
|
|
@@ -2589,7 +2636,6 @@ static const char *att_names_zmm[] = {
|
||
|
|
"%zmm28", "%zmm29", "%zmm30", "%zmm31"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_tmm;
|
||
|
|
static const char *intel_names_tmm[] = {
|
||
|
|
"tmm0", "tmm1", "tmm2", "tmm3",
|
||
|
|
"tmm4", "tmm5", "tmm6", "tmm7"
|
||
|
|
@@ -2599,7 +2645,6 @@ static const char *att_names_tmm[] = {
|
||
|
|
"%tmm4", "%tmm5", "%tmm6", "%tmm7"
|
||
|
|
};
|
||
|
|
|
||
|
|
-static const char **names_mask;
|
||
|
|
static const char *intel_names_mask[] = {
|
||
|
|
"k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7"
|
||
|
|
};
|
||
|
|
@@ -8650,37 +8695,34 @@ static const struct dis386 rm_table[][8] = {
|
||
|
|
#define BND_PREFIX (0xf2 | 0x400)
|
||
|
|
#define NOTRACK_PREFIX (0x3e | 0x100)
|
||
|
|
|
||
|
|
-/* Remember if the current op is a jump instruction. */
|
||
|
|
-static bool op_is_jump = false;
|
||
|
|
-
|
||
|
|
static int
|
||
|
|
-ckprefix (void)
|
||
|
|
+ckprefix (instr_info *ins)
|
||
|
|
{
|
||
|
|
int newrex, i, length;
|
||
|
|
- rex = 0;
|
||
|
|
- prefixes = 0;
|
||
|
|
- used_prefixes = 0;
|
||
|
|
- rex_used = 0;
|
||
|
|
- evex_used = 0;
|
||
|
|
- last_lock_prefix = -1;
|
||
|
|
- last_repz_prefix = -1;
|
||
|
|
- last_repnz_prefix = -1;
|
||
|
|
- last_data_prefix = -1;
|
||
|
|
- last_addr_prefix = -1;
|
||
|
|
- last_rex_prefix = -1;
|
||
|
|
- last_seg_prefix = -1;
|
||
|
|
- fwait_prefix = -1;
|
||
|
|
- active_seg_prefix = 0;
|
||
|
|
- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
|
||
|
|
- all_prefixes[i] = 0;
|
||
|
|
+ ins->rex = 0;
|
||
|
|
+ ins->prefixes = 0;
|
||
|
|
+ ins->used_prefixes = 0;
|
||
|
|
+ ins->rex_used = 0;
|
||
|
|
+ ins->evex_used = 0;
|
||
|
|
+ ins->last_lock_prefix = -1;
|
||
|
|
+ ins->last_repz_prefix = -1;
|
||
|
|
+ ins->last_repnz_prefix = -1;
|
||
|
|
+ ins->last_data_prefix = -1;
|
||
|
|
+ ins->last_addr_prefix = -1;
|
||
|
|
+ ins->last_rex_prefix = -1;
|
||
|
|
+ ins->last_seg_prefix = -1;
|
||
|
|
+ ins->fwait_prefix = -1;
|
||
|
|
+ ins->active_seg_prefix = 0;
|
||
|
|
+ for (i = 0; i < (int) ARRAY_SIZE (ins->all_prefixes); i++)
|
||
|
|
+ ins->all_prefixes[i] = 0;
|
||
|
|
i = 0;
|
||
|
|
length = 0;
|
||
|
|
/* The maximum instruction length is 15bytes. */
|
||
|
|
while (length < MAX_CODE_LENGTH - 1)
|
||
|
|
{
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
newrex = 0;
|
||
|
|
- switch (*codep)
|
||
|
|
+ switch (*ins->codep)
|
||
|
|
{
|
||
|
|
/* REX prefixes family. */
|
||
|
|
case 0x40:
|
||
|
|
@@ -8699,103 +8741,95 @@ ckprefix (void)
|
||
|
|
case 0x4d:
|
||
|
|
case 0x4e:
|
||
|
|
case 0x4f:
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
- newrex = *codep;
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
+ newrex = *ins->codep;
|
||
|
|
else
|
||
|
|
return 1;
|
||
|
|
- last_rex_prefix = i;
|
||
|
|
+ ins->last_rex_prefix = i;
|
||
|
|
break;
|
||
|
|
case 0xf3:
|
||
|
|
- prefixes |= PREFIX_REPZ;
|
||
|
|
- last_repz_prefix = i;
|
||
|
|
+ ins->prefixes |= PREFIX_REPZ;
|
||
|
|
+ ins->last_repz_prefix = i;
|
||
|
|
break;
|
||
|
|
case 0xf2:
|
||
|
|
- prefixes |= PREFIX_REPNZ;
|
||
|
|
- last_repnz_prefix = i;
|
||
|
|
+ ins->prefixes |= PREFIX_REPNZ;
|
||
|
|
+ ins->last_repnz_prefix = i;
|
||
|
|
break;
|
||
|
|
case 0xf0:
|
||
|
|
- prefixes |= PREFIX_LOCK;
|
||
|
|
- last_lock_prefix = i;
|
||
|
|
+ ins->prefixes |= PREFIX_LOCK;
|
||
|
|
+ ins->last_lock_prefix = i;
|
||
|
|
break;
|
||
|
|
case 0x2e:
|
||
|
|
- prefixes |= PREFIX_CS;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
-
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
- active_seg_prefix = PREFIX_CS;
|
||
|
|
-
|
||
|
|
+ ins->prefixes |= PREFIX_CS;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
+ ins->active_seg_prefix = PREFIX_CS;
|
||
|
|
break;
|
||
|
|
case 0x36:
|
||
|
|
- prefixes |= PREFIX_SS;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
-
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
- active_seg_prefix = PREFIX_SS;
|
||
|
|
-
|
||
|
|
+ ins->prefixes |= PREFIX_SS;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
+ ins->active_seg_prefix = PREFIX_SS;
|
||
|
|
break;
|
||
|
|
case 0x3e:
|
||
|
|
- prefixes |= PREFIX_DS;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
-
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
- active_seg_prefix = PREFIX_DS;
|
||
|
|
-
|
||
|
|
+ ins->prefixes |= PREFIX_DS;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
+ ins->active_seg_prefix = PREFIX_DS;
|
||
|
|
break;
|
||
|
|
case 0x26:
|
||
|
|
- prefixes |= PREFIX_ES;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
-
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
- active_seg_prefix = PREFIX_ES;
|
||
|
|
-
|
||
|
|
+ ins->prefixes |= PREFIX_ES;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
+ ins->active_seg_prefix = PREFIX_ES;
|
||
|
|
break;
|
||
|
|
case 0x64:
|
||
|
|
- prefixes |= PREFIX_FS;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
- active_seg_prefix = PREFIX_FS;
|
||
|
|
+ ins->prefixes |= PREFIX_FS;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ ins->active_seg_prefix = PREFIX_FS;
|
||
|
|
break;
|
||
|
|
case 0x65:
|
||
|
|
- prefixes |= PREFIX_GS;
|
||
|
|
- last_seg_prefix = i;
|
||
|
|
- active_seg_prefix = PREFIX_GS;
|
||
|
|
+ ins->prefixes |= PREFIX_GS;
|
||
|
|
+ ins->last_seg_prefix = i;
|
||
|
|
+ ins->active_seg_prefix = PREFIX_GS;
|
||
|
|
break;
|
||
|
|
case 0x66:
|
||
|
|
- prefixes |= PREFIX_DATA;
|
||
|
|
- last_data_prefix = i;
|
||
|
|
+ ins->prefixes |= PREFIX_DATA;
|
||
|
|
+ ins->last_data_prefix = i;
|
||
|
|
break;
|
||
|
|
case 0x67:
|
||
|
|
- prefixes |= PREFIX_ADDR;
|
||
|
|
- last_addr_prefix = i;
|
||
|
|
+ ins->prefixes |= PREFIX_ADDR;
|
||
|
|
+ ins->last_addr_prefix = i;
|
||
|
|
break;
|
||
|
|
case FWAIT_OPCODE:
|
||
|
|
/* fwait is really an instruction. If there are prefixes
|
||
|
|
before the fwait, they belong to the fwait, *not* to the
|
||
|
|
following instruction. */
|
||
|
|
- fwait_prefix = i;
|
||
|
|
- if (prefixes || rex)
|
||
|
|
+ ins->fwait_prefix = i;
|
||
|
|
+ if (ins->prefixes || ins->rex)
|
||
|
|
{
|
||
|
|
- prefixes |= PREFIX_FWAIT;
|
||
|
|
- codep++;
|
||
|
|
+ ins->prefixes |= PREFIX_FWAIT;
|
||
|
|
+ ins->codep++;
|
||
|
|
/* This ensures that the previous REX prefixes are noticed
|
||
|
|
as unused prefixes, as in the return case below. */
|
||
|
|
- rex_used = rex;
|
||
|
|
+ ins->rex_used = ins->rex;
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
- prefixes = PREFIX_FWAIT;
|
||
|
|
+ ins->prefixes = PREFIX_FWAIT;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
/* Rex is ignored when followed by another prefix. */
|
||
|
|
- if (rex)
|
||
|
|
+ if (ins->rex)
|
||
|
|
{
|
||
|
|
- rex_used = rex;
|
||
|
|
+ ins->rex_used = ins->rex;
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
- if (*codep != FWAIT_OPCODE)
|
||
|
|
- all_prefixes[i++] = *codep;
|
||
|
|
- rex = newrex;
|
||
|
|
- codep++;
|
||
|
|
+ if (*ins->codep != FWAIT_OPCODE)
|
||
|
|
+ ins->all_prefixes[i++] = *ins->codep;
|
||
|
|
+ ins->rex = newrex;
|
||
|
|
+ ins->codep++;
|
||
|
|
length++;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
@@ -8805,7 +8839,7 @@ ckprefix (void)
|
||
|
|
prefix byte. */
|
||
|
|
|
||
|
|
static const char *
|
||
|
|
-prefix_name (int pref, int sizeflag)
|
||
|
|
+prefix_name (instr_info *ins, int pref, int sizeflag)
|
||
|
|
{
|
||
|
|
static const char *rexes [16] =
|
||
|
|
{
|
||
|
|
@@ -8868,7 +8902,7 @@ prefix_name (int pref, int sizeflag)
|
||
|
|
case 0x66:
|
||
|
|
return (sizeflag & DFLAG) ? "data16" : "data32";
|
||
|
|
case 0x67:
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
return (sizeflag & AFLAG) ? "addr32" : "addr64";
|
||
|
|
else
|
||
|
|
return (sizeflag & AFLAG) ? "addr16" : "addr32";
|
||
|
|
@@ -8889,62 +8923,37 @@ prefix_name (int pref, int sizeflag)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-static char op_out[MAX_OPERANDS][100];
|
||
|
|
-static int op_ad, op_index[MAX_OPERANDS];
|
||
|
|
-static int two_source_ops;
|
||
|
|
-static bfd_vma op_address[MAX_OPERANDS];
|
||
|
|
-static bfd_vma op_riprel[MAX_OPERANDS];
|
||
|
|
-static bfd_vma start_pc;
|
||
|
|
-
|
||
|
|
-/*
|
||
|
|
- * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
|
||
|
|
- * (see topic "Redundant prefixes" in the "Differences from 8086"
|
||
|
|
- * section of the "Virtual 8086 Mode" chapter.)
|
||
|
|
- * 'pc' should be the address of this instruction, it will
|
||
|
|
- * be used to print the target address if this is a relative jump or call
|
||
|
|
- * The function returns the length of this instruction in bytes.
|
||
|
|
- */
|
||
|
|
-
|
||
|
|
-static char intel_syntax;
|
||
|
|
-static char intel_mnemonic = !SYSV386_COMPAT;
|
||
|
|
-static char open_char;
|
||
|
|
-static char close_char;
|
||
|
|
-static char separator_char;
|
||
|
|
-static char scale_char;
|
||
|
|
-
|
||
|
|
-enum x86_64_isa
|
||
|
|
-{
|
||
|
|
- amd64 = 1,
|
||
|
|
- intel64
|
||
|
|
-};
|
||
|
|
-
|
||
|
|
-static enum x86_64_isa isa64;
|
||
|
|
-
|
||
|
|
/* Here for backwards compatibility. When gdb stops using
|
||
|
|
print_insn_i386_att and print_insn_i386_intel these functions can
|
||
|
|
disappear, and print_insn_i386 be merged into print_insn. */
|
||
|
|
int
|
||
|
|
print_insn_i386_att (bfd_vma pc, disassemble_info *info)
|
||
|
|
{
|
||
|
|
- intel_syntax = 0;
|
||
|
|
+ instr_info ins;
|
||
|
|
+ ins.info = info;
|
||
|
|
+ ins.intel_syntax = 0;
|
||
|
|
|
||
|
|
- return print_insn (pc, info);
|
||
|
|
+ return print_insn (pc, &ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
int
|
||
|
|
print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
|
||
|
|
{
|
||
|
|
- intel_syntax = 1;
|
||
|
|
+ instr_info ins;
|
||
|
|
+ ins.info = info;
|
||
|
|
+ ins.intel_syntax = 1;
|
||
|
|
|
||
|
|
- return print_insn (pc, info);
|
||
|
|
+ return print_insn (pc, &ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
int
|
||
|
|
print_insn_i386 (bfd_vma pc, disassemble_info *info)
|
||
|
|
{
|
||
|
|
- intel_syntax = -1;
|
||
|
|
+ instr_info ins;
|
||
|
|
+ ins.info = info;
|
||
|
|
+ ins.intel_syntax = -1;
|
||
|
|
|
||
|
|
- return print_insn (pc, info);
|
||
|
|
+ return print_insn (pc, &ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
@@ -8979,7 +8988,7 @@ static const struct dis386 bad_opcode = { "(bad)", { XX }, 0 };
|
||
|
|
/* Get a pointer to struct dis386 with a valid name. */
|
||
|
|
|
||
|
|
static const struct dis386 *
|
||
|
|
-get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
+get_valid_dis386 (const struct dis386 *dp, instr_info *ins)
|
||
|
|
{
|
||
|
|
int vindex, vex_table_index;
|
||
|
|
|
||
|
|
@@ -8989,23 +8998,23 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
switch (dp->op[0].bytemode)
|
||
|
|
{
|
||
|
|
case USE_REG_TABLE:
|
||
|
|
- dp = ®_table[dp->op[1].bytemode][modrm.reg];
|
||
|
|
+ dp = ®_table[dp->op[1].bytemode][ins->modrm.reg];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_MOD_TABLE:
|
||
|
|
- vindex = modrm.mod == 0x3 ? 1 : 0;
|
||
|
|
+ vindex = ins->modrm.mod == 0x3 ? 1 : 0;
|
||
|
|
dp = &mod_table[dp->op[1].bytemode][vindex];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_RM_TABLE:
|
||
|
|
- dp = &rm_table[dp->op[1].bytemode][modrm.rm];
|
||
|
|
+ dp = &rm_table[dp->op[1].bytemode][ins->modrm.rm];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_PREFIX_TABLE:
|
||
|
|
- if (need_vex)
|
||
|
|
+ if (ins->need_vex)
|
||
|
|
{
|
||
|
|
/* The prefix in VEX is implicit. */
|
||
|
|
- switch (vex.prefix)
|
||
|
|
+ switch (ins->vex.prefix)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
vindex = 0;
|
||
|
|
@@ -9032,19 +9041,19 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
/* We check PREFIX_REPNZ and PREFIX_REPZ before PREFIX_DATA.
|
||
|
|
When there are multiple PREFIX_REPNZ and PREFIX_REPZ, the
|
||
|
|
last one wins. */
|
||
|
|
- if ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
|
||
|
|
+ if ((ins->prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
|
||
|
|
{
|
||
|
|
- if (last_repz_prefix > last_repnz_prefix)
|
||
|
|
+ if (ins->last_repz_prefix > ins->last_repnz_prefix)
|
||
|
|
{
|
||
|
|
vindex = 1;
|
||
|
|
prefix = PREFIX_REPZ;
|
||
|
|
- last_prefix = last_repz_prefix;
|
||
|
|
+ last_prefix = ins->last_repz_prefix;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
vindex = 3;
|
||
|
|
prefix = PREFIX_REPNZ;
|
||
|
|
- last_prefix = last_repnz_prefix;
|
||
|
|
+ last_prefix = ins->last_repnz_prefix;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check if prefix should be ignored. */
|
||
|
|
@@ -9055,42 +9064,42 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
vindex = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (vindex == 0 && (prefixes & PREFIX_DATA) != 0)
|
||
|
|
+ if (vindex == 0 && (ins->prefixes & PREFIX_DATA) != 0)
|
||
|
|
{
|
||
|
|
vindex = 2;
|
||
|
|
prefix = PREFIX_DATA;
|
||
|
|
- last_prefix = last_data_prefix;
|
||
|
|
+ last_prefix = ins->last_data_prefix;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vindex != 0)
|
||
|
|
{
|
||
|
|
- used_prefixes |= prefix;
|
||
|
|
- all_prefixes[last_prefix] = 0;
|
||
|
|
+ ins->used_prefixes |= prefix;
|
||
|
|
+ ins->all_prefixes[last_prefix] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
dp = &prefix_table[dp->op[1].bytemode][vindex];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_X86_64_TABLE:
|
||
|
|
- vindex = address_mode == mode_64bit ? 1 : 0;
|
||
|
|
+ vindex = ins->address_mode == mode_64bit ? 1 : 0;
|
||
|
|
dp = &x86_64_table[dp->op[1].bytemode][vindex];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_3BYTE_TABLE:
|
||
|
|
- FETCH_DATA (info, codep + 2);
|
||
|
|
- vindex = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 2);
|
||
|
|
+ vindex = *ins->codep++;
|
||
|
|
dp = &three_byte_table[dp->op[1].bytemode][vindex];
|
||
|
|
- end_codep = codep;
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_VEX_LEN_TABLE:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
vindex = 0;
|
||
|
|
@@ -9098,7 +9107,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
case 512:
|
||
|
|
/* This allows re-using in particular table entries where only
|
||
|
|
128-bit operand size (VEX.L=0 / EVEX.L'L=0) are valid. */
|
||
|
|
- if (vex.evex)
|
||
|
|
+ if (ins->vex.evex)
|
||
|
|
{
|
||
|
|
case 256:
|
||
|
|
vindex = 1;
|
||
|
|
@@ -9114,10 +9123,10 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_EVEX_LEN_TABLE:
|
||
|
|
- if (!vex.evex)
|
||
|
|
+ if (!ins->vex.evex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
vindex = 0;
|
||
|
|
@@ -9137,11 +9146,11 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_XOP_8F_TABLE:
|
||
|
|
- FETCH_DATA (info, codep + 3);
|
||
|
|
- rex = ~(*codep >> 5) & 0x7;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 3);
|
||
|
|
+ ins->rex = ~(*ins->codep >> 5) & 0x7;
|
||
|
|
|
||
|
|
/* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm". */
|
||
|
|
- switch ((*codep & 0x1f))
|
||
|
|
+ switch ((*ins->codep & 0x1f))
|
||
|
|
{
|
||
|
|
default:
|
||
|
|
dp = &bad_opcode;
|
||
|
|
@@ -9156,55 +9165,55 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
vex_table_index = XOP_0A;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- codep++;
|
||
|
|
- vex.w = *codep & 0x80;
|
||
|
|
- if (vex.w && address_mode == mode_64bit)
|
||
|
|
- rex |= REX_W;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ ins->vex.w = *ins->codep & 0x80;
|
||
|
|
+ if (ins->vex.w && ins->address_mode == mode_64bit)
|
||
|
|
+ ins->rex |= REX_W;
|
||
|
|
|
||
|
|
- vex.register_specifier = (~(*codep >> 3)) & 0xf;
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ ins->vex.register_specifier = (~(*ins->codep >> 3)) & 0xf;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
{
|
||
|
|
/* In 16/32-bit mode REX_B is silently ignored. */
|
||
|
|
- rex &= ~REX_B;
|
||
|
|
+ ins->rex &= ~REX_B;
|
||
|
|
}
|
||
|
|
|
||
|
|
- vex.length = (*codep & 0x4) ? 256 : 128;
|
||
|
|
- switch ((*codep & 0x3))
|
||
|
|
+ ins->vex.length = (*ins->codep & 0x4) ? 256 : 128;
|
||
|
|
+ switch ((*ins->codep & 0x3))
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
- vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- need_vex = 1;
|
||
|
|
- codep++;
|
||
|
|
- vindex = *codep++;
|
||
|
|
+ ins->need_vex = 1;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ vindex = *ins->codep++;
|
||
|
|
dp = &xop_table[vex_table_index][vindex];
|
||
|
|
|
||
|
|
- end_codep = codep;
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
|
||
|
|
/* No XOP encoding so far allows for a non-zero embedded prefix. Avoid
|
||
|
|
having to decode the bits for every otherwise valid encoding. */
|
||
|
|
- if (vex.prefix)
|
||
|
|
+ if (ins->vex.prefix)
|
||
|
|
return &bad_opcode;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_VEX_C4_TABLE:
|
||
|
|
/* VEX prefix. */
|
||
|
|
- FETCH_DATA (info, codep + 3);
|
||
|
|
- rex = ~(*codep >> 5) & 0x7;
|
||
|
|
- switch ((*codep & 0x1f))
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 3);
|
||
|
|
+ ins->rex = ~(*ins->codep >> 5) & 0x7;
|
||
|
|
+ switch ((*ins->codep & 0x1f))
|
||
|
|
{
|
||
|
|
default:
|
||
|
|
dp = &bad_opcode;
|
||
|
|
@@ -9219,105 +9228,105 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
vex_table_index = VEX_0F3A;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- codep++;
|
||
|
|
- vex.w = *codep & 0x80;
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ ins->codep++;
|
||
|
|
+ ins->vex.w = *ins->codep & 0x80;
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
- if (vex.w)
|
||
|
|
- rex |= REX_W;
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ ins->rex |= REX_W;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* For the 3-byte VEX prefix in 32-bit mode, the REX_B bit
|
||
|
|
is ignored, other REX bits are 0 and the highest bit in
|
||
|
|
VEX.vvvv is also ignored (but we mustn't clear it here). */
|
||
|
|
- rex = 0;
|
||
|
|
+ ins->rex = 0;
|
||
|
|
}
|
||
|
|
- vex.register_specifier = (~(*codep >> 3)) & 0xf;
|
||
|
|
- vex.length = (*codep & 0x4) ? 256 : 128;
|
||
|
|
- switch ((*codep & 0x3))
|
||
|
|
+ ins->vex.register_specifier = (~(*ins->codep >> 3)) & 0xf;
|
||
|
|
+ ins->vex.length = (*ins->codep & 0x4) ? 256 : 128;
|
||
|
|
+ switch ((*ins->codep & 0x3))
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
- vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- need_vex = 1;
|
||
|
|
- codep++;
|
||
|
|
- vindex = *codep++;
|
||
|
|
+ ins->need_vex = 1;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ vindex = *ins->codep++;
|
||
|
|
dp = &vex_table[vex_table_index][vindex];
|
||
|
|
- end_codep = codep;
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
/* There is no MODRM byte for VEX0F 77. */
|
||
|
|
if (vex_table_index != VEX_0F || vindex != 0x77)
|
||
|
|
{
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_VEX_C5_TABLE:
|
||
|
|
/* VEX prefix. */
|
||
|
|
- FETCH_DATA (info, codep + 2);
|
||
|
|
- rex = (*codep & 0x80) ? 0 : REX_R;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 2);
|
||
|
|
+ ins->rex = (*ins->codep & 0x80) ? 0 : REX_R;
|
||
|
|
|
||
|
|
/* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
|
||
|
|
VEX.vvvv is 1. */
|
||
|
|
- vex.register_specifier = (~(*codep >> 3)) & 0xf;
|
||
|
|
- vex.length = (*codep & 0x4) ? 256 : 128;
|
||
|
|
- switch ((*codep & 0x3))
|
||
|
|
+ ins->vex.register_specifier = (~(*ins->codep >> 3)) & 0xf;
|
||
|
|
+ ins->vex.length = (*ins->codep & 0x4) ? 256 : 128;
|
||
|
|
+ switch ((*ins->codep & 0x3))
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
- vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- need_vex = 1;
|
||
|
|
- codep++;
|
||
|
|
- vindex = *codep++;
|
||
|
|
+ ins->need_vex = 1;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ vindex = *ins->codep++;
|
||
|
|
dp = &vex_table[dp->op[1].bytemode][vindex];
|
||
|
|
- end_codep = codep;
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
/* There is no MODRM byte for VEX 77. */
|
||
|
|
if (vindex != 0x77)
|
||
|
|
{
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_VEX_W_TABLE:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- dp = &vex_w_table[dp->op[1].bytemode][vex.w ? 1 : 0];
|
||
|
|
+ dp = &vex_w_table[dp->op[1].bytemode][ins->vex.w ? 1 : 0];
|
||
|
|
break;
|
||
|
|
|
||
|
|
case USE_EVEX_TABLE:
|
||
|
|
- two_source_ops = 0;
|
||
|
|
+ ins->two_source_ops = 0;
|
||
|
|
/* EVEX prefix. */
|
||
|
|
- vex.evex = 1;
|
||
|
|
- FETCH_DATA (info, codep + 4);
|
||
|
|
+ ins->vex.evex = 1;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 4);
|
||
|
|
/* The first byte after 0x62. */
|
||
|
|
- rex = ~(*codep >> 5) & 0x7;
|
||
|
|
- vex.r = *codep & 0x10;
|
||
|
|
- switch ((*codep & 0xf))
|
||
|
|
+ ins->rex = ~(*ins->codep >> 5) & 0x7;
|
||
|
|
+ ins->vex.r = *ins->codep & 0x10;
|
||
|
|
+ switch ((*ins->codep & 0xf))
|
||
|
|
{
|
||
|
|
default:
|
||
|
|
return &bad_opcode;
|
||
|
|
@@ -9339,75 +9348,75 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
}
|
||
|
|
|
||
|
|
/* The second byte after 0x62. */
|
||
|
|
- codep++;
|
||
|
|
- vex.w = *codep & 0x80;
|
||
|
|
- if (vex.w && address_mode == mode_64bit)
|
||
|
|
- rex |= REX_W;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ ins->vex.w = *ins->codep & 0x80;
|
||
|
|
+ if (ins->vex.w && ins->address_mode == mode_64bit)
|
||
|
|
+ ins->rex |= REX_W;
|
||
|
|
|
||
|
|
- vex.register_specifier = (~(*codep >> 3)) & 0xf;
|
||
|
|
+ ins->vex.register_specifier = (~(*ins->codep >> 3)) & 0xf;
|
||
|
|
|
||
|
|
/* The U bit. */
|
||
|
|
- if (!(*codep & 0x4))
|
||
|
|
+ if (!(*ins->codep & 0x4))
|
||
|
|
return &bad_opcode;
|
||
|
|
|
||
|
|
- switch ((*codep & 0x3))
|
||
|
|
+ switch ((*ins->codep & 0x3))
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = DATA_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
- vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
+ ins->vex.prefix = REPNE_PREFIX_OPCODE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* The third byte after 0x62. */
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
|
||
|
|
/* Remember the static rounding bits. */
|
||
|
|
- vex.ll = (*codep >> 5) & 3;
|
||
|
|
- vex.b = (*codep & 0x10) != 0;
|
||
|
|
+ ins->vex.ll = (*ins->codep >> 5) & 3;
|
||
|
|
+ ins->vex.b = (*ins->codep & 0x10) != 0;
|
||
|
|
|
||
|
|
- vex.v = *codep & 0x8;
|
||
|
|
- vex.mask_register_specifier = *codep & 0x7;
|
||
|
|
- vex.zeroing = *codep & 0x80;
|
||
|
|
+ ins->vex.v = *ins->codep & 0x8;
|
||
|
|
+ ins->vex.mask_register_specifier = *ins->codep & 0x7;
|
||
|
|
+ ins->vex.zeroing = *ins->codep & 0x80;
|
||
|
|
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
{
|
||
|
|
/* In 16/32-bit mode silently ignore following bits. */
|
||
|
|
- rex &= ~REX_B;
|
||
|
|
- vex.r = 1;
|
||
|
|
+ ins->rex &= ~REX_B;
|
||
|
|
+ ins->vex.r = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- need_vex = 1;
|
||
|
|
- codep++;
|
||
|
|
- vindex = *codep++;
|
||
|
|
+ ins->need_vex = 1;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ vindex = *ins->codep++;
|
||
|
|
dp = &evex_table[vex_table_index][vindex];
|
||
|
|
- end_codep = codep;
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
|
||
|
|
/* Set vector length. */
|
||
|
|
- if (modrm.mod == 3 && vex.b)
|
||
|
|
- vex.length = 512;
|
||
|
|
+ if (ins->modrm.mod == 3 && ins->vex.b)
|
||
|
|
+ ins->vex.length = 512;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- switch (vex.ll)
|
||
|
|
+ switch (ins->vex.ll)
|
||
|
|
{
|
||
|
|
case 0x0:
|
||
|
|
- vex.length = 128;
|
||
|
|
+ ins->vex.length = 128;
|
||
|
|
break;
|
||
|
|
case 0x1:
|
||
|
|
- vex.length = 256;
|
||
|
|
+ ins->vex.length = 256;
|
||
|
|
break;
|
||
|
|
case 0x2:
|
||
|
|
- vex.length = 512;
|
||
|
|
+ ins->vex.length = 512;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return &bad_opcode;
|
||
|
|
@@ -9426,27 +9435,27 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
|
||
|
|
if (dp->name != NULL)
|
||
|
|
return dp;
|
||
|
|
else
|
||
|
|
- return get_valid_dis386 (dp, info);
|
||
|
|
+ return get_valid_dis386 (dp, ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-get_sib (disassemble_info *info, int sizeflag)
|
||
|
|
+get_sib (instr_info *ins, int sizeflag)
|
||
|
|
{
|
||
|
|
/* If modrm.mod == 3, operand must be register. */
|
||
|
|
- if (need_modrm
|
||
|
|
- && ((sizeflag & AFLAG) || address_mode == mode_64bit)
|
||
|
|
- && modrm.mod != 3
|
||
|
|
- && modrm.rm == 4)
|
||
|
|
+ if (ins->need_modrm
|
||
|
|
+ && ((sizeflag & AFLAG) || ins->address_mode == mode_64bit)
|
||
|
|
+ && ins->modrm.mod != 3
|
||
|
|
+ && ins->modrm.rm == 4)
|
||
|
|
{
|
||
|
|
- FETCH_DATA (info, codep + 2);
|
||
|
|
- sib.index = (codep [1] >> 3) & 7;
|
||
|
|
- sib.scale = (codep [1] >> 6) & 3;
|
||
|
|
- sib.base = codep [1] & 7;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 2);
|
||
|
|
+ ins->sib.index = (ins->codep[1] >> 3) & 7;
|
||
|
|
+ ins->sib.scale = (ins->codep[1] >> 6) & 3;
|
||
|
|
+ ins->sib.base = ins->codep[1] & 7;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static int
|
||
|
|
-print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
+print_insn (bfd_vma pc, instr_info *ins)
|
||
|
|
{
|
||
|
|
const struct dis386 *dp;
|
||
|
|
int i;
|
||
|
|
@@ -9457,56 +9466,59 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
struct dis_private priv;
|
||
|
|
int prefix_length;
|
||
|
|
|
||
|
|
+ ins->isa64 = 0;
|
||
|
|
+ ins->intel_mnemonic = !SYSV386_COMPAT;
|
||
|
|
+ ins->op_is_jump = false;
|
||
|
|
priv.orig_sizeflag = AFLAG | DFLAG;
|
||
|
|
- if ((info->mach & bfd_mach_i386_i386) != 0)
|
||
|
|
- address_mode = mode_32bit;
|
||
|
|
- else if (info->mach == bfd_mach_i386_i8086)
|
||
|
|
+ if ((ins->info->mach & bfd_mach_i386_i386) != 0)
|
||
|
|
+ ins->address_mode = mode_32bit;
|
||
|
|
+ else if (ins->info->mach == bfd_mach_i386_i8086)
|
||
|
|
{
|
||
|
|
- address_mode = mode_16bit;
|
||
|
|
+ ins->address_mode = mode_16bit;
|
||
|
|
priv.orig_sizeflag = 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- address_mode = mode_64bit;
|
||
|
|
+ ins->address_mode = mode_64bit;
|
||
|
|
|
||
|
|
- if (intel_syntax == (char) -1)
|
||
|
|
- intel_syntax = (info->mach & bfd_mach_i386_intel_syntax) != 0;
|
||
|
|
+ if (ins->intel_syntax == (char) -1)
|
||
|
|
+ ins->intel_syntax = (ins->info->mach & bfd_mach_i386_intel_syntax) != 0;
|
||
|
|
|
||
|
|
- for (p = info->disassembler_options; p != NULL; )
|
||
|
|
+ for (p = ins->info->disassembler_options; p != NULL;)
|
||
|
|
{
|
||
|
|
if (startswith (p, "amd64"))
|
||
|
|
- isa64 = amd64;
|
||
|
|
+ ins->isa64 = amd64;
|
||
|
|
else if (startswith (p, "intel64"))
|
||
|
|
- isa64 = intel64;
|
||
|
|
+ ins->isa64 = intel64;
|
||
|
|
else if (startswith (p, "x86-64"))
|
||
|
|
{
|
||
|
|
- address_mode = mode_64bit;
|
||
|
|
+ ins->address_mode = mode_64bit;
|
||
|
|
priv.orig_sizeflag |= AFLAG | DFLAG;
|
||
|
|
}
|
||
|
|
else if (startswith (p, "i386"))
|
||
|
|
{
|
||
|
|
- address_mode = mode_32bit;
|
||
|
|
+ ins->address_mode = mode_32bit;
|
||
|
|
priv.orig_sizeflag |= AFLAG | DFLAG;
|
||
|
|
}
|
||
|
|
else if (startswith (p, "i8086"))
|
||
|
|
{
|
||
|
|
- address_mode = mode_16bit;
|
||
|
|
+ ins->address_mode = mode_16bit;
|
||
|
|
priv.orig_sizeflag &= ~(AFLAG | DFLAG);
|
||
|
|
}
|
||
|
|
else if (startswith (p, "intel"))
|
||
|
|
{
|
||
|
|
- intel_syntax = 1;
|
||
|
|
+ ins->intel_syntax = 1;
|
||
|
|
if (startswith (p + 5, "-mnemonic"))
|
||
|
|
- intel_mnemonic = 1;
|
||
|
|
+ ins->intel_mnemonic = 1;
|
||
|
|
}
|
||
|
|
else if (startswith (p, "att"))
|
||
|
|
{
|
||
|
|
- intel_syntax = 0;
|
||
|
|
+ ins->intel_syntax = 0;
|
||
|
|
if (startswith (p + 3, "-mnemonic"))
|
||
|
|
- intel_mnemonic = 0;
|
||
|
|
+ ins->intel_mnemonic = 0;
|
||
|
|
}
|
||
|
|
else if (startswith (p, "addr"))
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
if (p[4] == '3' && p[5] == '2')
|
||
|
|
priv.orig_sizeflag &= ~AFLAG;
|
||
|
|
@@ -9536,83 +9548,82 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
p++;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (address_mode == mode_64bit && sizeof (bfd_vma) < 8)
|
||
|
|
+ if (ins->address_mode == mode_64bit && sizeof (bfd_vma) < 8)
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream,
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream,
|
||
|
|
_("64-bit address is disabled"));
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- names64 = intel_names64;
|
||
|
|
- names32 = intel_names32;
|
||
|
|
- names16 = intel_names16;
|
||
|
|
- names8 = intel_names8;
|
||
|
|
- names8rex = intel_names8rex;
|
||
|
|
- names_seg = intel_names_seg;
|
||
|
|
- names_mm = intel_names_mm;
|
||
|
|
- names_bnd = intel_names_bnd;
|
||
|
|
- names_xmm = intel_names_xmm;
|
||
|
|
- names_ymm = intel_names_ymm;
|
||
|
|
- names_zmm = intel_names_zmm;
|
||
|
|
- names_tmm = intel_names_tmm;
|
||
|
|
- index64 = intel_index64;
|
||
|
|
- index32 = intel_index32;
|
||
|
|
- names_mask = intel_names_mask;
|
||
|
|
- index16 = intel_index16;
|
||
|
|
- open_char = '[';
|
||
|
|
- close_char = ']';
|
||
|
|
- separator_char = '+';
|
||
|
|
- scale_char = '*';
|
||
|
|
+ ins->names64 = intel_names64;
|
||
|
|
+ ins->names32 = intel_names32;
|
||
|
|
+ ins->names16 = intel_names16;
|
||
|
|
+ ins->names8 = intel_names8;
|
||
|
|
+ ins->names8rex = intel_names8rex;
|
||
|
|
+ ins->names_seg = intel_names_seg;
|
||
|
|
+ ins->names_mm = intel_names_mm;
|
||
|
|
+ ins->names_bnd = intel_names_bnd;
|
||
|
|
+ ins->names_xmm = intel_names_xmm;
|
||
|
|
+ ins->names_ymm = intel_names_ymm;
|
||
|
|
+ ins->names_zmm = intel_names_zmm;
|
||
|
|
+ ins->names_tmm = intel_names_tmm;
|
||
|
|
+ ins->index64 = intel_index64;
|
||
|
|
+ ins->index32 = intel_index32;
|
||
|
|
+ ins->names_mask = intel_names_mask;
|
||
|
|
+ ins->index16 = intel_index16;
|
||
|
|
+ ins->open_char = '[';
|
||
|
|
+ ins->close_char = ']';
|
||
|
|
+ ins->separator_char = '+';
|
||
|
|
+ ins->scale_char = '*';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- names64 = att_names64;
|
||
|
|
- names32 = att_names32;
|
||
|
|
- names16 = att_names16;
|
||
|
|
- names8 = att_names8;
|
||
|
|
- names8rex = att_names8rex;
|
||
|
|
- names_seg = att_names_seg;
|
||
|
|
- names_mm = att_names_mm;
|
||
|
|
- names_bnd = att_names_bnd;
|
||
|
|
- names_xmm = att_names_xmm;
|
||
|
|
- names_ymm = att_names_ymm;
|
||
|
|
- names_zmm = att_names_zmm;
|
||
|
|
- names_tmm = att_names_tmm;
|
||
|
|
- index64 = att_index64;
|
||
|
|
- index32 = att_index32;
|
||
|
|
- names_mask = att_names_mask;
|
||
|
|
- index16 = att_index16;
|
||
|
|
- open_char = '(';
|
||
|
|
- close_char = ')';
|
||
|
|
- separator_char = ',';
|
||
|
|
- scale_char = ',';
|
||
|
|
+ ins->names64 = att_names64;
|
||
|
|
+ ins->names32 = att_names32;
|
||
|
|
+ ins->names16 = att_names16;
|
||
|
|
+ ins->names8 = att_names8;
|
||
|
|
+ ins->names8rex = att_names8rex;
|
||
|
|
+ ins->names_seg = att_names_seg;
|
||
|
|
+ ins->names_mm = att_names_mm;
|
||
|
|
+ ins->names_bnd = att_names_bnd;
|
||
|
|
+ ins->names_xmm = att_names_xmm;
|
||
|
|
+ ins->names_ymm = att_names_ymm;
|
||
|
|
+ ins->names_zmm = att_names_zmm;
|
||
|
|
+ ins->names_tmm = att_names_tmm;
|
||
|
|
+ ins->index64 = att_index64;
|
||
|
|
+ ins->index32 = att_index32;
|
||
|
|
+ ins->names_mask = att_names_mask;
|
||
|
|
+ ins->index16 = att_index16;
|
||
|
|
+ ins->open_char = '(';
|
||
|
|
+ ins->close_char = ')';
|
||
|
|
+ ins->separator_char = ',';
|
||
|
|
+ ins->scale_char = ',';
|
||
|
|
}
|
||
|
|
|
||
|
|
/* The output looks better if we put 7 bytes on a line, since that
|
||
|
|
puts most long word instructions on a single line. Use 8 bytes
|
||
|
|
for Intel L1OM. */
|
||
|
|
- if ((info->mach & bfd_mach_l1om) != 0)
|
||
|
|
- info->bytes_per_line = 8;
|
||
|
|
+ if ((ins->info->mach & bfd_mach_l1om) != 0)
|
||
|
|
+ ins->info->bytes_per_line = 8;
|
||
|
|
else
|
||
|
|
- info->bytes_per_line = 7;
|
||
|
|
+ ins->info->bytes_per_line = 7;
|
||
|
|
|
||
|
|
- info->private_data = &priv;
|
||
|
|
+ ins->info->private_data = &priv;
|
||
|
|
priv.max_fetched = priv.the_buffer;
|
||
|
|
priv.insn_start = pc;
|
||
|
|
|
||
|
|
- obuf[0] = 0;
|
||
|
|
+ ins->obuf[0] = 0;
|
||
|
|
for (i = 0; i < MAX_OPERANDS; ++i)
|
||
|
|
{
|
||
|
|
- op_out[i][0] = 0;
|
||
|
|
- op_index[i] = -1;
|
||
|
|
+ ins->op_out[i][0] = 0;
|
||
|
|
+ ins->op_index[i] = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- the_info = info;
|
||
|
|
- start_pc = pc;
|
||
|
|
- start_codep = priv.the_buffer;
|
||
|
|
- codep = priv.the_buffer;
|
||
|
|
+ ins->start_pc = pc;
|
||
|
|
+ ins->start_codep = priv.the_buffer;
|
||
|
|
+ ins->codep = priv.the_buffer;
|
||
|
|
|
||
|
|
if (OPCODES_SIGSETJMP (priv.bailout) != 0)
|
||
|
|
{
|
||
|
|
@@ -9621,15 +9632,15 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
/* Getting here means we tried for data but didn't get it. That
|
||
|
|
means we have an incomplete instruction of some sort. Just
|
||
|
|
print the first byte as a prefix or a .byte pseudo-op. */
|
||
|
|
- if (codep > priv.the_buffer)
|
||
|
|
+ if (ins->codep > priv.the_buffer)
|
||
|
|
{
|
||
|
|
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
|
||
|
|
+ name = prefix_name (ins, priv.the_buffer[0], priv.orig_sizeflag);
|
||
|
|
if (name != NULL)
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s", name);
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s", name);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Just print the first byte as a .byte instruction. */
|
||
|
|
- (*info->fprintf_func) (info->stream, ".byte 0x%x",
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, ".byte 0x%x",
|
||
|
|
(unsigned int) priv.the_buffer[0]);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -9639,130 +9650,135 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- obufp = obuf;
|
||
|
|
+ ins->obufp = ins->obuf;
|
||
|
|
sizeflag = priv.orig_sizeflag;
|
||
|
|
|
||
|
|
- if (!ckprefix () || rex_used)
|
||
|
|
+ if (!ckprefix (ins) || ins->rex_used)
|
||
|
|
{
|
||
|
|
- /* Too many prefixes or unused REX prefixes. */
|
||
|
|
+ /* Too many ins->prefixes or unused REX ins->prefixes. */
|
||
|
|
for (i = 0;
|
||
|
|
- i < (int) ARRAY_SIZE (all_prefixes) && all_prefixes[i];
|
||
|
|
+ i < (int) ARRAY_SIZE (ins->all_prefixes) && ins->all_prefixes[i];
|
||
|
|
i++)
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s%s",
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s%s",
|
||
|
|
i == 0 ? "" : " ",
|
||
|
|
- prefix_name (all_prefixes[i], sizeflag));
|
||
|
|
+ prefix_name (ins, ins->all_prefixes[i],
|
||
|
|
+ sizeflag));
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
|
||
|
|
- insn_codep = codep;
|
||
|
|
+ ins->insn_codep = ins->codep;
|
||
|
|
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->two_source_ops = (*ins->codep == 0x62) || (*ins->codep == 0xc8);
|
||
|
|
|
||
|
|
- if (((prefixes & PREFIX_FWAIT)
|
||
|
|
- && ((*codep < 0xd8) || (*codep > 0xdf))))
|
||
|
|
+ if (((ins->prefixes & PREFIX_FWAIT)
|
||
|
|
+ && ((*ins->codep < 0xd8) || (*ins->codep > 0xdf))))
|
||
|
|
{
|
||
|
|
- /* Handle prefixes before fwait. */
|
||
|
|
- for (i = 0; i < fwait_prefix && all_prefixes[i];
|
||
|
|
+ /* Handle ins->prefixes before fwait. */
|
||
|
|
+ for (i = 0; i < ins->fwait_prefix && ins->all_prefixes[i];
|
||
|
|
i++)
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s ",
|
||
|
|
- prefix_name (all_prefixes[i], sizeflag));
|
||
|
|
- (*info->fprintf_func) (info->stream, "fwait");
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s ",
|
||
|
|
+ prefix_name (ins, ins->all_prefixes[i],
|
||
|
|
+ sizeflag));
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "fwait");
|
||
|
|
return i + 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (*codep == 0x0f)
|
||
|
|
+ if (*ins->codep == 0x0f)
|
||
|
|
{
|
||
|
|
unsigned char threebyte;
|
||
|
|
|
||
|
|
- codep++;
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- threebyte = *codep;
|
||
|
|
+ ins->codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ threebyte = *ins->codep;
|
||
|
|
dp = &dis386_twobyte[threebyte];
|
||
|
|
- need_modrm = twobyte_has_modrm[threebyte];
|
||
|
|
- codep++;
|
||
|
|
+ ins->need_modrm = twobyte_has_modrm[threebyte];
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- dp = &dis386[*codep];
|
||
|
|
- need_modrm = onebyte_has_modrm[*codep];
|
||
|
|
- codep++;
|
||
|
|
+ dp = &dis386[*ins->codep];
|
||
|
|
+ ins->need_modrm = onebyte_has_modrm[*ins->codep];
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
|
||
|
|
- /* Save sizeflag for printing the extra prefixes later before updating
|
||
|
|
+ /* Save sizeflag for printing the extra ins->prefixes later before updating
|
||
|
|
it for mnemonic and operand processing. The prefix names depend
|
||
|
|
only on the address mode. */
|
||
|
|
orig_sizeflag = sizeflag;
|
||
|
|
- if (prefixes & PREFIX_ADDR)
|
||
|
|
+ if (ins->prefixes & PREFIX_ADDR)
|
||
|
|
sizeflag ^= AFLAG;
|
||
|
|
- if ((prefixes & PREFIX_DATA))
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA))
|
||
|
|
sizeflag ^= DFLAG;
|
||
|
|
|
||
|
|
- end_codep = codep;
|
||
|
|
- if (need_modrm)
|
||
|
|
+ ins->end_codep = ins->codep;
|
||
|
|
+ if (ins->need_modrm)
|
||
|
|
{
|
||
|
|
- FETCH_DATA (info, codep + 1);
|
||
|
|
- modrm.mod = (*codep >> 6) & 3;
|
||
|
|
- modrm.reg = (*codep >> 3) & 7;
|
||
|
|
- modrm.rm = *codep & 7;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ ins->modrm.mod = (*ins->codep >> 6) & 3;
|
||
|
|
+ ins->modrm.reg = (*ins->codep >> 3) & 7;
|
||
|
|
+ ins->modrm.rm = *ins->codep & 7;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- memset (&modrm, 0, sizeof (modrm));
|
||
|
|
+ memset (&ins->modrm, 0, sizeof (ins->modrm));
|
||
|
|
|
||
|
|
- need_vex = 0;
|
||
|
|
- memset (&vex, 0, sizeof (vex));
|
||
|
|
+ ins->need_vex = 0;
|
||
|
|
+ memset (&ins->vex, 0, sizeof (ins->vex));
|
||
|
|
|
||
|
|
if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
|
||
|
|
{
|
||
|
|
- get_sib (info, sizeflag);
|
||
|
|
- dofloat (sizeflag);
|
||
|
|
+ get_sib (ins, sizeflag);
|
||
|
|
+ dofloat (ins, sizeflag);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- dp = get_valid_dis386 (dp, info);
|
||
|
|
- if (dp != NULL && putop (dp->name, sizeflag) == 0)
|
||
|
|
+ dp = get_valid_dis386 (dp, ins);
|
||
|
|
+ if (dp != NULL && putop (ins, dp->name, sizeflag) == 0)
|
||
|
|
{
|
||
|
|
- get_sib (info, sizeflag);
|
||
|
|
+ get_sib (ins, sizeflag);
|
||
|
|
for (i = 0; i < MAX_OPERANDS; ++i)
|
||
|
|
{
|
||
|
|
- obufp = op_out[i];
|
||
|
|
- op_ad = MAX_OPERANDS - 1 - i;
|
||
|
|
+ ins->obufp = ins->op_out[i];
|
||
|
|
+ ins->op_ad = MAX_OPERANDS - 1 - i;
|
||
|
|
if (dp->op[i].rtn)
|
||
|
|
- (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
|
||
|
|
+ (*dp->op[i].rtn) (ins, dp->op[i].bytemode, sizeflag);
|
||
|
|
/* For EVEX instruction after the last operand masking
|
||
|
|
should be printed. */
|
||
|
|
- if (i == 0 && vex.evex)
|
||
|
|
+ if (i == 0 && ins->vex.evex)
|
||
|
|
{
|
||
|
|
/* Don't print {%k0}. */
|
||
|
|
- if (vex.mask_register_specifier)
|
||
|
|
+ if (ins->vex.mask_register_specifier)
|
||
|
|
{
|
||
|
|
- oappend ("{");
|
||
|
|
- oappend (names_mask[vex.mask_register_specifier]);
|
||
|
|
- oappend ("}");
|
||
|
|
+ oappend (ins, "{");
|
||
|
|
+ oappend (ins,
|
||
|
|
+ ins->names_mask[ins->vex.mask_register_specifier]);
|
||
|
|
+ oappend (ins, "}");
|
||
|
|
}
|
||
|
|
- if (vex.zeroing)
|
||
|
|
- oappend ("{z}");
|
||
|
|
+ if (ins->vex.zeroing)
|
||
|
|
+ oappend (ins, "{z}");
|
||
|
|
|
||
|
|
/* S/G insns require a mask and don't allow
|
||
|
|
zeroing-masking. */
|
||
|
|
if ((dp->op[0].bytemode == vex_vsib_d_w_dq_mode
|
||
|
|
|| dp->op[0].bytemode == vex_vsib_q_w_dq_mode)
|
||
|
|
- && (vex.mask_register_specifier == 0 || vex.zeroing))
|
||
|
|
- oappend ("/(bad)");
|
||
|
|
+ && (ins->vex.mask_register_specifier == 0
|
||
|
|
+ || ins->vex.zeroing))
|
||
|
|
+ oappend (ins, "/(bad)");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check whether rounding control was enabled for an insn not
|
||
|
|
supporting it. */
|
||
|
|
- if (modrm.mod == 3 && vex.b && !(evex_used & EVEX_b_used))
|
||
|
|
+ if (ins->modrm.mod == 3 && ins->vex.b
|
||
|
|
+ && !(ins->evex_used & EVEX_b_used))
|
||
|
|
{
|
||
|
|
for (i = 0; i < MAX_OPERANDS; ++i)
|
||
|
|
{
|
||
|
|
- obufp = op_out[i];
|
||
|
|
- if (*obufp)
|
||
|
|
+ ins->obufp = ins->op_out[i];
|
||
|
|
+ if (*ins->obufp)
|
||
|
|
continue;
|
||
|
|
- oappend (names_rounding[vex.ll]);
|
||
|
|
- oappend ("bad}");
|
||
|
|
+ oappend (ins, names_rounding[ins->vex.ll]);
|
||
|
|
+ oappend (ins, "bad}");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -9770,19 +9786,15 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Clear instruction information. */
|
||
|
|
- if (the_info)
|
||
|
|
- {
|
||
|
|
- the_info->insn_info_valid = 0;
|
||
|
|
- the_info->branch_delay_insns = 0;
|
||
|
|
- the_info->data_size = 0;
|
||
|
|
- the_info->insn_type = dis_noninsn;
|
||
|
|
- the_info->target = 0;
|
||
|
|
- the_info->target2 = 0;
|
||
|
|
- }
|
||
|
|
+ ins->info->insn_info_valid = 0;
|
||
|
|
+ ins->info->branch_delay_insns = 0;
|
||
|
|
+ ins->info->data_size = 0;
|
||
|
|
+ ins->info->insn_type = dis_noninsn;
|
||
|
|
+ ins->info->target = 0;
|
||
|
|
+ ins->info->target2 = 0;
|
||
|
|
|
||
|
|
/* Reset jump operation indicator. */
|
||
|
|
- op_is_jump = false;
|
||
|
|
-
|
||
|
|
+ ins->op_is_jump = false;
|
||
|
|
{
|
||
|
|
int jump_detection = 0;
|
||
|
|
|
||
|
|
@@ -9803,29 +9815,28 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
/* Determine if this is a jump or branch. */
|
||
|
|
if ((jump_detection & 0x3) == 0x3)
|
||
|
|
{
|
||
|
|
- op_is_jump = true;
|
||
|
|
+ ins->op_is_jump = true;
|
||
|
|
if (jump_detection & 0x4)
|
||
|
|
- the_info->insn_type = dis_condbranch;
|
||
|
|
+ ins->info->insn_type = dis_condbranch;
|
||
|
|
else
|
||
|
|
- the_info->insn_type =
|
||
|
|
- (dp->name && !strncmp(dp->name, "call", 4))
|
||
|
|
+ ins->info->insn_type = (dp->name && !strncmp (dp->name, "call", 4))
|
||
|
|
? dis_jsr : dis_branch;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* If VEX.vvvv and EVEX.vvvv are unused, they must be all 1s, which
|
||
|
|
are all 0s in inverted form. */
|
||
|
|
- if (need_vex && vex.register_specifier != 0)
|
||
|
|
+ if (ins->need_vex && ins->vex.register_specifier != 0)
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, "(bad)");
|
||
|
|
- return end_codep - priv.the_buffer;
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "(bad)");
|
||
|
|
+ return ins->end_codep - priv.the_buffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* If EVEX.z is set, there must be an actual mask register in use. */
|
||
|
|
- if (vex.zeroing && vex.mask_register_specifier == 0)
|
||
|
|
+ if (ins->vex.zeroing && ins->vex.mask_register_specifier == 0)
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, "(bad)");
|
||
|
|
- return end_codep - priv.the_buffer;
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "(bad)");
|
||
|
|
+ return ins->end_codep - priv.the_buffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (dp->prefix_requirement)
|
||
|
|
@@ -9833,12 +9844,12 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
case PREFIX_DATA:
|
||
|
|
/* If only the data prefix is marked as mandatory, its absence renders
|
||
|
|
the encoding invalid. Most other PREFIX_OPCODE rules still apply. */
|
||
|
|
- if (need_vex ? !vex.prefix : !(prefixes & PREFIX_DATA))
|
||
|
|
+ if (ins->need_vex ? !ins->vex.prefix : !(ins->prefixes & PREFIX_DATA))
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, "(bad)");
|
||
|
|
- return end_codep - priv.the_buffer;
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "(bad)");
|
||
|
|
+ return ins->end_codep - priv.the_buffer;
|
||
|
|
}
|
||
|
|
- used_prefixes |= PREFIX_DATA;
|
||
|
|
+ ins->used_prefixes |= PREFIX_DATA;
|
||
|
|
/* Fall through. */
|
||
|
|
case PREFIX_OPCODE:
|
||
|
|
/* If the mandatory PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is
|
||
|
|
@@ -9846,117 +9857,118 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
used by putop and MMX/SSE operand and may be overridden by the
|
||
|
|
PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
|
||
|
|
separately. */
|
||
|
|
- if (((need_vex
|
||
|
|
- ? vex.prefix == REPE_PREFIX_OPCODE
|
||
|
|
- || vex.prefix == REPNE_PREFIX_OPCODE
|
||
|
|
- : (prefixes
|
||
|
|
+ if (((ins->need_vex
|
||
|
|
+ ? ins->vex.prefix == REPE_PREFIX_OPCODE
|
||
|
|
+ || ins->vex.prefix == REPNE_PREFIX_OPCODE
|
||
|
|
+ : (ins->prefixes
|
||
|
|
& (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
|
||
|
|
- && (used_prefixes
|
||
|
|
+ && (ins->used_prefixes
|
||
|
|
& (PREFIX_REPZ | PREFIX_REPNZ)) == 0)
|
||
|
|
- || (((need_vex
|
||
|
|
- ? vex.prefix == DATA_PREFIX_OPCODE
|
||
|
|
- : ((prefixes
|
||
|
|
+ || (((ins->need_vex
|
||
|
|
+ ? ins->vex.prefix == DATA_PREFIX_OPCODE
|
||
|
|
+ : ((ins->prefixes
|
||
|
|
& (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
|
||
|
|
== PREFIX_DATA))
|
||
|
|
- && (used_prefixes & PREFIX_DATA) == 0))
|
||
|
|
- || (vex.evex && dp->prefix_requirement != PREFIX_DATA
|
||
|
|
- && !vex.w != !(used_prefixes & PREFIX_DATA)))
|
||
|
|
+ && (ins->used_prefixes & PREFIX_DATA) == 0))
|
||
|
|
+ || (ins->vex.evex && dp->prefix_requirement != PREFIX_DATA
|
||
|
|
+ && !ins->vex.w != !(ins->used_prefixes & PREFIX_DATA)))
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, "(bad)");
|
||
|
|
- return end_codep - priv.the_buffer;
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "(bad)");
|
||
|
|
+ return ins->end_codep - priv.the_buffer;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case PREFIX_IGNORED:
|
||
|
|
/* Zap data size and rep prefixes from used_prefixes and reinstate their
|
||
|
|
origins in all_prefixes. */
|
||
|
|
- used_prefixes &= ~PREFIX_OPCODE;
|
||
|
|
- if (last_data_prefix >= 0)
|
||
|
|
- all_prefixes[last_data_prefix] = 0x66;
|
||
|
|
- if (last_repz_prefix >= 0)
|
||
|
|
- all_prefixes[last_repz_prefix] = 0xf3;
|
||
|
|
- if (last_repnz_prefix >= 0)
|
||
|
|
- all_prefixes[last_repnz_prefix] = 0xf2;
|
||
|
|
+ ins->used_prefixes &= ~PREFIX_OPCODE;
|
||
|
|
+ if (ins->last_data_prefix >= 0)
|
||
|
|
+ ins->all_prefixes[ins->last_data_prefix] = 0x66;
|
||
|
|
+ if (ins->last_repz_prefix >= 0)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = 0xf3;
|
||
|
|
+ if (ins->last_repnz_prefix >= 0)
|
||
|
|
+ ins->all_prefixes[ins->last_repnz_prefix] = 0xf2;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check if the REX prefix is used. */
|
||
|
|
- if ((rex ^ rex_used) == 0 && !need_vex && last_rex_prefix >= 0)
|
||
|
|
- all_prefixes[last_rex_prefix] = 0;
|
||
|
|
+ if ((ins->rex ^ ins->rex_used) == 0
|
||
|
|
+ && !ins->need_vex && ins->last_rex_prefix >= 0)
|
||
|
|
+ ins->all_prefixes[ins->last_rex_prefix] = 0;
|
||
|
|
|
||
|
|
/* Check if the SEG prefix is used. */
|
||
|
|
- if ((prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | PREFIX_ES
|
||
|
|
+ if ((ins->prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | PREFIX_ES
|
||
|
|
| PREFIX_FS | PREFIX_GS)) != 0
|
||
|
|
- && (used_prefixes & active_seg_prefix) != 0)
|
||
|
|
- all_prefixes[last_seg_prefix] = 0;
|
||
|
|
+ && (ins->used_prefixes & ins->active_seg_prefix) != 0)
|
||
|
|
+ ins->all_prefixes[ins->last_seg_prefix] = 0;
|
||
|
|
|
||
|
|
/* Check if the ADDR prefix is used. */
|
||
|
|
- if ((prefixes & PREFIX_ADDR) != 0
|
||
|
|
- && (used_prefixes & PREFIX_ADDR) != 0)
|
||
|
|
- all_prefixes[last_addr_prefix] = 0;
|
||
|
|
+ if ((ins->prefixes & PREFIX_ADDR) != 0
|
||
|
|
+ && (ins->used_prefixes & PREFIX_ADDR) != 0)
|
||
|
|
+ ins->all_prefixes[ins->last_addr_prefix] = 0;
|
||
|
|
|
||
|
|
/* Check if the DATA prefix is used. */
|
||
|
|
- if ((prefixes & PREFIX_DATA) != 0
|
||
|
|
- && (used_prefixes & PREFIX_DATA) != 0
|
||
|
|
- && !need_vex)
|
||
|
|
- all_prefixes[last_data_prefix] = 0;
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) != 0
|
||
|
|
+ && (ins->used_prefixes & PREFIX_DATA) != 0
|
||
|
|
+ && !ins->need_vex)
|
||
|
|
+ ins->all_prefixes[ins->last_data_prefix] = 0;
|
||
|
|
|
||
|
|
- /* Print the extra prefixes. */
|
||
|
|
+ /* Print the extra ins->prefixes. */
|
||
|
|
prefix_length = 0;
|
||
|
|
- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
|
||
|
|
- if (all_prefixes[i])
|
||
|
|
+ for (i = 0; i < (int) ARRAY_SIZE (ins->all_prefixes); i++)
|
||
|
|
+ if (ins->all_prefixes[i])
|
||
|
|
{
|
||
|
|
const char *name;
|
||
|
|
- name = prefix_name (all_prefixes[i], orig_sizeflag);
|
||
|
|
+ name = prefix_name (ins, ins->all_prefixes[i], orig_sizeflag);
|
||
|
|
if (name == NULL)
|
||
|
|
abort ();
|
||
|
|
prefix_length += strlen (name) + 1;
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s ", name);
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s ", name);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Check maximum code length. */
|
||
|
|
- if ((codep - start_codep) > MAX_CODE_LENGTH)
|
||
|
|
+ if ((ins->codep - ins->start_codep) > MAX_CODE_LENGTH)
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, "(bad)");
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "(bad)");
|
||
|
|
return MAX_CODE_LENGTH;
|
||
|
|
}
|
||
|
|
|
||
|
|
- obufp = mnemonicendp;
|
||
|
|
- for (i = strlen (obuf) + prefix_length; i < 6; i++)
|
||
|
|
- oappend (" ");
|
||
|
|
- oappend (" ");
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s", obuf);
|
||
|
|
+ ins->obufp = ins->mnemonicendp;
|
||
|
|
+ for (i = strlen (ins->obuf) + prefix_length; i < 6; i++)
|
||
|
|
+ oappend (ins, " ");
|
||
|
|
+ oappend (ins, " ");
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s", ins->obuf);
|
||
|
|
|
||
|
|
/* The enter and bound instructions are printed with operands in the same
|
||
|
|
order as the intel book; everything else is printed in reverse order. */
|
||
|
|
- if (intel_syntax || two_source_ops)
|
||
|
|
+ if (ins->intel_syntax || ins->two_source_ops)
|
||
|
|
{
|
||
|
|
bfd_vma riprel;
|
||
|
|
|
||
|
|
for (i = 0; i < MAX_OPERANDS; ++i)
|
||
|
|
- op_txt[i] = op_out[i];
|
||
|
|
+ op_txt[i] = ins->op_out[i];
|
||
|
|
|
||
|
|
- if (intel_syntax && dp && dp->op[2].rtn == OP_Rounding
|
||
|
|
+ if (ins->intel_syntax && dp && dp->op[2].rtn == OP_Rounding
|
||
|
|
&& dp->op[3].rtn == OP_E && dp->op[4].rtn == NULL)
|
||
|
|
{
|
||
|
|
- op_txt[2] = op_out[3];
|
||
|
|
- op_txt[3] = op_out[2];
|
||
|
|
+ op_txt[2] = ins->op_out[3];
|
||
|
|
+ op_txt[3] = ins->op_out[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
|
||
|
|
{
|
||
|
|
- op_ad = op_index[i];
|
||
|
|
- op_index[i] = op_index[MAX_OPERANDS - 1 - i];
|
||
|
|
- op_index[MAX_OPERANDS - 1 - i] = op_ad;
|
||
|
|
- riprel = op_riprel[i];
|
||
|
|
- op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
|
||
|
|
- op_riprel[MAX_OPERANDS - 1 - i] = riprel;
|
||
|
|
+ ins->op_ad = ins->op_index[i];
|
||
|
|
+ ins->op_index[i] = ins->op_index[MAX_OPERANDS - 1 - i];
|
||
|
|
+ ins->op_index[MAX_OPERANDS - 1 - i] = ins->op_ad;
|
||
|
|
+ riprel = ins->op_riprel[i];
|
||
|
|
+ ins->op_riprel[i] = ins->op_riprel[MAX_OPERANDS - 1 - i];
|
||
|
|
+ ins->op_riprel[MAX_OPERANDS - 1 - i] = riprel;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
for (i = 0; i < MAX_OPERANDS; ++i)
|
||
|
|
- op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
|
||
|
|
+ op_txt[MAX_OPERANDS - 1 - i] = ins->op_out[i];
|
||
|
|
}
|
||
|
|
|
||
|
|
needcomma = 0;
|
||
|
|
@@ -9964,35 +9976,36 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||
|
|
if (*op_txt[i])
|
||
|
|
{
|
||
|
|
if (needcomma)
|
||
|
|
- (*info->fprintf_func) (info->stream, ",");
|
||
|
|
- if (op_index[i] != -1 && !op_riprel[i])
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, ",");
|
||
|
|
+ if (ins->op_index[i] != -1 && !ins->op_riprel[i])
|
||
|
|
{
|
||
|
|
- bfd_vma target = (bfd_vma) op_address[op_index[i]];
|
||
|
|
+ bfd_vma target = (bfd_vma) ins->op_address[ins->op_index[i]];
|
||
|
|
|
||
|
|
- if (the_info && op_is_jump)
|
||
|
|
+ if (ins->op_is_jump)
|
||
|
|
{
|
||
|
|
- the_info->insn_info_valid = 1;
|
||
|
|
- the_info->branch_delay_insns = 0;
|
||
|
|
- the_info->data_size = 0;
|
||
|
|
- the_info->target = target;
|
||
|
|
- the_info->target2 = 0;
|
||
|
|
+ ins->info->insn_info_valid = 1;
|
||
|
|
+ ins->info->branch_delay_insns = 0;
|
||
|
|
+ ins->info->data_size = 0;
|
||
|
|
+ ins->info->target = target;
|
||
|
|
+ ins->info->target2 = 0;
|
||
|
|
}
|
||
|
|
- (*info->print_address_func) (target, info);
|
||
|
|
+ (*ins->info->print_address_func) (target, ins->info);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, "%s", op_txt[i]);
|
||
|
|
needcomma = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < MAX_OPERANDS; i++)
|
||
|
|
- if (op_index[i] != -1 && op_riprel[i])
|
||
|
|
+ if (ins->op_index[i] != -1 && ins->op_riprel[i])
|
||
|
|
{
|
||
|
|
- (*info->fprintf_func) (info->stream, " # ");
|
||
|
|
- (*info->print_address_func) ((bfd_vma) (start_pc + (codep - start_codep)
|
||
|
|
- + op_address[op_index[i]]), info);
|
||
|
|
+ (*ins->info->fprintf_func) (ins->info->stream, " # ");
|
||
|
|
+ (*ins->info->print_address_func) ((bfd_vma)
|
||
|
|
+ (ins->start_pc + (ins->codep - ins->start_codep)
|
||
|
|
+ + ins->op_address[ins->op_index[i]]), ins->info);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- return codep - priv.the_buffer;
|
||
|
|
+ return ins->codep - priv.the_buffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
static const char *float_mem[] = {
|
||
|
|
@@ -10303,94 +10316,96 @@ static char *fgrps[][8] = {
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
-swap_operand (void)
|
||
|
|
+swap_operand (instr_info *ins)
|
||
|
|
{
|
||
|
|
- mnemonicendp[0] = '.';
|
||
|
|
- mnemonicendp[1] = 's';
|
||
|
|
- mnemonicendp[2] = '\0';
|
||
|
|
- mnemonicendp += 2;
|
||
|
|
+ ins->mnemonicendp[0] = '.';
|
||
|
|
+ ins->mnemonicendp[1] = 's';
|
||
|
|
+ ins->mnemonicendp[2] = '\0';
|
||
|
|
+ ins->mnemonicendp += 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+OP_Skip_MODRM (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-dofloat (int sizeflag)
|
||
|
|
+dofloat (instr_info *ins, int sizeflag)
|
||
|
|
{
|
||
|
|
const struct dis386 *dp;
|
||
|
|
unsigned char floatop;
|
||
|
|
|
||
|
|
- floatop = codep[-1];
|
||
|
|
+ floatop = ins->codep[-1];
|
||
|
|
|
||
|
|
- if (modrm.mod != 3)
|
||
|
|
+ if (ins->modrm.mod != 3)
|
||
|
|
{
|
||
|
|
- int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
|
||
|
|
+ int fp_indx = (floatop - 0xd8) * 8 + ins->modrm.reg;
|
||
|
|
|
||
|
|
- putop (float_mem[fp_indx], sizeflag);
|
||
|
|
- obufp = op_out[0];
|
||
|
|
- op_ad = 2;
|
||
|
|
- OP_E (float_mem_mode[fp_indx], sizeflag);
|
||
|
|
+ putop (ins, float_mem[fp_indx], sizeflag);
|
||
|
|
+ ins->obufp = ins->op_out[0];
|
||
|
|
+ ins->op_ad = 2;
|
||
|
|
+ OP_E (ins, float_mem_mode[fp_indx], sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
|
||
|
|
- dp = &float_reg[floatop - 0xd8][modrm.reg];
|
||
|
|
+ dp = &float_reg[floatop - 0xd8][ins->modrm.reg];
|
||
|
|
if (dp->name == NULL)
|
||
|
|
{
|
||
|
|
- putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
|
||
|
|
+ putop (ins, fgrps[dp->op[0].bytemode][ins->modrm.rm], sizeflag);
|
||
|
|
|
||
|
|
/* Instruction fnstsw is only one with strange arg. */
|
||
|
|
- if (floatop == 0xdf && codep[-1] == 0xe0)
|
||
|
|
- strcpy (op_out[0], names16[0]);
|
||
|
|
+ if (floatop == 0xdf && ins->codep[-1] == 0xe0)
|
||
|
|
+ strcpy (ins->op_out[0], ins->names16[0]);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- putop (dp->name, sizeflag);
|
||
|
|
+ putop (ins, dp->name, sizeflag);
|
||
|
|
|
||
|
|
- obufp = op_out[0];
|
||
|
|
- op_ad = 2;
|
||
|
|
+ ins->obufp = ins->op_out[0];
|
||
|
|
+ ins->op_ad = 2;
|
||
|
|
if (dp->op[0].rtn)
|
||
|
|
- (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
|
||
|
|
+ (*dp->op[0].rtn) (ins, dp->op[0].bytemode, sizeflag);
|
||
|
|
|
||
|
|
- obufp = op_out[1];
|
||
|
|
- op_ad = 1;
|
||
|
|
+ ins->obufp = ins->op_out[1];
|
||
|
|
+ ins->op_ad = 1;
|
||
|
|
if (dp->op[1].rtn)
|
||
|
|
- (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
|
||
|
|
+ (*dp->op[1].rtn) (ins, dp->op[1].bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Like oappend (below), but S is a string starting with '%'.
|
||
|
|
In Intel syntax, the '%' is elided. */
|
||
|
|
static void
|
||
|
|
-oappend_maybe_intel (const char *s)
|
||
|
|
+oappend_maybe_intel (instr_info *ins, const char *s)
|
||
|
|
{
|
||
|
|
- oappend (s + intel_syntax);
|
||
|
|
+ oappend (ins, s + ins->intel_syntax);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_ST (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- oappend_maybe_intel ("%st");
|
||
|
|
+ oappend_maybe_intel (ins, "%st");
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_STi (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- sprintf (scratchbuf, "%%st(%d)", modrm.rm);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
+ sprintf (ins->scratchbuf, "%%st(%d)", ins->modrm.rm);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Capital letters in template are macros. */
|
||
|
|
static int
|
||
|
|
-putop (const char *in_template, int sizeflag)
|
||
|
|
+putop (instr_info *ins, const char *in_template, int sizeflag)
|
||
|
|
{
|
||
|
|
const char *p;
|
||
|
|
int alt = 0;
|
||
|
|
@@ -10410,7 +10425,7 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
switch (*p)
|
||
|
|
{
|
||
|
|
default:
|
||
|
|
- *obufp++ = *p;
|
||
|
|
+ *ins->obufp++ = *p;
|
||
|
|
break;
|
||
|
|
case '%':
|
||
|
|
len++;
|
||
|
|
@@ -10419,7 +10434,7 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
cond = 0;
|
||
|
|
break;
|
||
|
|
case '{':
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
while (*++p != '|')
|
||
|
|
if (*p == '}' || *p == '\0')
|
||
|
|
@@ -10438,29 +10453,29 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
alt = 0;
|
||
|
|
break;
|
||
|
|
case 'A':
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
- if ((need_modrm && modrm.mod != 3)
|
||
|
|
+ if ((ins->need_modrm && ins->modrm.mod != 3)
|
||
|
|
|| (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
break;
|
||
|
|
case 'B':
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
case_B:
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
if (sizeflag & SUFFIX_ALWAYS)
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'L')
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit
|
||
|
|
- && !(prefixes & PREFIX_ADDR))
|
||
|
|
+ if (ins->address_mode == mode_64bit
|
||
|
|
+ && !(ins->prefixes & PREFIX_ADDR))
|
||
|
|
{
|
||
|
|
- *obufp++ = 'a';
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
- *obufp++ = 's';
|
||
|
|
+ *ins->obufp++ = 'a';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 's';
|
||
|
|
}
|
||
|
|
|
||
|
|
goto case_B;
|
||
|
|
@@ -10469,109 +10484,110 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
abort ();
|
||
|
|
break;
|
||
|
|
case 'C':
|
||
|
|
- if (intel_syntax && !alt)
|
||
|
|
+ if (ins->intel_syntax && !alt)
|
||
|
|
break;
|
||
|
|
- if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = intel_syntax ? 'd' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax ? 'd' : 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = intel_syntax ? 'w' : 's';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax ? 'w' : 's';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 'D':
|
||
|
|
- if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ if (ins->intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
|
||
|
|
break;
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
{
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = intel_syntax ? 'd' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax ? 'd' : 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
break;
|
||
|
|
case 'E': /* For jcxz/jecxz */
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
if (sizeflag & AFLAG)
|
||
|
|
- *obufp++ = 'r';
|
||
|
|
+ *ins->obufp++ = 'r';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'e';
|
||
|
|
+ *ins->obufp++ = 'e';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if (sizeflag & AFLAG)
|
||
|
|
- *obufp++ = 'e';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_ADDR);
|
||
|
|
+ *ins->obufp++ = 'e';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_ADDR);
|
||
|
|
break;
|
||
|
|
case 'F':
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
- if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ if ((ins->prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
{
|
||
|
|
if (sizeflag & AFLAG)
|
||
|
|
- *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->address_mode == mode_64bit ? 'q' : 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_ADDR);
|
||
|
|
+ *ins->obufp++ = ins->address_mode == mode_64bit ? 'l' : 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_ADDR);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 'G':
|
||
|
|
- if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
+ if (ins->intel_syntax || (ins->obufp[-1] != 's'
|
||
|
|
+ && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
break;
|
||
|
|
- if ((rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
- *obufp++ = 'l';
|
||
|
|
+ if ((ins->rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
+ *ins->obufp++ = 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case 'H':
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
- if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
|
||
|
|
- || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
|
||
|
|
+ if ((ins->prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
|
||
|
|
+ || (ins->prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
|
||
|
|
{
|
||
|
|
- used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
|
||
|
|
- *obufp++ = ',';
|
||
|
|
- *obufp++ = 'p';
|
||
|
|
+ ins->used_prefixes |= ins->prefixes & (PREFIX_CS | PREFIX_DS);
|
||
|
|
+ *ins->obufp++ = ',';
|
||
|
|
+ *ins->obufp++ = 'p';
|
||
|
|
|
||
|
|
/* Set active_seg_prefix even if not set in 64-bit mode
|
||
|
|
because here it is a valid branch hint. */
|
||
|
|
- if (prefixes & PREFIX_DS)
|
||
|
|
+ if (ins->prefixes & PREFIX_DS)
|
||
|
|
{
|
||
|
|
- active_seg_prefix = PREFIX_DS;
|
||
|
|
- *obufp++ = 't';
|
||
|
|
+ ins->active_seg_prefix = PREFIX_DS;
|
||
|
|
+ *ins->obufp++ = 't';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- active_seg_prefix = PREFIX_CS;
|
||
|
|
- *obufp++ = 'n';
|
||
|
|
+ ins->active_seg_prefix = PREFIX_CS;
|
||
|
|
+ *ins->obufp++ = 'n';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'X')
|
||
|
|
{
|
||
|
|
- if (vex.w == 0)
|
||
|
|
- *obufp++ = 'h';
|
||
|
|
+ if (ins->vex.w == 0)
|
||
|
|
+ *ins->obufp++ = 'h';
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- *obufp++ = '{';
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
- *obufp++ = 'a';
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
- *obufp++ = '}';
|
||
|
|
+ *ins->obufp++ = '{';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 'a';
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
+ *ins->obufp++ = '}';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
@@ -10579,79 +10595,79 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
break;
|
||
|
|
case 'K':
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
break;
|
||
|
|
case 'L':
|
||
|
|
abort ();
|
||
|
|
case 'M':
|
||
|
|
- if (intel_mnemonic != cond)
|
||
|
|
- *obufp++ = 'r';
|
||
|
|
+ if (ins->intel_mnemonic != cond)
|
||
|
|
+ *ins->obufp++ = 'r';
|
||
|
|
break;
|
||
|
|
case 'N':
|
||
|
|
- if ((prefixes & PREFIX_FWAIT) == 0)
|
||
|
|
- *obufp++ = 'n';
|
||
|
|
+ if ((ins->prefixes & PREFIX_FWAIT) == 0)
|
||
|
|
+ *ins->obufp++ = 'n';
|
||
|
|
else
|
||
|
|
- used_prefixes |= PREFIX_FWAIT;
|
||
|
|
+ ins->used_prefixes |= PREFIX_FWAIT;
|
||
|
|
break;
|
||
|
|
case 'O':
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'o';
|
||
|
|
- else if (intel_syntax && (sizeflag & DFLAG))
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'o';
|
||
|
|
+ else if (ins->intel_syntax && (sizeflag & DFLAG))
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case '@':
|
||
|
|
- if (address_mode == mode_64bit
|
||
|
|
- && (isa64 == intel64 || (rex & REX_W)
|
||
|
|
- || !(prefixes & PREFIX_DATA)))
|
||
|
|
+ if (ins->address_mode == mode_64bit
|
||
|
|
+ && (ins->isa64 == intel64 || (ins->rex & REX_W)
|
||
|
|
+ || !(ins->prefixes & PREFIX_DATA)))
|
||
|
|
{
|
||
|
|
if (sizeflag & SUFFIX_ALWAYS)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
case 'P':
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
- if ((modrm.mod == 3 || !cond)
|
||
|
|
+ if ((ins->modrm.mod == 3 || !cond)
|
||
|
|
&& !(sizeflag & SUFFIX_ALWAYS))
|
||
|
|
break;
|
||
|
|
/* Fall through. */
|
||
|
|
case 'T':
|
||
|
|
- if ((!(rex & REX_W) && (prefixes & PREFIX_DATA))
|
||
|
|
+ if ((!(ins->rex & REX_W) && (ins->prefixes & PREFIX_DATA))
|
||
|
|
|| ((sizeflag & SUFFIX_ALWAYS)
|
||
|
|
- && address_mode != mode_64bit))
|
||
|
|
+ && ins->address_mode != mode_64bit))
|
||
|
|
{
|
||
|
|
- *obufp++ = (sizeflag & DFLAG) ?
|
||
|
|
- intel_syntax ? 'd' : 'l' : 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = (sizeflag & DFLAG)
|
||
|
|
+ ? ins->intel_syntax ? 'd' : 'l' : 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
else if (sizeflag & SUFFIX_ALWAYS)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'L')
|
||
|
|
{
|
||
|
|
- if ((prefixes & PREFIX_DATA)
|
||
|
|
- || (rex & REX_W)
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA)
|
||
|
|
+ || (ins->rex & REX_W)
|
||
|
|
|| (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
{
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = intel_syntax ? 'd' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax ? 'd' : 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -10661,90 +10677,90 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
case 'Q':
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
- if (intel_syntax && !alt)
|
||
|
|
+ if (ins->intel_syntax && !alt)
|
||
|
|
break;
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if ((need_modrm && modrm.mod != 3)
|
||
|
|
+ if ((ins->need_modrm && ins->modrm.mod != 3)
|
||
|
|
|| (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
{
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = intel_syntax ? 'd' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax ? 'd' : 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'D')
|
||
|
|
- *obufp++ = vex.w ? 'q' : 'd';
|
||
|
|
+ *ins->obufp++ = ins->vex.w ? 'q' : 'd';
|
||
|
|
else if (l == 1 && last[0] == 'L')
|
||
|
|
{
|
||
|
|
- if (cond ? modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)
|
||
|
|
- : address_mode != mode_64bit)
|
||
|
|
+ if (cond ? ins->modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)
|
||
|
|
+ : ins->address_mode != mode_64bit)
|
||
|
|
break;
|
||
|
|
- if ((rex & REX_W))
|
||
|
|
+ if ((ins->rex & REX_W))
|
||
|
|
{
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
}
|
||
|
|
- else if((address_mode == mode_64bit && cond)
|
||
|
|
+ else if ((ins->address_mode == mode_64bit && cond)
|
||
|
|
|| (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
- *obufp++ = intel_syntax? 'd' : 'l';
|
||
|
|
+ *ins->obufp++ = ins->intel_syntax? 'd' : 'l';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
abort ();
|
||
|
|
break;
|
||
|
|
case 'R':
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else if (sizeflag & DFLAG)
|
||
|
|
{
|
||
|
|
- if (intel_syntax)
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'l';
|
||
|
|
+ *ins->obufp++ = 'l';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- if (intel_syntax && !p[1]
|
||
|
|
- && ((rex & REX_W) || (sizeflag & DFLAG)))
|
||
|
|
- *obufp++ = 'e';
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ if (ins->intel_syntax && !p[1]
|
||
|
|
+ && ((ins->rex & REX_W) || (sizeflag & DFLAG)))
|
||
|
|
+ *ins->obufp++ = 'e';
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case 'S':
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
case_S:
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
if (sizeflag & SUFFIX_ALWAYS)
|
||
|
|
{
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = 'l';
|
||
|
|
+ *ins->obufp++ = 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'L')
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit
|
||
|
|
- && !(prefixes & PREFIX_ADDR))
|
||
|
|
+ if (ins->address_mode == mode_64bit
|
||
|
|
+ && !(ins->prefixes & PREFIX_ADDR))
|
||
|
|
{
|
||
|
|
- *obufp++ = 'a';
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
- *obufp++ = 's';
|
||
|
|
+ *ins->obufp++ = 'a';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 's';
|
||
|
|
}
|
||
|
|
|
||
|
|
goto case_S;
|
||
|
|
@@ -10760,17 +10776,17 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
{
|
||
|
|
if (last[0] == 'X')
|
||
|
|
{
|
||
|
|
- *obufp++ = '{';
|
||
|
|
- *obufp++ = 'v';
|
||
|
|
- *obufp++ = 'e';
|
||
|
|
- *obufp++ = 'x';
|
||
|
|
- *obufp++ = '}';
|
||
|
|
+ *ins->obufp++ = '{';
|
||
|
|
+ *ins->obufp++ = 'v';
|
||
|
|
+ *ins->obufp++ = 'e';
|
||
|
|
+ *ins->obufp++ = 'x';
|
||
|
|
+ *ins->obufp++ = '}';
|
||
|
|
}
|
||
|
|
- else if (rex & REX_W)
|
||
|
|
+ else if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
- *obufp++ = 'a';
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
- *obufp++ = 's';
|
||
|
|
+ *ins->obufp++ = 'a';
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
+ *ins->obufp++ = 's';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
@@ -10781,28 +10797,28 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
{
|
||
|
|
/* operand size flag for cwtl, cbtw */
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
- if (intel_syntax)
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'l';
|
||
|
|
+ *ins->obufp++ = 'l';
|
||
|
|
}
|
||
|
|
else if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'b';
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'b';
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
else if (l == 1)
|
||
|
|
{
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
if (last[0] == 'X')
|
||
|
|
- *obufp++ = vex.w ? 'd': 's';
|
||
|
|
+ *ins->obufp++ = ins->vex.w ? 'd': 's';
|
||
|
|
else if (last[0] == 'B')
|
||
|
|
- *obufp++ = vex.w ? 'w': 'b';
|
||
|
|
+ *ins->obufp++ = ins->vex.w ? 'w': 'b';
|
||
|
|
else
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
@@ -10812,34 +10828,35 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
case 'X':
|
||
|
|
if (l != 0)
|
||
|
|
abort ();
|
||
|
|
- if (need_vex
|
||
|
|
- ? vex.prefix == DATA_PREFIX_OPCODE
|
||
|
|
- : prefixes & PREFIX_DATA)
|
||
|
|
+ if (ins->need_vex
|
||
|
|
+ ? ins->vex.prefix == DATA_PREFIX_OPCODE
|
||
|
|
+ : ins->prefixes & PREFIX_DATA)
|
||
|
|
{
|
||
|
|
- *obufp++ = 'd';
|
||
|
|
- used_prefixes |= PREFIX_DATA;
|
||
|
|
+ *ins->obufp++ = 'd';
|
||
|
|
+ ins->used_prefixes |= PREFIX_DATA;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- *obufp++ = 's';
|
||
|
|
+ *ins->obufp++ = 's';
|
||
|
|
break;
|
||
|
|
case 'Y':
|
||
|
|
if (l == 1 && last[0] == 'X')
|
||
|
|
{
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
- if (intel_syntax
|
||
|
|
- || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
+ if (ins->intel_syntax
|
||
|
|
+ || ((ins->modrm.mod == 3 || ins->vex.b)
|
||
|
|
+ && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
break;
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- *obufp++ = 'x';
|
||
|
|
+ *ins->obufp++ = 'x';
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- *obufp++ = 'y';
|
||
|
|
+ *ins->obufp++ = 'y';
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- if (!vex.evex)
|
||
|
|
+ if (!ins->vex.evex)
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
@@ -10851,27 +10868,28 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
if (l == 0)
|
||
|
|
{
|
||
|
|
/* These insns ignore ModR/M.mod: Force it to 3 for OP_E(). */
|
||
|
|
- modrm.mod = 3;
|
||
|
|
- if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
- *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
|
||
|
|
+ ins->modrm.mod = 3;
|
||
|
|
+ if (!ins->intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ *ins->obufp++ = ins->address_mode == mode_64bit ? 'q' : 'l';
|
||
|
|
}
|
||
|
|
else if (l == 1 && last[0] == 'X')
|
||
|
|
{
|
||
|
|
- if (!vex.evex)
|
||
|
|
+ if (!ins->vex.evex)
|
||
|
|
abort ();
|
||
|
|
- if (intel_syntax
|
||
|
|
- || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
+ if (ins->intel_syntax
|
||
|
|
+ || ((ins->modrm.mod == 3 || ins->vex.b)
|
||
|
|
+ && !(sizeflag & SUFFIX_ALWAYS)))
|
||
|
|
break;
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- *obufp++ = 'x';
|
||
|
|
+ *ins->obufp++ = 'x';
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- *obufp++ = 'y';
|
||
|
|
+ *ins->obufp++ = 'y';
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- *obufp++ = 'z';
|
||
|
|
+ *ins->obufp++ = 'z';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -10881,21 +10899,21 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
abort ();
|
||
|
|
break;
|
||
|
|
case '^':
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
break;
|
||
|
|
- if (isa64 == intel64 && (rex & REX_W))
|
||
|
|
+ if (ins->isa64 == intel64 && (ins->rex & REX_W))
|
||
|
|
{
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- *obufp++ = 'q';
|
||
|
|
+ *ins->obufp++ = 'q';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- *obufp++ = 'l';
|
||
|
|
+ *ins->obufp++ = 'l';
|
||
|
|
else
|
||
|
|
- *obufp++ = 'w';
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ *ins->obufp++ = 'w';
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
@@ -10903,44 +10921,44 @@ putop (const char *in_template, int sizeflag)
|
||
|
|
if (len == l)
|
||
|
|
len = l = 0;
|
||
|
|
}
|
||
|
|
- *obufp = 0;
|
||
|
|
- mnemonicendp = obufp;
|
||
|
|
+ *ins->obufp = 0;
|
||
|
|
+ ins->mnemonicendp = ins->obufp;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-oappend (const char *s)
|
||
|
|
+oappend (instr_info *ins, const char *s)
|
||
|
|
{
|
||
|
|
- obufp = stpcpy (obufp, s);
|
||
|
|
+ ins->obufp = stpcpy (ins->obufp, s);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-append_seg (void)
|
||
|
|
+append_seg (instr_info *ins)
|
||
|
|
{
|
||
|
|
/* Only print the active segment register. */
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
return;
|
||
|
|
|
||
|
|
- used_prefixes |= active_seg_prefix;
|
||
|
|
- switch (active_seg_prefix)
|
||
|
|
+ ins->used_prefixes |= ins->active_seg_prefix;
|
||
|
|
+ switch (ins->active_seg_prefix)
|
||
|
|
{
|
||
|
|
case PREFIX_CS:
|
||
|
|
- oappend_maybe_intel ("%cs:");
|
||
|
|
+ oappend_maybe_intel (ins, "%cs:");
|
||
|
|
break;
|
||
|
|
case PREFIX_DS:
|
||
|
|
- oappend_maybe_intel ("%ds:");
|
||
|
|
+ oappend_maybe_intel (ins, "%ds:");
|
||
|
|
break;
|
||
|
|
case PREFIX_SS:
|
||
|
|
- oappend_maybe_intel ("%ss:");
|
||
|
|
+ oappend_maybe_intel (ins, "%ss:");
|
||
|
|
break;
|
||
|
|
case PREFIX_ES:
|
||
|
|
- oappend_maybe_intel ("%es:");
|
||
|
|
+ oappend_maybe_intel (ins, "%es:");
|
||
|
|
break;
|
||
|
|
case PREFIX_FS:
|
||
|
|
- oappend_maybe_intel ("%fs:");
|
||
|
|
+ oappend_maybe_intel (ins, "%fs:");
|
||
|
|
break;
|
||
|
|
case PREFIX_GS:
|
||
|
|
- oappend_maybe_intel ("%gs:");
|
||
|
|
+ oappend_maybe_intel (ins, "%gs:");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
@@ -10948,17 +10966,17 @@ append_seg (void)
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_indirE (int bytemode, int sizeflag)
|
||
|
|
+OP_indirE (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (!intel_syntax)
|
||
|
|
- oappend ("*");
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
+ oappend (ins, "*");
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-print_operand_value (char *buf, int hex, bfd_vma disp)
|
||
|
|
+print_operand_value (instr_info *ins, char *buf, int hex, bfd_vma disp)
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
if (hex)
|
||
|
|
{
|
||
|
|
@@ -11015,7 +11033,7 @@ print_operand_value (char *buf, int hex, bfd_vma disp)
|
||
|
|
/* Put DISP in BUF as signed hex number. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-print_displacement (char *buf, bfd_vma disp)
|
||
|
|
+print_displacement (instr_info *ins, char *buf, bfd_vma disp)
|
||
|
|
{
|
||
|
|
bfd_signed_vma val = disp;
|
||
|
|
char tmp[30];
|
||
|
|
@@ -11029,7 +11047,7 @@ print_displacement (char *buf, bfd_vma disp)
|
||
|
|
/* Check for possible overflow. */
|
||
|
|
if (val < 0)
|
||
|
|
{
|
||
|
|
- switch (address_mode)
|
||
|
|
+ switch (ins->address_mode)
|
||
|
|
{
|
||
|
|
case mode_64bit:
|
||
|
|
strcpy (buf + j, "0x8000000000000000");
|
||
|
|
@@ -11057,27 +11075,27 @@ print_displacement (char *buf, bfd_vma disp)
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
+intel_operand_size (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (vex.b)
|
||
|
|
+ if (ins->vex.b)
|
||
|
|
{
|
||
|
|
- if (!vex.no_broadcast)
|
||
|
|
+ if (!ins->vex.no_broadcast)
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case x_mode:
|
||
|
|
case evex_half_bcst_xmmq_mode:
|
||
|
|
- if (vex.w)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case xh_mode:
|
||
|
|
case evex_half_bcst_xmmqh_mode:
|
||
|
|
case evex_half_bcst_xmmqdh_mode:
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- vex.no_broadcast = 1;
|
||
|
|
+ ins->vex.no_broadcast = 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
@@ -11087,24 +11105,25 @@ intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
case b_mode:
|
||
|
|
case b_swap_mode:
|
||
|
|
case db_mode:
|
||
|
|
- oappend ("BYTE PTR ");
|
||
|
|
+ oappend (ins, "BYTE PTR ");
|
||
|
|
break;
|
||
|
|
case w_mode:
|
||
|
|
case w_swap_mode:
|
||
|
|
case dw_mode:
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
break;
|
||
|
|
case indir_v_mode:
|
||
|
|
- if (address_mode == mode_64bit && isa64 == intel64)
|
||
|
|
+ if (ins->address_mode == mode_64bit && ins->isa64 == intel64)
|
||
|
|
{
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
case stack_v_mode:
|
||
|
|
- if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
|
||
|
|
+ if (ins->address_mode == mode_64bit && ((sizeflag & DFLAG)
|
||
|
|
+ || (ins->rex & REX_W)))
|
||
|
|
{
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
@@ -11112,63 +11131,63 @@ intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
case v_swap_mode:
|
||
|
|
case dq_mode:
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else if (bytemode == dq_mode)
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case z_mode:
|
||
|
|
- if ((rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
- *obufp++ = 'D';
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ if ((ins->rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
+ *ins->obufp++ = 'D';
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case a_mode:
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case movsxd_mode:
|
||
|
|
- if (!(sizeflag & DFLAG) && isa64 == intel64)
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
+ if (!(sizeflag & DFLAG) && ins->isa64 == intel64)
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case d_mode:
|
||
|
|
case d_swap_mode:
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case q_mode:
|
||
|
|
case q_swap_mode:
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
case m_mode:
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case f_mode:
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- oappend ("FWORD PTR ");
|
||
|
|
+ oappend (ins, "FWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case t_mode:
|
||
|
|
- oappend ("TBYTE PTR ");
|
||
|
|
+ oappend (ins, "TBYTE PTR ");
|
||
|
|
break;
|
||
|
|
case x_mode:
|
||
|
|
case xh_mode:
|
||
|
|
@@ -11176,67 +11195,67 @@ intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
case evex_x_gscat_mode:
|
||
|
|
case evex_x_nobcst_mode:
|
||
|
|
case bw_unit_mode:
|
||
|
|
- if (need_vex)
|
||
|
|
+ if (ins->need_vex)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("YMMWORD PTR ");
|
||
|
|
+ oappend (ins, "YMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("ZMMWORD PTR ");
|
||
|
|
+ oappend (ins, "ZMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case xmm_mode:
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case ymm_mode:
|
||
|
|
- oappend ("YMMWORD PTR ");
|
||
|
|
+ oappend (ins, "YMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case xmmq_mode:
|
||
|
|
case evex_half_bcst_xmmqh_mode:
|
||
|
|
case evex_half_bcst_xmmq_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("YMMWORD PTR ");
|
||
|
|
+ oappend (ins, "YMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case xmmdw_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -11244,85 +11263,84 @@ intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
break;
|
||
|
|
case xmmqd_mode:
|
||
|
|
case evex_half_bcst_xmmqdh_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case ymmq_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("YMMWORD PTR ");
|
||
|
|
+ oappend (ins, "YMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("ZMMWORD PTR ");
|
||
|
|
+ oappend (ins, "ZMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case ymmxmm_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
case 256:
|
||
|
|
- oappend ("XMMWORD PTR ");
|
||
|
|
+ oappend (ins, "XMMWORD PTR ");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case o_mode:
|
||
|
|
- oappend ("OWORD PTR ");
|
||
|
|
+ oappend (ins, "OWORD PTR ");
|
||
|
|
break;
|
||
|
|
case vex_vsib_d_w_dq_mode:
|
||
|
|
case vex_vsib_q_w_dq_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
-
|
||
|
|
- if (vex.w)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
break;
|
||
|
|
case mask_bd_mode:
|
||
|
|
- if (!need_vex || vex.length != 128)
|
||
|
|
+ if (!ins->need_vex || ins->vex.length != 128)
|
||
|
|
abort ();
|
||
|
|
- if (vex.w)
|
||
|
|
- oappend ("DWORD PTR ");
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ oappend (ins, "DWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("BYTE PTR ");
|
||
|
|
+ oappend (ins, "BYTE PTR ");
|
||
|
|
break;
|
||
|
|
case mask_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
- if (vex.w)
|
||
|
|
- oappend ("QWORD PTR ");
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ oappend (ins, "QWORD PTR ");
|
||
|
|
else
|
||
|
|
- oappend ("WORD PTR ");
|
||
|
|
+ oappend (ins, "WORD PTR ");
|
||
|
|
break;
|
||
|
|
case v_bnd_mode:
|
||
|
|
case v_bndmk_mode:
|
||
|
|
@@ -11332,12 +11350,13 @@ intel_operand_size (int bytemode, int sizeflag)
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-print_register (unsigned int reg, unsigned int rexmask, int bytemode, int sizeflag)
|
||
|
|
+print_register (instr_info *ins, unsigned int reg, unsigned int rexmask,
|
||
|
|
+ int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
USED_REX (rexmask);
|
||
|
|
- if (rex & rexmask)
|
||
|
|
+ if (ins->rex & rexmask)
|
||
|
|
reg += 8;
|
||
|
|
|
||
|
|
switch (bytemode)
|
||
|
|
@@ -11346,46 +11365,47 @@ print_register (unsigned int reg, unsigned int rexmask, int bytemode, int sizefl
|
||
|
|
case b_swap_mode:
|
||
|
|
if (reg & 4)
|
||
|
|
USED_REX (0);
|
||
|
|
- if (rex)
|
||
|
|
- names = names8rex;
|
||
|
|
+ if (ins->rex)
|
||
|
|
+ names = ins->names8rex;
|
||
|
|
else
|
||
|
|
- names = names8;
|
||
|
|
+ names = ins->names8;
|
||
|
|
break;
|
||
|
|
case w_mode:
|
||
|
|
- names = names16;
|
||
|
|
+ names = ins->names16;
|
||
|
|
break;
|
||
|
|
case d_mode:
|
||
|
|
case dw_mode:
|
||
|
|
case db_mode:
|
||
|
|
- names = names32;
|
||
|
|
+ names = ins->names32;
|
||
|
|
break;
|
||
|
|
case q_mode:
|
||
|
|
- names = names64;
|
||
|
|
+ names = ins->names64;
|
||
|
|
break;
|
||
|
|
case m_mode:
|
||
|
|
case v_bnd_mode:
|
||
|
|
- names = address_mode == mode_64bit ? names64 : names32;
|
||
|
|
+ names = ins->address_mode == mode_64bit ? ins->names64 : ins->names32;
|
||
|
|
break;
|
||
|
|
case bnd_mode:
|
||
|
|
case bnd_swap_mode:
|
||
|
|
if (reg > 0x3)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- names = names_bnd;
|
||
|
|
+ names = ins->names_bnd;
|
||
|
|
break;
|
||
|
|
case indir_v_mode:
|
||
|
|
- if (address_mode == mode_64bit && isa64 == intel64)
|
||
|
|
+ if (ins->address_mode == mode_64bit && ins->isa64 == intel64)
|
||
|
|
{
|
||
|
|
- names = names64;
|
||
|
|
+ names = ins->names64;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
case stack_v_mode:
|
||
|
|
- if (address_mode == mode_64bit && ((sizeflag & DFLAG) || (rex & REX_W)))
|
||
|
|
+ if (ins->address_mode == mode_64bit && ((sizeflag & DFLAG)
|
||
|
|
+ || (ins->rex & REX_W)))
|
||
|
|
{
|
||
|
|
- names = names64;
|
||
|
|
+ names = ins->names64;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
bytemode = v_mode;
|
||
|
|
@@ -11394,68 +11414,68 @@ print_register (unsigned int reg, unsigned int rexmask, int bytemode, int sizefl
|
||
|
|
case v_swap_mode:
|
||
|
|
case dq_mode:
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- names = names64;
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ names = ins->names64;
|
||
|
|
else if (bytemode != v_mode && bytemode != v_swap_mode)
|
||
|
|
- names = names32;
|
||
|
|
+ names = ins->names32;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- names = names32;
|
||
|
|
+ names = ins->names32;
|
||
|
|
else
|
||
|
|
- names = names16;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ names = ins->names16;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case movsxd_mode:
|
||
|
|
- if (!(sizeflag & DFLAG) && isa64 == intel64)
|
||
|
|
- names = names16;
|
||
|
|
+ if (!(sizeflag & DFLAG) && ins->isa64 == intel64)
|
||
|
|
+ names = ins->names16;
|
||
|
|
else
|
||
|
|
- names = names32;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ names = ins->names32;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
case va_mode:
|
||
|
|
- names = (address_mode == mode_64bit
|
||
|
|
- ? names64 : names32);
|
||
|
|
- if (!(prefixes & PREFIX_ADDR))
|
||
|
|
- names = (address_mode == mode_16bit
|
||
|
|
- ? names16 : names);
|
||
|
|
+ names = (ins->address_mode == mode_64bit
|
||
|
|
+ ? ins->names64 : ins->names32);
|
||
|
|
+ if (!(ins->prefixes & PREFIX_ADDR))
|
||
|
|
+ names = (ins->address_mode == mode_16bit
|
||
|
|
+ ? ins->names16 : names);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Remove "addr16/addr32". */
|
||
|
|
- all_prefixes[last_addr_prefix] = 0;
|
||
|
|
- names = (address_mode != mode_32bit
|
||
|
|
- ? names32 : names16);
|
||
|
|
- used_prefixes |= PREFIX_ADDR;
|
||
|
|
+ ins->all_prefixes[ins->last_addr_prefix] = 0;
|
||
|
|
+ names = (ins->address_mode != mode_32bit
|
||
|
|
+ ? ins->names32 : ins->names16);
|
||
|
|
+ ins->used_prefixes |= PREFIX_ADDR;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case mask_bd_mode:
|
||
|
|
case mask_mode:
|
||
|
|
if (reg > 0x7)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- names = names_mask;
|
||
|
|
+ names = ins->names_mask;
|
||
|
|
break;
|
||
|
|
case 0:
|
||
|
|
return;
|
||
|
|
default:
|
||
|
|
- oappend (INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
+ oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
+OP_E_memory (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_vma disp = 0;
|
||
|
|
- int add = (rex & REX_B) ? 8 : 0;
|
||
|
|
+ int add = (ins->rex & REX_B) ? 8 : 0;
|
||
|
|
int riprel = 0;
|
||
|
|
int shift;
|
||
|
|
|
||
|
|
- if (vex.evex)
|
||
|
|
+ if (ins->vex.evex)
|
||
|
|
{
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
@@ -11469,7 +11489,7 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
shift = 0;
|
||
|
|
break;
|
||
|
|
case dq_mode:
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
{
|
||
|
|
case d_mode:
|
||
|
|
case d_swap_mode:
|
||
|
|
@@ -11480,22 +11500,22 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
case vex_vsib_d_w_dq_mode:
|
||
|
|
case vex_vsib_q_w_dq_mode:
|
||
|
|
case evex_x_gscat_mode:
|
||
|
|
- shift = vex.w ? 3 : 2;
|
||
|
|
+ shift = ins->vex.w ? 3 : 2;
|
||
|
|
break;
|
||
|
|
case xh_mode:
|
||
|
|
case evex_half_bcst_xmmqh_mode:
|
||
|
|
case evex_half_bcst_xmmqdh_mode:
|
||
|
|
- if (vex.b)
|
||
|
|
+ if (ins->vex.b)
|
||
|
|
{
|
||
|
|
- shift = vex.w ? 2 : 1;
|
||
|
|
+ shift = ins->vex.w ? 2 : 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
case x_mode:
|
||
|
|
case evex_half_bcst_xmmq_mode:
|
||
|
|
- if (vex.b)
|
||
|
|
+ if (ins->vex.b)
|
||
|
|
{
|
||
|
|
- shift = vex.w ? 3 : 2;
|
||
|
|
+ shift = ins->vex.w ? 3 : 2;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
@@ -11505,7 +11525,7 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
case ymmq_mode:
|
||
|
|
case evex_x_nobcst_mode:
|
||
|
|
case x_swap_mode:
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
shift = 4;
|
||
|
|
@@ -11523,7 +11543,7 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
if (bytemode == xmmq_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmqh_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmq_mode
|
||
|
|
- || (bytemode == ymmq_mode && vex.length == 128))
|
||
|
|
+ || (bytemode == ymmq_mode && ins->vex.length == 128))
|
||
|
|
shift -= 1;
|
||
|
|
else if (bytemode == xmmqd_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmqdh_mode)
|
||
|
|
@@ -11542,7 +11562,7 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
shift = 3;
|
||
|
|
break;
|
||
|
|
case bw_unit_mode:
|
||
|
|
- shift = vex.w ? 1 : 0;
|
||
|
|
+ shift = ins->vex.w ? 1 : 0;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -11552,11 +11572,11 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
shift = 0;
|
||
|
|
|
||
|
|
USED_REX (REX_B);
|
||
|
|
- if (intel_syntax)
|
||
|
|
- intel_operand_size (bytemode, sizeflag);
|
||
|
|
- append_seg ();
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ intel_operand_size (ins, bytemode, sizeflag);
|
||
|
|
+ append_seg (ins);
|
||
|
|
|
||
|
|
- if ((sizeflag & AFLAG) || address_mode == mode_64bit)
|
||
|
|
+ if ((sizeflag & AFLAG) || ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
/* 32/64 bit address mode */
|
||
|
|
int havedisp;
|
||
|
|
@@ -11574,53 +11594,53 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
|| bytemode == bnd_mode
|
||
|
|
|| bytemode == bnd_swap_mode);
|
||
|
|
bool check_gather = false;
|
||
|
|
- const char **indexes64 = names64;
|
||
|
|
- const char **indexes32 = names32;
|
||
|
|
+ const char **indexes64 = ins->names64;
|
||
|
|
+ const char **indexes32 = ins->names32;
|
||
|
|
|
||
|
|
havesib = 0;
|
||
|
|
havebase = 1;
|
||
|
|
haveindex = 0;
|
||
|
|
- base = modrm.rm;
|
||
|
|
+ base = ins->modrm.rm;
|
||
|
|
|
||
|
|
if (base == 4)
|
||
|
|
{
|
||
|
|
havesib = 1;
|
||
|
|
- vindex = sib.index;
|
||
|
|
+ vindex = ins->sib.index;
|
||
|
|
USED_REX (REX_X);
|
||
|
|
- if (rex & REX_X)
|
||
|
|
+ if (ins->rex & REX_X)
|
||
|
|
vindex += 8;
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case vex_vsib_d_w_dq_mode:
|
||
|
|
case vex_vsib_q_w_dq_mode:
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
- if (vex.evex)
|
||
|
|
+ if (ins->vex.evex)
|
||
|
|
{
|
||
|
|
- if (!vex.v)
|
||
|
|
+ if (!ins->vex.v)
|
||
|
|
vindex += 16;
|
||
|
|
- check_gather = obufp == op_out[1];
|
||
|
|
+ check_gather = ins->obufp == ins->op_out[1];
|
||
|
|
}
|
||
|
|
|
||
|
|
haveindex = 1;
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- indexes64 = indexes32 = names_xmm;
|
||
|
|
+ indexes64 = indexes32 = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- if (!vex.w
|
||
|
|
+ if (!ins->vex.w
|
||
|
|
|| bytemode == vex_vsib_q_w_dq_mode)
|
||
|
|
- indexes64 = indexes32 = names_ymm;
|
||
|
|
+ indexes64 = indexes32 = ins->names_ymm;
|
||
|
|
else
|
||
|
|
- indexes64 = indexes32 = names_xmm;
|
||
|
|
+ indexes64 = indexes32 = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- if (!vex.w
|
||
|
|
+ if (!ins->vex.w
|
||
|
|
|| bytemode == vex_vsib_q_w_dq_mode)
|
||
|
|
- indexes64 = indexes32 = names_zmm;
|
||
|
|
+ indexes64 = indexes32 = ins->names_zmm;
|
||
|
|
else
|
||
|
|
- indexes64 = indexes32 = names_ymm;
|
||
|
|
+ indexes64 = indexes32 = ins->names_ymm;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -11630,9 +11650,9 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
haveindex = vindex != 4;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- scale = sib.scale;
|
||
|
|
- base = sib.base;
|
||
|
|
- codep++;
|
||
|
|
+ scale = ins->sib.scale;
|
||
|
|
+ base = ins->sib.base;
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
@@ -11641,38 +11661,38 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
|| bytemode == vex_vsib_q_w_dq_mode
|
||
|
|
|| bytemode == vex_sibmem_mode)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
rbase = base + add;
|
||
|
|
|
||
|
|
- switch (modrm.mod)
|
||
|
|
+ switch (ins->modrm.mod)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
if (base == 5)
|
||
|
|
{
|
||
|
|
havebase = 0;
|
||
|
|
- if (address_mode == mode_64bit && !havesib)
|
||
|
|
+ if (ins->address_mode == mode_64bit && !havesib)
|
||
|
|
riprel = 1;
|
||
|
|
- disp = get32s ();
|
||
|
|
+ disp = get32s (ins);
|
||
|
|
if (riprel && bytemode == v_bndmk_mode)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- disp = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ disp = *ins->codep++;
|
||
|
|
if ((disp & 0x80) != 0)
|
||
|
|
disp -= 0x100;
|
||
|
|
- if (vex.evex && shift > 0)
|
||
|
|
+ if (ins->vex.evex && shift > 0)
|
||
|
|
disp <<= shift;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- disp = get32s ();
|
||
|
|
+ disp = get32s (ins);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -11681,9 +11701,9 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
if (havesib
|
||
|
|
&& !havebase
|
||
|
|
&& !haveindex
|
||
|
|
- && address_mode != mode_16bit)
|
||
|
|
+ && ins->address_mode != mode_16bit)
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
if (addr32flag)
|
||
|
|
{
|
||
|
|
@@ -11706,41 +11726,41 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
|| needindex
|
||
|
|
|| (havesib && (haveindex || scale != 0)));
|
||
|
|
|
||
|
|
- if (!intel_syntax)
|
||
|
|
- if (modrm.mod != 0 || base == 5)
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
+ if (ins->modrm.mod != 0 || base == 5)
|
||
|
|
{
|
||
|
|
if (havedisp || riprel)
|
||
|
|
- print_displacement (scratchbuf, disp);
|
||
|
|
+ print_displacement (ins, ins->scratchbuf, disp);
|
||
|
|
else
|
||
|
|
- print_operand_value (scratchbuf, 1, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
if (riprel)
|
||
|
|
{
|
||
|
|
- set_op (disp, 1);
|
||
|
|
- oappend (!addr32flag ? "(%rip)" : "(%eip)");
|
||
|
|
+ set_op (ins, disp, 1);
|
||
|
|
+ oappend (ins, !addr32flag ? "(%rip)" : "(%eip)");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((havebase || haveindex || needindex || needaddr32 || riprel)
|
||
|
|
- && (address_mode != mode_64bit
|
||
|
|
+ && (ins->address_mode != mode_64bit
|
||
|
|
|| ((bytemode != v_bnd_mode)
|
||
|
|
&& (bytemode != v_bndmk_mode)
|
||
|
|
&& (bytemode != bnd_mode)
|
||
|
|
&& (bytemode != bnd_swap_mode))))
|
||
|
|
- used_prefixes |= PREFIX_ADDR;
|
||
|
|
+ ins->used_prefixes |= PREFIX_ADDR;
|
||
|
|
|
||
|
|
- if (havedisp || (intel_syntax && riprel))
|
||
|
|
+ if (havedisp || (ins->intel_syntax && riprel))
|
||
|
|
{
|
||
|
|
- *obufp++ = open_char;
|
||
|
|
- if (intel_syntax && riprel)
|
||
|
|
+ *ins->obufp++ = ins->open_char;
|
||
|
|
+ if (ins->intel_syntax && riprel)
|
||
|
|
{
|
||
|
|
- set_op (disp, 1);
|
||
|
|
- oappend (!addr32flag ? "rip" : "eip");
|
||
|
|
+ set_op (ins, disp, 1);
|
||
|
|
+ oappend (ins, !addr32flag ? "rip" : "eip");
|
||
|
|
}
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
if (havebase)
|
||
|
|
- oappend (address_mode == mode_64bit && !addr32flag
|
||
|
|
- ? names64[rbase] : names32[rbase]);
|
||
|
|
+ oappend (ins, ins->address_mode == mode_64bit && !addr32flag
|
||
|
|
+ ? ins->names64[rbase] : ins->names32[rbase]);
|
||
|
|
if (havesib)
|
||
|
|
{
|
||
|
|
/* ESP/RSP won't allow index. If base isn't ESP/RSP,
|
||
|
|
@@ -11750,78 +11770,79 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
|| haveindex
|
||
|
|
|| (havebase && base != ESP_REG_NUM))
|
||
|
|
{
|
||
|
|
- if (!intel_syntax || havebase)
|
||
|
|
+ if (!ins->intel_syntax || havebase)
|
||
|
|
{
|
||
|
|
- *obufp++ = separator_char;
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp++ = ins->separator_char;
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
}
|
||
|
|
if (haveindex)
|
||
|
|
{
|
||
|
|
- if (address_mode == mode_64bit || vindex < 16)
|
||
|
|
- oappend (address_mode == mode_64bit && !addr32flag
|
||
|
|
+ if (ins->address_mode == mode_64bit || vindex < 16)
|
||
|
|
+ oappend (ins, ins->address_mode == mode_64bit
|
||
|
|
+ && !addr32flag
|
||
|
|
? indexes64[vindex] : indexes32[vindex]);
|
||
|
|
else
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- oappend (address_mode == mode_64bit && !addr32flag
|
||
|
|
- ? index64 : index32);
|
||
|
|
+ oappend (ins, ins->address_mode == mode_64bit && !addr32flag
|
||
|
|
+ ? ins->index64 : ins->index32);
|
||
|
|
|
||
|
|
- *obufp++ = scale_char;
|
||
|
|
- *obufp = '\0';
|
||
|
|
- sprintf (scratchbuf, "%d", 1 << scale);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ *ins->obufp++ = ins->scale_char;
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
+ sprintf (ins->scratchbuf, "%d", 1 << scale);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- if (intel_syntax
|
||
|
|
- && (disp || modrm.mod != 0 || base == 5))
|
||
|
|
+ if (ins->intel_syntax
|
||
|
|
+ && (disp || ins->modrm.mod != 0 || base == 5))
|
||
|
|
{
|
||
|
|
if (!havedisp || (bfd_signed_vma) disp >= 0)
|
||
|
|
{
|
||
|
|
- *obufp++ = '+';
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp++ = '+';
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
}
|
||
|
|
- else if (modrm.mod != 1 && disp != -disp)
|
||
|
|
+ else if (ins->modrm.mod != 1 && disp != -disp)
|
||
|
|
{
|
||
|
|
- *obufp++ = '-';
|
||
|
|
- *obufp = '\0';
|
||
|
|
- disp = -disp;
|
||
|
|
+ *ins->obufp++ = '-';
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
+ disp = - (bfd_signed_vma) disp;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (havedisp)
|
||
|
|
- print_displacement (scratchbuf, disp);
|
||
|
|
+ print_displacement (ins, ins->scratchbuf, disp);
|
||
|
|
else
|
||
|
|
- print_operand_value (scratchbuf, 1, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
- *obufp++ = close_char;
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp++ = ins->close_char;
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
|
||
|
|
if (check_gather)
|
||
|
|
{
|
||
|
|
/* Both XMM/YMM/ZMM registers must be distinct. */
|
||
|
|
- int modrm_reg = modrm.reg;
|
||
|
|
+ int modrm_reg = ins->modrm.reg;
|
||
|
|
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
modrm_reg += 8;
|
||
|
|
- if (!vex.r)
|
||
|
|
+ if (!ins->vex.r)
|
||
|
|
modrm_reg += 16;
|
||
|
|
if (vindex == modrm_reg)
|
||
|
|
- oappend ("/(bad)");
|
||
|
|
+ oappend (ins, "/(bad)");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- else if (intel_syntax)
|
||
|
|
+ else if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 0 || base == 5)
|
||
|
|
+ if (ins->modrm.mod != 0 || base == 5)
|
||
|
|
{
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
{
|
||
|
|
- oappend (names_seg[ds_reg - es_reg]);
|
||
|
|
- oappend (":");
|
||
|
|
+ oappend (ins, ins->names_seg[ds_reg - es_reg]);
|
||
|
|
+ oappend (ins, ":");
|
||
|
|
}
|
||
|
|
- print_operand_value (scratchbuf, 1, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -11832,124 +11853,124 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
|| bytemode == vex_vsib_d_w_dq_mode
|
||
|
|
|| bytemode == vex_vsib_q_w_dq_mode)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* 16 bit address mode */
|
||
|
|
- used_prefixes |= prefixes & PREFIX_ADDR;
|
||
|
|
- switch (modrm.mod)
|
||
|
|
+ ins->used_prefixes |= ins->prefixes & PREFIX_ADDR;
|
||
|
|
+ switch (ins->modrm.mod)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
- if (modrm.rm == 6)
|
||
|
|
+ if (ins->modrm.rm == 6)
|
||
|
|
{
|
||
|
|
- disp = get16 ();
|
||
|
|
+ disp = get16 (ins);
|
||
|
|
if ((disp & 0x8000) != 0)
|
||
|
|
disp -= 0x10000;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- disp = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ disp = *ins->codep++;
|
||
|
|
if ((disp & 0x80) != 0)
|
||
|
|
disp -= 0x100;
|
||
|
|
- if (vex.evex && shift > 0)
|
||
|
|
+ if (ins->vex.evex && shift > 0)
|
||
|
|
disp <<= shift;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
- disp = get16 ();
|
||
|
|
+ disp = get16 (ins);
|
||
|
|
if ((disp & 0x8000) != 0)
|
||
|
|
disp -= 0x10000;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (!intel_syntax)
|
||
|
|
- if (modrm.mod != 0 || modrm.rm == 6)
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
+ if (ins->modrm.mod != 0 || ins->modrm.rm == 6)
|
||
|
|
{
|
||
|
|
- print_displacement (scratchbuf, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_displacement (ins, ins->scratchbuf, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (modrm.mod != 0 || modrm.rm != 6)
|
||
|
|
+ if (ins->modrm.mod != 0 || ins->modrm.rm != 6)
|
||
|
|
{
|
||
|
|
- *obufp++ = open_char;
|
||
|
|
- *obufp = '\0';
|
||
|
|
- oappend (index16[modrm.rm]);
|
||
|
|
- if (intel_syntax
|
||
|
|
- && (disp || modrm.mod != 0 || modrm.rm == 6))
|
||
|
|
+ *ins->obufp++ = ins->open_char;
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
+ oappend (ins, ins->index16[ins->modrm.rm]);
|
||
|
|
+ if (ins->intel_syntax
|
||
|
|
+ && (disp || ins->modrm.mod != 0 || ins->modrm.rm == 6))
|
||
|
|
{
|
||
|
|
if ((bfd_signed_vma) disp >= 0)
|
||
|
|
{
|
||
|
|
- *obufp++ = '+';
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp++ = '+';
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
}
|
||
|
|
- else if (modrm.mod != 1)
|
||
|
|
+ else if (ins->modrm.mod != 1)
|
||
|
|
{
|
||
|
|
- *obufp++ = '-';
|
||
|
|
- *obufp = '\0';
|
||
|
|
- disp = -disp;
|
||
|
|
+ *ins->obufp++ = '-';
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
+ disp = - (bfd_signed_vma) disp;
|
||
|
|
}
|
||
|
|
|
||
|
|
- print_displacement (scratchbuf, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_displacement (ins, ins->scratchbuf, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
- *obufp++ = close_char;
|
||
|
|
- *obufp = '\0';
|
||
|
|
+ *ins->obufp++ = ins->close_char;
|
||
|
|
+ *ins->obufp = '\0';
|
||
|
|
}
|
||
|
|
- else if (intel_syntax)
|
||
|
|
+ else if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
{
|
||
|
|
- oappend (names_seg[ds_reg - es_reg]);
|
||
|
|
- oappend (":");
|
||
|
|
+ oappend (ins, ins->names_seg[ds_reg - es_reg]);
|
||
|
|
+ oappend (ins, ":");
|
||
|
|
}
|
||
|
|
- print_operand_value (scratchbuf, 1, disp & 0xffff);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, disp & 0xffff);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- if (vex.b)
|
||
|
|
+ if (ins->vex.b)
|
||
|
|
{
|
||
|
|
- evex_used |= EVEX_b_used;
|
||
|
|
- if (!vex.no_broadcast)
|
||
|
|
+ ins->evex_used |= EVEX_b_used;
|
||
|
|
+ if (!ins->vex.no_broadcast)
|
||
|
|
{
|
||
|
|
if (bytemode == xh_mode)
|
||
|
|
{
|
||
|
|
- if (vex.w)
|
||
|
|
- oappend ("{bad}");
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
+ oappend (ins, "{bad}");
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("{1to8}");
|
||
|
|
+ oappend (ins, "{1to8}");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("{1to16}");
|
||
|
|
+ oappend (ins, "{1to16}");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("{1to32}");
|
||
|
|
+ oappend (ins, "{1to32}");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- else if (vex.w
|
||
|
|
+ else if (ins->vex.w
|
||
|
|
|| bytemode == evex_half_bcst_xmmqdh_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmq_mode)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("{1to2}");
|
||
|
|
+ oappend (ins, "{1to2}");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("{1to4}");
|
||
|
|
+ oappend (ins, "{1to4}");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("{1to8}");
|
||
|
|
+ oappend (ins, "{1to8}");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -11958,146 +11979,150 @@ OP_E_memory (int bytemode, int sizeflag)
|
||
|
|
else if (bytemode == x_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmqh_mode)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- oappend ("{1to4}");
|
||
|
|
+ oappend (ins, "{1to4}");
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- oappend ("{1to8}");
|
||
|
|
+ oappend (ins, "{1to8}");
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- oappend ("{1to16}");
|
||
|
|
+ oappend (ins, "{1to16}");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- vex.no_broadcast = 1;
|
||
|
|
+ ins->vex.no_broadcast = 1;
|
||
|
|
}
|
||
|
|
- if (vex.no_broadcast)
|
||
|
|
- oappend ("{bad}");
|
||
|
|
+ if (ins->vex.no_broadcast)
|
||
|
|
+ oappend (ins, "{bad}");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_E (int bytemode, int sizeflag)
|
||
|
|
+OP_E (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
{
|
||
|
|
if ((sizeflag & SUFFIX_ALWAYS)
|
||
|
|
&& (bytemode == b_swap_mode
|
||
|
|
|| bytemode == bnd_swap_mode
|
||
|
|
|| bytemode == v_swap_mode))
|
||
|
|
- swap_operand ();
|
||
|
|
+ swap_operand (ins);
|
||
|
|
|
||
|
|
- print_register (modrm.rm, REX_B, bytemode, sizeflag);
|
||
|
|
+ print_register (ins, ins->modrm.rm, REX_B, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- OP_E_memory (bytemode, sizeflag);
|
||
|
|
+ OP_E_memory (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_G (int bytemode, int sizeflag)
|
||
|
|
+OP_G (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (vex.evex && !vex.r && address_mode == mode_64bit)
|
||
|
|
+ if (ins->vex.evex && !ins->vex.r && ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- print_register (modrm.reg, REX_R, bytemode, sizeflag);
|
||
|
|
+ print_register (ins, ins->modrm.reg, REX_R, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
+#ifdef BFD64
|
||
|
|
static bfd_vma
|
||
|
|
-get64 (void)
|
||
|
|
+get64 (instr_info *ins)
|
||
|
|
{
|
||
|
|
bfd_vma x;
|
||
|
|
-#ifdef BFD64
|
||
|
|
unsigned int a;
|
||
|
|
unsigned int b;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 8);
|
||
|
|
- a = *codep++ & 0xff;
|
||
|
|
- a |= (*codep++ & 0xff) << 8;
|
||
|
|
- a |= (*codep++ & 0xff) << 16;
|
||
|
|
- a |= (*codep++ & 0xffu) << 24;
|
||
|
|
- b = *codep++ & 0xff;
|
||
|
|
- b |= (*codep++ & 0xff) << 8;
|
||
|
|
- b |= (*codep++ & 0xff) << 16;
|
||
|
|
- b |= (*codep++ & 0xffu) << 24;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 8);
|
||
|
|
+ a = *ins->codep++ & 0xff;
|
||
|
|
+ a |= (*ins->codep++ & 0xff) << 8;
|
||
|
|
+ a |= (*ins->codep++ & 0xff) << 16;
|
||
|
|
+ a |= (*ins->codep++ & 0xffu) << 24;
|
||
|
|
+ b = *ins->codep++ & 0xff;
|
||
|
|
+ b |= (*ins->codep++ & 0xff) << 8;
|
||
|
|
+ b |= (*ins->codep++ & 0xff) << 16;
|
||
|
|
+ b |= (*ins->codep++ & 0xffu) << 24;
|
||
|
|
x = a + ((bfd_vma) b << 32);
|
||
|
|
+ return x;
|
||
|
|
+}
|
||
|
|
#else
|
||
|
|
+static bfd_vma
|
||
|
|
+get64 (instr_info *ins ATTRIBUTE_UNUSED)
|
||
|
|
+{
|
||
|
|
abort ();
|
||
|
|
- x = 0;
|
||
|
|
-#endif
|
||
|
|
- return x;
|
||
|
|
+ return 0;
|
||
|
|
}
|
||
|
|
+#endif
|
||
|
|
|
||
|
|
static bfd_signed_vma
|
||
|
|
-get32 (void)
|
||
|
|
+get32 (instr_info *ins)
|
||
|
|
{
|
||
|
|
- bfd_vma x = 0;
|
||
|
|
+ bfd_signed_vma x = 0;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 4);
|
||
|
|
- x = *codep++ & (bfd_vma) 0xff;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 8;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 16;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 24;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 4);
|
||
|
|
+ x = *ins->codep++ & (bfd_signed_vma) 0xff;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 8;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 16;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 24;
|
||
|
|
return x;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bfd_signed_vma
|
||
|
|
-get32s (void)
|
||
|
|
+get32s (instr_info *ins)
|
||
|
|
{
|
||
|
|
- bfd_vma x = 0;
|
||
|
|
+ bfd_signed_vma x = 0;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 4);
|
||
|
|
- x = *codep++ & (bfd_vma) 0xff;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 8;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 16;
|
||
|
|
- x |= (*codep++ & (bfd_vma) 0xff) << 24;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 4);
|
||
|
|
+ x = *ins->codep++ & (bfd_signed_vma) 0xff;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 8;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 16;
|
||
|
|
+ x |= (*ins->codep++ & (bfd_signed_vma) 0xff) << 24;
|
||
|
|
|
||
|
|
- x = (x ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
|
||
|
|
+ x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
|
||
|
|
|
||
|
|
return x;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int
|
||
|
|
-get16 (void)
|
||
|
|
+get16 (instr_info *ins)
|
||
|
|
{
|
||
|
|
int x = 0;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 2);
|
||
|
|
- x = *codep++ & 0xff;
|
||
|
|
- x |= (*codep++ & 0xff) << 8;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 2);
|
||
|
|
+ x = *ins->codep++ & 0xff;
|
||
|
|
+ x |= (*ins->codep++ & 0xff) << 8;
|
||
|
|
return x;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-set_op (bfd_vma op, int riprel)
|
||
|
|
+set_op (instr_info *ins, bfd_vma op, int riprel)
|
||
|
|
{
|
||
|
|
- op_index[op_ad] = op_ad;
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ ins->op_index[ins->op_ad] = ins->op_ad;
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
- op_address[op_ad] = op;
|
||
|
|
- op_riprel[op_ad] = riprel;
|
||
|
|
+ ins->op_address[ins->op_ad] = op;
|
||
|
|
+ ins->op_riprel[ins->op_ad] = riprel;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Mask to get a 32-bit address. */
|
||
|
|
- op_address[op_ad] = op & 0xffffffff;
|
||
|
|
- op_riprel[op_ad] = riprel & 0xffffffff;
|
||
|
|
+ ins->op_address[ins->op_ad] = op & 0xffffffff;
|
||
|
|
+ ins->op_riprel[ins->op_ad] = riprel & 0xffffffff;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_REG (int code, int sizeflag)
|
||
|
|
+OP_REG (instr_info *ins, int code, int sizeflag)
|
||
|
|
{
|
||
|
|
const char *s;
|
||
|
|
int add;
|
||
|
|
@@ -12106,12 +12131,12 @@ OP_REG (int code, int sizeflag)
|
||
|
|
{
|
||
|
|
case es_reg: case ss_reg: case cs_reg:
|
||
|
|
case ds_reg: case fs_reg: case gs_reg:
|
||
|
|
- oappend (names_seg[code - es_reg]);
|
||
|
|
+ oappend (ins, ins->names_seg[code - es_reg]);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
USED_REX (REX_B);
|
||
|
|
- if (rex & REX_B)
|
||
|
|
+ if (ins->rex & REX_B)
|
||
|
|
add = 8;
|
||
|
|
else
|
||
|
|
add = 0;
|
||
|
|
@@ -12120,23 +12145,23 @@ OP_REG (int code, int sizeflag)
|
||
|
|
{
|
||
|
|
case ax_reg: case cx_reg: case dx_reg: case bx_reg:
|
||
|
|
case sp_reg: case bp_reg: case si_reg: case di_reg:
|
||
|
|
- s = names16[code - ax_reg + add];
|
||
|
|
+ s = ins->names16[code - ax_reg + add];
|
||
|
|
break;
|
||
|
|
case ah_reg: case ch_reg: case dh_reg: case bh_reg:
|
||
|
|
USED_REX (0);
|
||
|
|
/* Fall through. */
|
||
|
|
case al_reg: case cl_reg: case dl_reg: case bl_reg:
|
||
|
|
- if (rex)
|
||
|
|
- s = names8rex[code - al_reg + add];
|
||
|
|
+ if (ins->rex)
|
||
|
|
+ s = ins->names8rex[code - al_reg + add];
|
||
|
|
else
|
||
|
|
- s = names8[code - al_reg];
|
||
|
|
+ s = ins->names8[code - al_reg];
|
||
|
|
break;
|
||
|
|
case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
|
||
|
|
case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
|
||
|
|
- if (address_mode == mode_64bit
|
||
|
|
- && ((sizeflag & DFLAG) || (rex & REX_W)))
|
||
|
|
+ if (ins->address_mode == mode_64bit
|
||
|
|
+ && ((sizeflag & DFLAG) || (ins->rex & REX_W)))
|
||
|
|
{
|
||
|
|
- s = names64[code - rAX_reg + add];
|
||
|
|
+ s = ins->names64[code - rAX_reg + add];
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
code += eAX_reg - rAX_reg;
|
||
|
|
@@ -12144,65 +12169,65 @@ OP_REG (int code, int sizeflag)
|
||
|
|
case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
|
||
|
|
case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- s = names64[code - eAX_reg + add];
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ s = ins->names64[code - eAX_reg + add];
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
- s = names32[code - eAX_reg + add];
|
||
|
|
+ s = ins->names32[code - eAX_reg + add];
|
||
|
|
else
|
||
|
|
- s = names16[code - eAX_reg + add];
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ s = ins->names16[code - eAX_reg + add];
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
s = INTERNAL_DISASSEMBLER_ERROR;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- oappend (s);
|
||
|
|
+ oappend (ins, s);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_IMREG (int code, int sizeflag)
|
||
|
|
+OP_IMREG (instr_info *ins, int code, int sizeflag)
|
||
|
|
{
|
||
|
|
const char *s;
|
||
|
|
|
||
|
|
switch (code)
|
||
|
|
{
|
||
|
|
case indir_dx_reg:
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
s = "dx";
|
||
|
|
else
|
||
|
|
s = "(%dx)";
|
||
|
|
break;
|
||
|
|
case al_reg: case cl_reg:
|
||
|
|
- s = names8[code - al_reg];
|
||
|
|
+ s = ins->names8[code - al_reg];
|
||
|
|
break;
|
||
|
|
case eAX_reg:
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
- s = *names64;
|
||
|
|
+ s = *ins->names64;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
/* Fall through. */
|
||
|
|
case z_mode_ax_reg:
|
||
|
|
- if ((rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
- s = *names32;
|
||
|
|
+ if ((ins->rex & REX_W) || (sizeflag & DFLAG))
|
||
|
|
+ s = *ins->names32;
|
||
|
|
else
|
||
|
|
- s = *names16;
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ s = *ins->names16;
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
s = INTERNAL_DISASSEMBLER_ERROR;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- oappend (s);
|
||
|
|
+ oappend (ins, s);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_I (int bytemode, int sizeflag)
|
||
|
|
+OP_I (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_signed_vma op;
|
||
|
|
bfd_signed_vma mask = -1;
|
||
|
|
@@ -12210,72 +12235,73 @@ OP_I (int bytemode, int sizeflag)
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case b_mode:
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- op = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ op = *ins->codep++;
|
||
|
|
mask = 0xff;
|
||
|
|
break;
|
||
|
|
case v_mode:
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- op = get32s ();
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ op = get32s (ins);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
{
|
||
|
|
- op = get32 ();
|
||
|
|
+ op = get32 (ins);
|
||
|
|
mask = 0xffffffff;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- op = get16 ();
|
||
|
|
+ op = get16 (ins);
|
||
|
|
mask = 0xfffff;
|
||
|
|
}
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case d_mode:
|
||
|
|
mask = 0xffffffff;
|
||
|
|
- op = get32 ();
|
||
|
|
+ op = get32 (ins);
|
||
|
|
break;
|
||
|
|
case w_mode:
|
||
|
|
mask = 0xfffff;
|
||
|
|
- op = get16 ();
|
||
|
|
+ op = get16 (ins);
|
||
|
|
break;
|
||
|
|
case const_1_mode:
|
||
|
|
- if (intel_syntax)
|
||
|
|
- oappend ("1");
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ oappend (ins, "1");
|
||
|
|
return;
|
||
|
|
default:
|
||
|
|
- oappend (INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
+ oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
op &= mask;
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, op);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, op);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_I64 (int bytemode, int sizeflag)
|
||
|
|
+OP_I64 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (bytemode != v_mode || address_mode != mode_64bit || !(rex & REX_W))
|
||
|
|
+ if (bytemode != v_mode || ins->address_mode != mode_64bit
|
||
|
|
+ || !(ins->rex & REX_W))
|
||
|
|
{
|
||
|
|
- OP_I (bytemode, sizeflag);
|
||
|
|
+ OP_I (ins, bytemode, sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
USED_REX (REX_W);
|
||
|
|
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, get64 ());
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, get64 (ins));
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_sI (int bytemode, int sizeflag)
|
||
|
|
+OP_sI (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_signed_vma op;
|
||
|
|
|
||
|
|
@@ -12283,17 +12309,17 @@ OP_sI (int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
case b_mode:
|
||
|
|
case b_T_mode:
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- op = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ op = *ins->codep++;
|
||
|
|
if ((op & 0x80) != 0)
|
||
|
|
op -= 0x100;
|
||
|
|
if (bytemode == b_T_mode)
|
||
|
|
{
|
||
|
|
- if (address_mode != mode_64bit
|
||
|
|
- || !((sizeflag & DFLAG) || (rex & REX_W)))
|
||
|
|
+ if (ins->address_mode != mode_64bit
|
||
|
|
+ || !((sizeflag & DFLAG) || (ins->rex & REX_W)))
|
||
|
|
{
|
||
|
|
/* The operand-size prefix is overridden by a REX prefix. */
|
||
|
|
- if ((sizeflag & DFLAG) || (rex & REX_W))
|
||
|
|
+ if ((sizeflag & DFLAG) || (ins->rex & REX_W))
|
||
|
|
op &= 0xffffffff;
|
||
|
|
else
|
||
|
|
op &= 0xffff;
|
||
|
|
@@ -12301,7 +12327,7 @@ OP_sI (int bytemode, int sizeflag)
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- if (!(rex & REX_W))
|
||
|
|
+ if (!(ins->rex & REX_W))
|
||
|
|
{
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
op &= 0xffffffff;
|
||
|
|
@@ -12312,23 +12338,23 @@ OP_sI (int bytemode, int sizeflag)
|
||
|
|
break;
|
||
|
|
case v_mode:
|
||
|
|
/* The operand-size prefix is overridden by a REX prefix. */
|
||
|
|
- if ((sizeflag & DFLAG) || (rex & REX_W))
|
||
|
|
- op = get32s ();
|
||
|
|
+ if ((sizeflag & DFLAG) || (ins->rex & REX_W))
|
||
|
|
+ op = get32s (ins);
|
||
|
|
else
|
||
|
|
- op = get16 ();
|
||
|
|
+ op = get16 (ins);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- oappend (INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
+ oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, op);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, op);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_J (int bytemode, int sizeflag)
|
||
|
|
+OP_J (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_vma disp;
|
||
|
|
bfd_vma mask = -1;
|
||
|
|
@@ -12337,21 +12363,21 @@ OP_J (int bytemode, int sizeflag)
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case b_mode:
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- disp = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ disp = *ins->codep++;
|
||
|
|
if ((disp & 0x80) != 0)
|
||
|
|
disp -= 0x100;
|
||
|
|
break;
|
||
|
|
case v_mode:
|
||
|
|
case dqw_mode:
|
||
|
|
if ((sizeflag & DFLAG)
|
||
|
|
- || (address_mode == mode_64bit
|
||
|
|
- && ((isa64 == intel64 && bytemode != dqw_mode)
|
||
|
|
- || (rex & REX_W))))
|
||
|
|
- disp = get32s ();
|
||
|
|
+ || (ins->address_mode == mode_64bit
|
||
|
|
+ && ((ins->isa64 == intel64 && bytemode != dqw_mode)
|
||
|
|
+ || (ins->rex & REX_W))))
|
||
|
|
+ disp = get32s (ins);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- disp = get16 ();
|
||
|
|
+ disp = get16 (ins);
|
||
|
|
if ((disp & 0x8000) != 0)
|
||
|
|
disp -= 0x10000;
|
||
|
|
/* In 16bit mode, address is wrapped around at 64k within
|
||
|
|
@@ -12359,251 +12385,256 @@ OP_J (int bytemode, int sizeflag)
|
||
|
|
instruction means that the pc is masked to 16 bits after
|
||
|
|
the displacement is added! */
|
||
|
|
mask = 0xffff;
|
||
|
|
- if ((prefixes & PREFIX_DATA) == 0)
|
||
|
|
- segment = ((start_pc + (codep - start_codep))
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) == 0)
|
||
|
|
+ segment = ((ins->start_pc + (ins->codep - ins->start_codep))
|
||
|
|
& ~((bfd_vma) 0xffff));
|
||
|
|
}
|
||
|
|
- if (address_mode != mode_64bit
|
||
|
|
- || (isa64 != intel64 && !(rex & REX_W)))
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ if (ins->address_mode != mode_64bit
|
||
|
|
+ || (ins->isa64 != intel64 && !(ins->rex & REX_W)))
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- oappend (INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
+ oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- disp = ((start_pc + (codep - start_codep) + disp) & mask) | segment;
|
||
|
|
- set_op (disp, 0);
|
||
|
|
- print_operand_value (scratchbuf, 1, disp);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ disp = ((ins->start_pc + (ins->codep - ins->start_codep) + disp) & mask)
|
||
|
|
+ | segment;
|
||
|
|
+ set_op (ins, disp, 0);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, disp);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_SEG (int bytemode, int sizeflag)
|
||
|
|
+OP_SEG (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
if (bytemode == w_mode)
|
||
|
|
- oappend (names_seg[modrm.reg]);
|
||
|
|
+ oappend (ins, ins->names_seg[ins->modrm.reg]);
|
||
|
|
else
|
||
|
|
- OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
|
||
|
|
+ OP_E (ins, ins->modrm.mod == 3 ? bytemode : w_mode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
|
||
|
|
+OP_DIR (instr_info *ins, int dummy ATTRIBUTE_UNUSED, int sizeflag)
|
||
|
|
{
|
||
|
|
int seg, offset;
|
||
|
|
|
||
|
|
if (sizeflag & DFLAG)
|
||
|
|
{
|
||
|
|
- offset = get32 ();
|
||
|
|
- seg = get16 ();
|
||
|
|
+ offset = get32 (ins);
|
||
|
|
+ seg = get16 (ins);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- offset = get16 ();
|
||
|
|
- seg = get16 ();
|
||
|
|
+ offset = get16 (ins);
|
||
|
|
+ seg = get16 (ins);
|
||
|
|
}
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
- if (intel_syntax)
|
||
|
|
- sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ sprintf (ins->scratchbuf, "0x%x:0x%x", seg, offset);
|
||
|
|
else
|
||
|
|
- sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ sprintf (ins->scratchbuf, "$0x%x,$0x%x", seg, offset);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_OFF (int bytemode, int sizeflag)
|
||
|
|
+OP_OFF (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_vma off;
|
||
|
|
|
||
|
|
- if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
- intel_operand_size (bytemode, sizeflag);
|
||
|
|
- append_seg ();
|
||
|
|
+ if (ins->intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ intel_operand_size (ins, bytemode, sizeflag);
|
||
|
|
+ append_seg (ins);
|
||
|
|
|
||
|
|
- if ((sizeflag & AFLAG) || address_mode == mode_64bit)
|
||
|
|
- off = get32 ();
|
||
|
|
+ if ((sizeflag & AFLAG) || ins->address_mode == mode_64bit)
|
||
|
|
+ off = get32 (ins);
|
||
|
|
else
|
||
|
|
- off = get16 ();
|
||
|
|
+ off = get16 (ins);
|
||
|
|
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
{
|
||
|
|
- oappend (names_seg[ds_reg - es_reg]);
|
||
|
|
- oappend (":");
|
||
|
|
+ oappend (ins, ins->names_seg[ds_reg - es_reg]);
|
||
|
|
+ oappend (ins, ":");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- print_operand_value (scratchbuf, 1, off);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, off);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_OFF64 (int bytemode, int sizeflag)
|
||
|
|
+OP_OFF64 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
bfd_vma off;
|
||
|
|
|
||
|
|
- if (address_mode != mode_64bit
|
||
|
|
- || (prefixes & PREFIX_ADDR))
|
||
|
|
+ if (ins->address_mode != mode_64bit
|
||
|
|
+ || (ins->prefixes & PREFIX_ADDR))
|
||
|
|
{
|
||
|
|
- OP_OFF (bytemode, sizeflag);
|
||
|
|
+ OP_OFF (ins, bytemode, sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
- intel_operand_size (bytemode, sizeflag);
|
||
|
|
- append_seg ();
|
||
|
|
+ if (ins->intel_syntax && (sizeflag & SUFFIX_ALWAYS))
|
||
|
|
+ intel_operand_size (ins, bytemode, sizeflag);
|
||
|
|
+ append_seg (ins);
|
||
|
|
|
||
|
|
- off = get64 ();
|
||
|
|
+ off = get64 (ins);
|
||
|
|
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
{
|
||
|
|
- oappend (names_seg[ds_reg - es_reg]);
|
||
|
|
- oappend (":");
|
||
|
|
+ oappend (ins, ins->names_seg[ds_reg - es_reg]);
|
||
|
|
+ oappend (ins, ":");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- print_operand_value (scratchbuf, 1, off);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf, 1, off);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-ptr_reg (int code, int sizeflag)
|
||
|
|
+ptr_reg (instr_info *ins, int code, int sizeflag)
|
||
|
|
{
|
||
|
|
const char *s;
|
||
|
|
|
||
|
|
- *obufp++ = open_char;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_ADDR);
|
||
|
|
- if (address_mode == mode_64bit)
|
||
|
|
+ *ins->obufp++ = ins->open_char;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_ADDR);
|
||
|
|
+ if (ins->address_mode == mode_64bit)
|
||
|
|
{
|
||
|
|
if (!(sizeflag & AFLAG))
|
||
|
|
- s = names32[code - eAX_reg];
|
||
|
|
+ s = ins->names32[code - eAX_reg];
|
||
|
|
else
|
||
|
|
- s = names64[code - eAX_reg];
|
||
|
|
+ s = ins->names64[code - eAX_reg];
|
||
|
|
}
|
||
|
|
else if (sizeflag & AFLAG)
|
||
|
|
- s = names32[code - eAX_reg];
|
||
|
|
+ s = ins->names32[code - eAX_reg];
|
||
|
|
else
|
||
|
|
- s = names16[code - eAX_reg];
|
||
|
|
- oappend (s);
|
||
|
|
- *obufp++ = close_char;
|
||
|
|
- *obufp = 0;
|
||
|
|
+ s = ins->names16[code - eAX_reg];
|
||
|
|
+ oappend (ins, s);
|
||
|
|
+ *ins->obufp++ = ins->close_char;
|
||
|
|
+ *ins->obufp = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_ESreg (int code, int sizeflag)
|
||
|
|
+OP_ESreg (instr_info *ins, int code, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- switch (codep[-1])
|
||
|
|
+ switch (ins->codep[-1])
|
||
|
|
{
|
||
|
|
case 0x6d: /* insw/insl */
|
||
|
|
- intel_operand_size (z_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, z_mode, sizeflag);
|
||
|
|
break;
|
||
|
|
case 0xa5: /* movsw/movsl/movsq */
|
||
|
|
case 0xa7: /* cmpsw/cmpsl/cmpsq */
|
||
|
|
case 0xab: /* stosw/stosl */
|
||
|
|
case 0xaf: /* scasw/scasl */
|
||
|
|
- intel_operand_size (v_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, v_mode, sizeflag);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- intel_operand_size (b_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, b_mode, sizeflag);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- oappend_maybe_intel ("%es:");
|
||
|
|
- ptr_reg (code, sizeflag);
|
||
|
|
+ oappend_maybe_intel (ins, "%es:");
|
||
|
|
+ ptr_reg (ins, code, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_DSreg (int code, int sizeflag)
|
||
|
|
+OP_DSreg (instr_info *ins, int code, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (intel_syntax)
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- switch (codep[-1])
|
||
|
|
+ switch (ins->codep[-1])
|
||
|
|
{
|
||
|
|
case 0x6f: /* outsw/outsl */
|
||
|
|
- intel_operand_size (z_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, z_mode, sizeflag);
|
||
|
|
break;
|
||
|
|
case 0xa5: /* movsw/movsl/movsq */
|
||
|
|
case 0xa7: /* cmpsw/cmpsl/cmpsq */
|
||
|
|
case 0xad: /* lodsw/lodsl/lodsq */
|
||
|
|
- intel_operand_size (v_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, v_mode, sizeflag);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- intel_operand_size (b_mode, sizeflag);
|
||
|
|
+ intel_operand_size (ins, b_mode, sizeflag);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- /* Set active_seg_prefix to PREFIX_DS if it is unset so that the
|
||
|
|
+ /* Set ins->active_seg_prefix to PREFIX_DS if it is unset so that the
|
||
|
|
default segment register DS is printed. */
|
||
|
|
- if (!active_seg_prefix)
|
||
|
|
- active_seg_prefix = PREFIX_DS;
|
||
|
|
- append_seg ();
|
||
|
|
- ptr_reg (code, sizeflag);
|
||
|
|
+ if (!ins->active_seg_prefix)
|
||
|
|
+ ins->active_seg_prefix = PREFIX_DS;
|
||
|
|
+ append_seg (ins);
|
||
|
|
+ ptr_reg (ins, code, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_C (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
int add;
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
{
|
||
|
|
USED_REX (REX_R);
|
||
|
|
add = 8;
|
||
|
|
}
|
||
|
|
- else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
|
||
|
|
+ else if (ins->address_mode != mode_64bit && (ins->prefixes & PREFIX_LOCK))
|
||
|
|
{
|
||
|
|
- all_prefixes[last_lock_prefix] = 0;
|
||
|
|
- used_prefixes |= PREFIX_LOCK;
|
||
|
|
+ ins->all_prefixes[ins->last_lock_prefix] = 0;
|
||
|
|
+ ins->used_prefixes |= PREFIX_LOCK;
|
||
|
|
add = 8;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
add = 0;
|
||
|
|
- sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
+ sprintf (ins->scratchbuf, "%%cr%d", ins->modrm.reg + add);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_D (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
int add;
|
||
|
|
USED_REX (REX_R);
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
add = 8;
|
||
|
|
else
|
||
|
|
add = 0;
|
||
|
|
- if (intel_syntax)
|
||
|
|
- sprintf (scratchbuf, "dr%d", modrm.reg + add);
|
||
|
|
+ if (ins->intel_syntax)
|
||
|
|
+ sprintf (ins->scratchbuf, "dr%d", ins->modrm.reg + add);
|
||
|
|
else
|
||
|
|
- sprintf (scratchbuf, "%%db%d", modrm.reg + add);
|
||
|
|
- oappend (scratchbuf);
|
||
|
|
+ sprintf (ins->scratchbuf, "%%db%d", ins->modrm.reg + add);
|
||
|
|
+ oappend (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_T (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- sprintf (scratchbuf, "%%tr%d", modrm.reg);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
+ sprintf (ins->scratchbuf, "%%tr%d", ins->modrm.reg);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_MMX (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- int reg = modrm.reg;
|
||
|
|
+ int reg = ins->modrm.reg;
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
- if (prefixes & PREFIX_DATA)
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
+ if (ins->prefixes & PREFIX_DATA)
|
||
|
|
{
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
USED_REX (REX_R);
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
reg += 8;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- names = names_mm;
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ names = ins->names_mm;
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-print_vector_reg (unsigned int reg, int bytemode)
|
||
|
|
+print_vector_reg (instr_info *ins, unsigned int reg, int bytemode)
|
||
|
|
{
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
@@ -12611,31 +12642,31 @@ print_vector_reg (unsigned int reg, int bytemode)
|
||
|
|
|| bytemode == evex_half_bcst_xmmqh_mode
|
||
|
|
|| bytemode == evex_half_bcst_xmmq_mode)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
case 256:
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (bytemode == ymm_mode)
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
else if (bytemode == tmm_mode)
|
||
|
|
{
|
||
|
|
if (reg >= 8)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- names = names_tmm;
|
||
|
|
+ names = ins->names_tmm;
|
||
|
|
}
|
||
|
|
- else if (need_vex
|
||
|
|
+ else if (ins->need_vex
|
||
|
|
&& bytemode != xmm_mode
|
||
|
|
&& bytemode != scalar_mode
|
||
|
|
&& bytemode != xmmdw_mode
|
||
|
|
@@ -12647,92 +12678,92 @@ print_vector_reg (unsigned int reg, int bytemode)
|
||
|
|
&& bytemode != d_mode
|
||
|
|
&& bytemode != q_mode)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- if (vex.w
|
||
|
|
+ if (ins->vex.w
|
||
|
|
|| bytemode != vex_vsib_q_w_dq_mode)
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
else
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- if (vex.w
|
||
|
|
+ if (ins->vex.w
|
||
|
|
|| bytemode != vex_vsib_q_w_dq_mode)
|
||
|
|
- names = names_zmm;
|
||
|
|
+ names = ins->names_zmm;
|
||
|
|
else
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- names = names_xmm;
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_XMM (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_XMM (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- unsigned int reg = modrm.reg;
|
||
|
|
+ unsigned int reg = ins->modrm.reg;
|
||
|
|
|
||
|
|
USED_REX (REX_R);
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
reg += 8;
|
||
|
|
- if (vex.evex)
|
||
|
|
+ if (ins->vex.evex)
|
||
|
|
{
|
||
|
|
- if (!vex.r)
|
||
|
|
+ if (!ins->vex.r)
|
||
|
|
reg += 16;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bytemode == tmm_mode)
|
||
|
|
- modrm.reg = reg;
|
||
|
|
+ ins->modrm.reg = reg;
|
||
|
|
else if (bytemode == scalar_mode)
|
||
|
|
- vex.no_broadcast = 1;
|
||
|
|
+ ins->vex.no_broadcast = 1;
|
||
|
|
|
||
|
|
- print_vector_reg (reg, bytemode);
|
||
|
|
+ print_vector_reg (ins, reg, bytemode);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_EM (int bytemode, int sizeflag)
|
||
|
|
+OP_EM (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
int reg;
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
- if (modrm.mod != 3)
|
||
|
|
+ if (ins->modrm.mod != 3)
|
||
|
|
{
|
||
|
|
- if (intel_syntax
|
||
|
|
+ if (ins->intel_syntax
|
||
|
|
&& (bytemode == v_mode || bytemode == v_swap_mode))
|
||
|
|
{
|
||
|
|
- bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ bytemode = (ins->prefixes & PREFIX_DATA) ? x_mode : q_mode;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((sizeflag & SUFFIX_ALWAYS) && bytemode == v_swap_mode)
|
||
|
|
- swap_operand ();
|
||
|
|
+ swap_operand (ins);
|
||
|
|
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
- reg = modrm.rm;
|
||
|
|
- if (prefixes & PREFIX_DATA)
|
||
|
|
+ ins->codep++;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
+ reg = ins->modrm.rm;
|
||
|
|
+ if (ins->prefixes & PREFIX_DATA)
|
||
|
|
{
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
USED_REX (REX_B);
|
||
|
|
- if (rex & REX_B)
|
||
|
|
+ if (ins->rex & REX_B)
|
||
|
|
reg += 8;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- names = names_mm;
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ names = ins->names_mm;
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* cvt* are the only instructions in sse2 which have
|
||
|
|
@@ -12741,59 +12772,60 @@ OP_EM (int bytemode, int sizeflag)
|
||
|
|
between SSE and MMX instruction(operands). So we have to handle the
|
||
|
|
cvt* separately using OP_EMC and OP_MXC */
|
||
|
|
static void
|
||
|
|
-OP_EMC (int bytemode, int sizeflag)
|
||
|
|
+OP_EMC (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3)
|
||
|
|
+ if (ins->modrm.mod != 3)
|
||
|
|
{
|
||
|
|
- if (intel_syntax && bytemode == v_mode)
|
||
|
|
+ if (ins->intel_syntax && bytemode == v_mode)
|
||
|
|
{
|
||
|
|
- bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
+ bytemode = (ins->prefixes & PREFIX_DATA) ? x_mode : q_mode;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
}
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
- oappend (names_mm[modrm.rm]);
|
||
|
|
+ ins->codep++;
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, ins->names_mm[ins->modrm.rm]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_MXC (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- used_prefixes |= (prefixes & PREFIX_DATA);
|
||
|
|
- oappend (names_mm[modrm.reg]);
|
||
|
|
+ ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
|
||
|
|
+ oappend (ins, ins->names_mm[ins->modrm.reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_EX (int bytemode, int sizeflag)
|
||
|
|
+OP_EX (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
int reg;
|
||
|
|
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
|
||
|
|
if (bytemode == dq_mode)
|
||
|
|
- bytemode = vex.w ? q_mode : d_mode;
|
||
|
|
+ bytemode = ins->vex.w ? q_mode : d_mode;
|
||
|
|
|
||
|
|
- if (modrm.mod != 3)
|
||
|
|
+ if (ins->modrm.mod != 3)
|
||
|
|
{
|
||
|
|
- OP_E_memory (bytemode, sizeflag);
|
||
|
|
+ OP_E_memory (ins, bytemode, sizeflag);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- reg = modrm.rm;
|
||
|
|
+ reg = ins->modrm.rm;
|
||
|
|
USED_REX (REX_B);
|
||
|
|
- if (rex & REX_B)
|
||
|
|
+ if (ins->rex & REX_B)
|
||
|
|
reg += 8;
|
||
|
|
- if (vex.evex)
|
||
|
|
+ if (ins->vex.evex)
|
||
|
|
{
|
||
|
|
USED_REX (REX_X);
|
||
|
|
- if ((rex & REX_X))
|
||
|
|
+ if ((ins->rex & REX_X))
|
||
|
|
reg += 16;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -12802,74 +12834,74 @@ OP_EX (int bytemode, int sizeflag)
|
||
|
|
|| bytemode == w_swap_mode
|
||
|
|
|| bytemode == d_swap_mode
|
||
|
|
|| bytemode == q_swap_mode))
|
||
|
|
- swap_operand ();
|
||
|
|
+ swap_operand (ins);
|
||
|
|
|
||
|
|
if (bytemode == tmm_mode)
|
||
|
|
- modrm.rm = reg;
|
||
|
|
+ ins->modrm.rm = reg;
|
||
|
|
|
||
|
|
- print_vector_reg (reg, bytemode);
|
||
|
|
+ print_vector_reg (ins, reg, bytemode);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_MS (int bytemode, int sizeflag)
|
||
|
|
+OP_MS (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
- OP_EM (bytemode, sizeflag);
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
+ OP_EM (ins, bytemode, sizeflag);
|
||
|
|
else
|
||
|
|
- BadOp ();
|
||
|
|
+ BadOp (ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_XS (int bytemode, int sizeflag)
|
||
|
|
+OP_XS (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
- OP_EX (bytemode, sizeflag);
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
+ OP_EX (ins, bytemode, sizeflag);
|
||
|
|
else
|
||
|
|
- BadOp ();
|
||
|
|
+ BadOp (ins);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_M (int bytemode, int sizeflag)
|
||
|
|
+OP_M (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
/* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
|
||
|
|
- BadOp ();
|
||
|
|
+ BadOp (ins);
|
||
|
|
else
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_0f07 (int bytemode, int sizeflag)
|
||
|
|
+OP_0f07 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3 || modrm.rm != 0)
|
||
|
|
- BadOp ();
|
||
|
|
+ if (ins->modrm.mod != 3 || ins->modrm.rm != 0)
|
||
|
|
+ BadOp (ins);
|
||
|
|
else
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, 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. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-NOP_Fixup1 (int bytemode, int sizeflag)
|
||
|
|
+NOP_Fixup1 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if ((prefixes & PREFIX_DATA) != 0
|
||
|
|
- || (rex != 0
|
||
|
|
- && rex != 0x48
|
||
|
|
- && address_mode == mode_64bit))
|
||
|
|
- OP_REG (bytemode, sizeflag);
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) != 0
|
||
|
|
+ || (ins->rex != 0
|
||
|
|
+ && ins->rex != 0x48
|
||
|
|
+ && ins->address_mode == mode_64bit))
|
||
|
|
+ OP_REG (ins, bytemode, sizeflag);
|
||
|
|
else
|
||
|
|
- strcpy (obuf, "nop");
|
||
|
|
+ strcpy (ins->obuf, "nop");
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-NOP_Fixup2 (int bytemode, int sizeflag)
|
||
|
|
+NOP_Fixup2 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if ((prefixes & PREFIX_DATA) != 0
|
||
|
|
- || (rex != 0
|
||
|
|
- && rex != 0x48
|
||
|
|
- && address_mode == mode_64bit))
|
||
|
|
- OP_IMREG (bytemode, sizeflag);
|
||
|
|
+ if ((ins->prefixes & PREFIX_DATA) != 0
|
||
|
|
+ || (ins->rex != 0
|
||
|
|
+ && ins->rex != 0x48
|
||
|
|
+ && ins->address_mode == mode_64bit))
|
||
|
|
+ OP_IMREG (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static const char *const Suffix3DNow[] = {
|
||
|
|
@@ -12940,29 +12972,30 @@ static const char *const Suffix3DNow[] = {
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_3DNowSuffix (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
const char *mnemonic;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
/* AMD 3DNow! instructions are specified by an opcode suffix in the
|
||
|
|
place where an 8-bit immediate would normally go. ie. the last
|
||
|
|
byte of the instruction. */
|
||
|
|
- obufp = mnemonicendp;
|
||
|
|
- mnemonic = Suffix3DNow[*codep++ & 0xff];
|
||
|
|
+ ins->obufp = ins->mnemonicendp;
|
||
|
|
+ mnemonic = Suffix3DNow[*ins->codep++ & 0xff];
|
||
|
|
if (mnemonic)
|
||
|
|
- oappend (mnemonic);
|
||
|
|
+ oappend (ins, mnemonic);
|
||
|
|
else
|
||
|
|
{
|
||
|
|
- /* Since a variable sized modrm/sib chunk is between the start
|
||
|
|
+ /* Since a variable sized ins->modrm/ins->sib chunk is between the start
|
||
|
|
of the opcode (0x0f0f) and the opcode suffix, we need to do
|
||
|
|
- all the modrm processing first, and don't know until now that
|
||
|
|
+ all the ins->modrm processing first, and don't know until now that
|
||
|
|
we have a bad opcode. This necessitates some cleaning up. */
|
||
|
|
- op_out[0][0] = '\0';
|
||
|
|
- op_out[1][0] = '\0';
|
||
|
|
- BadOp ();
|
||
|
|
+ ins->op_out[0][0] = '\0';
|
||
|
|
+ ins->op_out[1][0] = '\0';
|
||
|
|
+ BadOp (ins);
|
||
|
|
}
|
||
|
|
- mnemonicendp = obufp;
|
||
|
|
+ ins->mnemonicendp = ins->obufp;
|
||
|
|
}
|
||
|
|
|
||
|
|
static const struct op simd_cmp_op[] =
|
||
|
|
@@ -13006,119 +13039,120 @@ static const struct op vex_cmp_op[] =
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
-CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+CMP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
unsigned int cmp_type;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- cmp_type = *codep++ & 0xff;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ cmp_type = *ins->codep++ & 0xff;
|
||
|
|
if (cmp_type < ARRAY_SIZE (simd_cmp_op))
|
||
|
|
{
|
||
|
|
- char suffix [3];
|
||
|
|
- char *p = mnemonicendp - 2;
|
||
|
|
+ char suffix[3];
|
||
|
|
+ char *p = ins->mnemonicendp - 2;
|
||
|
|
suffix[0] = p[0];
|
||
|
|
suffix[1] = p[1];
|
||
|
|
suffix[2] = '\0';
|
||
|
|
sprintf (p, "%s%s", simd_cmp_op[cmp_type].name, suffix);
|
||
|
|
- mnemonicendp += simd_cmp_op[cmp_type].len;
|
||
|
|
+ ins->mnemonicendp += simd_cmp_op[cmp_type].len;
|
||
|
|
}
|
||
|
|
- else if (need_vex
|
||
|
|
+ else if (ins->need_vex
|
||
|
|
&& cmp_type < ARRAY_SIZE (simd_cmp_op) + ARRAY_SIZE (vex_cmp_op))
|
||
|
|
{
|
||
|
|
- char suffix [3];
|
||
|
|
- char *p = mnemonicendp - 2;
|
||
|
|
+ char suffix[3];
|
||
|
|
+ char *p = ins->mnemonicendp - 2;
|
||
|
|
suffix[0] = p[0];
|
||
|
|
suffix[1] = p[1];
|
||
|
|
suffix[2] = '\0';
|
||
|
|
cmp_type -= ARRAY_SIZE (simd_cmp_op);
|
||
|
|
sprintf (p, "%s%s", vex_cmp_op[cmp_type].name, suffix);
|
||
|
|
- mnemonicendp += vex_cmp_op[cmp_type].len;
|
||
|
|
+ ins->mnemonicendp += vex_cmp_op[cmp_type].len;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* We have a reserved extension byte. Output it directly. */
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, cmp_type);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, cmp_type);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_Mwait (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_Mwait (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
/* mwait %eax,%ecx / mwaitx %eax,%ecx,%ebx */
|
||
|
|
- if (!intel_syntax)
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- strcpy (op_out[0], names32[0]);
|
||
|
|
- strcpy (op_out[1], names32[1]);
|
||
|
|
+ strcpy (ins->op_out[0], ins->names32[0]);
|
||
|
|
+ strcpy (ins->op_out[1], ins->names32[1]);
|
||
|
|
if (bytemode == eBX_reg)
|
||
|
|
- strcpy (op_out[2], names32[3]);
|
||
|
|
- two_source_ops = 1;
|
||
|
|
+ strcpy (ins->op_out[2], ins->names32[3]);
|
||
|
|
+ ins->two_source_ops = 1;
|
||
|
|
}
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_Monitor (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+OP_Monitor (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
/* monitor %{e,r,}ax,%ecx,%edx" */
|
||
|
|
- if (!intel_syntax)
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
{
|
||
|
|
- const char **names = (address_mode == mode_64bit
|
||
|
|
- ? names64 : names32);
|
||
|
|
+ const char **names = (ins->address_mode == mode_64bit
|
||
|
|
+ ? ins->names64 : ins->names32);
|
||
|
|
|
||
|
|
- if (prefixes & PREFIX_ADDR)
|
||
|
|
+ if (ins->prefixes & PREFIX_ADDR)
|
||
|
|
{
|
||
|
|
/* Remove "addr16/addr32". */
|
||
|
|
- all_prefixes[last_addr_prefix] = 0;
|
||
|
|
- names = (address_mode != mode_32bit
|
||
|
|
- ? names32 : names16);
|
||
|
|
- used_prefixes |= PREFIX_ADDR;
|
||
|
|
+ ins->all_prefixes[ins->last_addr_prefix] = 0;
|
||
|
|
+ names = (ins->address_mode != mode_32bit
|
||
|
|
+ ? ins->names32 : ins->names16);
|
||
|
|
+ ins->used_prefixes |= PREFIX_ADDR;
|
||
|
|
}
|
||
|
|
- else if (address_mode == mode_16bit)
|
||
|
|
- names = names16;
|
||
|
|
- strcpy (op_out[0], names[0]);
|
||
|
|
- strcpy (op_out[1], names32[1]);
|
||
|
|
- strcpy (op_out[2], names32[2]);
|
||
|
|
- two_source_ops = 1;
|
||
|
|
+ else if (ins->address_mode == mode_16bit)
|
||
|
|
+ names = ins->names16;
|
||
|
|
+ strcpy (ins->op_out[0], names[0]);
|
||
|
|
+ strcpy (ins->op_out[1], ins->names32[1]);
|
||
|
|
+ strcpy (ins->op_out[2], ins->names32[2]);
|
||
|
|
+ ins->two_source_ops = 1;
|
||
|
|
}
|
||
|
|
/* Skip mod/rm byte. */
|
||
|
|
MODRM_CHECK;
|
||
|
|
- codep++;
|
||
|
|
+ ins->codep++;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-BadOp (void)
|
||
|
|
+BadOp (instr_info *ins)
|
||
|
|
{
|
||
|
|
/* Throw away prefixes and 1st. opcode byte. */
|
||
|
|
- codep = insn_codep + 1;
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ ins->codep = ins->insn_codep + 1;
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-REP_Fixup (int bytemode, int sizeflag)
|
||
|
|
+REP_Fixup (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
/* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
|
||
|
|
lods and stos. */
|
||
|
|
- if (prefixes & PREFIX_REPZ)
|
||
|
|
- all_prefixes[last_repz_prefix] = REP_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = REP_PREFIX;
|
||
|
|
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case al_reg:
|
||
|
|
case eAX_reg:
|
||
|
|
case indir_dx_reg:
|
||
|
|
- OP_IMREG (bytemode, sizeflag);
|
||
|
|
+ OP_IMREG (ins, bytemode, sizeflag);
|
||
|
|
break;
|
||
|
|
case eDI_reg:
|
||
|
|
- OP_ESreg (bytemode, sizeflag);
|
||
|
|
+ OP_ESreg (ins, bytemode, sizeflag);
|
||
|
|
break;
|
||
|
|
case eSI_reg:
|
||
|
|
- OP_DSreg (bytemode, sizeflag);
|
||
|
|
+ OP_DSreg (ins, bytemode, sizeflag);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -13127,275 +13161,277 @@ REP_Fixup (int bytemode, int sizeflag)
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-SEP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+SEP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- if ( isa64 != amd64 )
|
||
|
|
+ if (ins->isa64 != amd64)
|
||
|
|
return;
|
||
|
|
|
||
|
|
- obufp = obuf;
|
||
|
|
- BadOp ();
|
||
|
|
- mnemonicendp = obufp;
|
||
|
|
- ++codep;
|
||
|
|
+ ins->obufp = ins->obuf;
|
||
|
|
+ BadOp (ins);
|
||
|
|
+ ins->mnemonicendp = ins->obufp;
|
||
|
|
+ ++ins->codep;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* For BND-prefixed instructions 0xF2 prefix should be displayed as
|
||
|
|
"bnd". */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-BND_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+BND_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+ int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- if (prefixes & PREFIX_REPNZ)
|
||
|
|
- all_prefixes[last_repnz_prefix] = BND_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPNZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repnz_prefix] = BND_PREFIX;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
|
||
|
|
"notrack". */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-NOTRACK_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+NOTRACK_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
-
|
||
|
|
/* Since active_seg_prefix is not set in 64-bit mode, check whether
|
||
|
|
we've seen a PREFIX_DS. */
|
||
|
|
- if ((prefixes & PREFIX_DS) != 0
|
||
|
|
- && (address_mode != mode_64bit || last_data_prefix < 0))
|
||
|
|
+ if ((ins->prefixes & PREFIX_DS) != 0
|
||
|
|
+ && (ins->address_mode != mode_64bit || ins->last_data_prefix < 0))
|
||
|
|
{
|
||
|
|
/* NOTRACK prefix is only valid on indirect branch instructions.
|
||
|
|
NB: DATA prefix is unsupported for Intel64. */
|
||
|
|
- active_seg_prefix = 0;
|
||
|
|
- all_prefixes[last_seg_prefix] = NOTRACK_PREFIX;
|
||
|
|
+ ins->active_seg_prefix = 0;
|
||
|
|
+ ins->all_prefixes[ins->last_seg_prefix] = NOTRACK_PREFIX;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-/* Similar to OP_E. But the 0xf2/0xf3 prefixes should be displayed as
|
||
|
|
+/* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
|
||
|
|
"xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static void
|
||
|
|
-HLE_Fixup1 (int bytemode, int sizeflag)
|
||
|
|
+HLE_Fixup1 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3
|
||
|
|
- && (prefixes & PREFIX_LOCK) != 0)
|
||
|
|
+ if (ins->modrm.mod != 3
|
||
|
|
+ && (ins->prefixes & PREFIX_LOCK) != 0)
|
||
|
|
{
|
||
|
|
- if (prefixes & PREFIX_REPZ)
|
||
|
|
- all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
- if (prefixes & PREFIX_REPNZ)
|
||
|
|
- all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPNZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
}
|
||
|
|
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
-/* Similar to OP_E. But the 0xf2/0xf3 prefixes should be displayed as
|
||
|
|
+/* Similar to OP_E. But the 0xf2/0xf3 ins->prefixes should be displayed as
|
||
|
|
"xacquire"/"xrelease" for memory operand. No check for LOCK prefix.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static void
|
||
|
|
-HLE_Fixup2 (int bytemode, int sizeflag)
|
||
|
|
+HLE_Fixup2 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3)
|
||
|
|
+ if (ins->modrm.mod != 3)
|
||
|
|
{
|
||
|
|
- if (prefixes & PREFIX_REPZ)
|
||
|
|
- all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
- if (prefixes & PREFIX_REPNZ)
|
||
|
|
- all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPNZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
}
|
||
|
|
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Similar to OP_E. But the 0xf3 prefixes should be displayed as
|
||
|
|
"xrelease" for memory operand. No check for LOCK prefix. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-HLE_Fixup3 (int bytemode, int sizeflag)
|
||
|
|
+HLE_Fixup3 (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3
|
||
|
|
- && last_repz_prefix > last_repnz_prefix
|
||
|
|
- && (prefixes & PREFIX_REPZ) != 0)
|
||
|
|
- all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
+ if (ins->modrm.mod != 3
|
||
|
|
+ && ins->last_repz_prefix > ins->last_repnz_prefix
|
||
|
|
+ && (ins->prefixes & PREFIX_REPZ) != 0)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-CMPXCHG8B_Fixup (int bytemode, int sizeflag)
|
||
|
|
+CMPXCHG8B_Fixup (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
/* Change cmpxchg8b to cmpxchg16b. */
|
||
|
|
- char *p = mnemonicendp - 2;
|
||
|
|
- mnemonicendp = stpcpy (p, "16b");
|
||
|
|
+ char *p = ins->mnemonicendp - 2;
|
||
|
|
+ ins->mnemonicendp = stpcpy (p, "16b");
|
||
|
|
bytemode = o_mode;
|
||
|
|
}
|
||
|
|
- else if ((prefixes & PREFIX_LOCK) != 0)
|
||
|
|
+ else if ((ins->prefixes & PREFIX_LOCK) != 0)
|
||
|
|
{
|
||
|
|
- if (prefixes & PREFIX_REPZ)
|
||
|
|
- all_prefixes[last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
- if (prefixes & PREFIX_REPNZ)
|
||
|
|
- all_prefixes[last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repz_prefix] = XRELEASE_PREFIX;
|
||
|
|
+ if (ins->prefixes & PREFIX_REPNZ)
|
||
|
|
+ ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
|
||
|
|
}
|
||
|
|
|
||
|
|
- OP_M (bytemode, sizeflag);
|
||
|
|
+ OP_M (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+XMM_Fixup (instr_info *ins, int reg, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
- if (need_vex)
|
||
|
|
+ if (ins->need_vex)
|
||
|
|
{
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case 256:
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- names = names_xmm;
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-FXSAVE_Fixup (int bytemode, int sizeflag)
|
||
|
|
+FXSAVE_Fixup (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
/* Add proper suffix to "fxsave" and "fxrstor". */
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
- char *p = mnemonicendp;
|
||
|
|
+ char *p = ins->mnemonicendp;
|
||
|
|
*p++ = '6';
|
||
|
|
*p++ = '4';
|
||
|
|
*p = '\0';
|
||
|
|
- mnemonicendp = p;
|
||
|
|
+ ins->mnemonicendp = p;
|
||
|
|
}
|
||
|
|
- OP_M (bytemode, sizeflag);
|
||
|
|
+ OP_M (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Display the destination register operand for instructions with
|
||
|
|
VEX. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_VEX (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
int reg, modrm_reg, sib_index = -1;
|
||
|
|
const char **names;
|
||
|
|
|
||
|
|
- if (!need_vex)
|
||
|
|
+ if (!ins->need_vex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- reg = vex.register_specifier;
|
||
|
|
- vex.register_specifier = 0;
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ reg = ins->vex.register_specifier;
|
||
|
|
+ ins->vex.register_specifier = 0;
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
{
|
||
|
|
- if (vex.evex && !vex.v)
|
||
|
|
+ if (ins->vex.evex && !ins->vex.v)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
reg &= 7;
|
||
|
|
}
|
||
|
|
- else if (vex.evex && !vex.v)
|
||
|
|
+ else if (ins->vex.evex && !ins->vex.v)
|
||
|
|
reg += 16;
|
||
|
|
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case scalar_mode:
|
||
|
|
- oappend (names_xmm[reg]);
|
||
|
|
+ oappend (ins, ins->names_xmm[reg]);
|
||
|
|
return;
|
||
|
|
|
||
|
|
case vex_vsib_d_w_dq_mode:
|
||
|
|
case vex_vsib_q_w_dq_mode:
|
||
|
|
/* This must be the 3rd operand. */
|
||
|
|
- if (obufp != op_out[2])
|
||
|
|
+ if (ins->obufp != ins->op_out[2])
|
||
|
|
abort ();
|
||
|
|
- if (vex.length == 128
|
||
|
|
+ if (ins->vex.length == 128
|
||
|
|
|| (bytemode != vex_vsib_d_w_dq_mode
|
||
|
|
- && !vex.w))
|
||
|
|
- oappend (names_xmm[reg]);
|
||
|
|
+ && !ins->vex.w))
|
||
|
|
+ oappend (ins, ins->names_xmm[reg]);
|
||
|
|
else
|
||
|
|
- oappend (names_ymm[reg]);
|
||
|
|
+ oappend (ins, ins->names_ymm[reg]);
|
||
|
|
|
||
|
|
/* All 3 XMM/YMM registers must be distinct. */
|
||
|
|
- modrm_reg = modrm.reg;
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ modrm_reg = ins->modrm.reg;
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
modrm_reg += 8;
|
||
|
|
|
||
|
|
- if (modrm.rm == 4)
|
||
|
|
+ if (ins->modrm.rm == 4)
|
||
|
|
{
|
||
|
|
- sib_index = sib.index;
|
||
|
|
- if (rex & REX_X)
|
||
|
|
+ sib_index = ins->sib.index;
|
||
|
|
+ if (ins->rex & REX_X)
|
||
|
|
sib_index += 8;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reg == modrm_reg || reg == sib_index)
|
||
|
|
- strcpy (obufp, "/(bad)");
|
||
|
|
+ strcpy (ins->obufp, "/(bad)");
|
||
|
|
if (modrm_reg == sib_index || modrm_reg == reg)
|
||
|
|
- strcat (op_out[0], "/(bad)");
|
||
|
|
+ strcat (ins->op_out[0], "/(bad)");
|
||
|
|
if (sib_index == modrm_reg || sib_index == reg)
|
||
|
|
- strcat (op_out[1], "/(bad)");
|
||
|
|
+ strcat (ins->op_out[1], "/(bad)");
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
case tmm_mode:
|
||
|
|
/* All 3 TMM registers must be distinct. */
|
||
|
|
if (reg >= 8)
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* This must be the 3rd operand. */
|
||
|
|
- if (obufp != op_out[2])
|
||
|
|
+ if (ins->obufp != ins->op_out[2])
|
||
|
|
abort ();
|
||
|
|
- oappend (names_tmm[reg]);
|
||
|
|
- if (reg == modrm.reg || reg == modrm.rm)
|
||
|
|
- strcpy (obufp, "/(bad)");
|
||
|
|
+ oappend (ins, ins->names_tmm[reg]);
|
||
|
|
+ if (reg == ins->modrm.reg || reg == ins->modrm.rm)
|
||
|
|
+ strcpy (ins->obufp, "/(bad)");
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (modrm.reg == modrm.rm || modrm.reg == reg || modrm.rm == reg)
|
||
|
|
+ if (ins->modrm.reg == ins->modrm.rm || ins->modrm.reg == reg
|
||
|
|
+ || ins->modrm.rm == reg)
|
||
|
|
{
|
||
|
|
- if (modrm.reg <= 8
|
||
|
|
- && (modrm.reg == modrm.rm || modrm.reg == reg))
|
||
|
|
- strcat (op_out[0], "/(bad)");
|
||
|
|
- if (modrm.rm <= 8
|
||
|
|
- && (modrm.rm == modrm.reg || modrm.rm == reg))
|
||
|
|
- strcat (op_out[1], "/(bad)");
|
||
|
|
+ if (ins->modrm.reg <= 8
|
||
|
|
+ && (ins->modrm.reg == ins->modrm.rm || ins->modrm.reg == reg))
|
||
|
|
+ strcat (ins->op_out[0], "/(bad)");
|
||
|
|
+ if (ins->modrm.rm <= 8
|
||
|
|
+ && (ins->modrm.rm == ins->modrm.reg || ins->modrm.rm == reg))
|
||
|
|
+ strcat (ins->op_out[1], "/(bad)");
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
- switch (vex.length)
|
||
|
|
+ switch (ins->vex.length)
|
||
|
|
{
|
||
|
|
case 128:
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case x_mode:
|
||
|
|
- names = names_xmm;
|
||
|
|
+ names = ins->names_xmm;
|
||
|
|
break;
|
||
|
|
case dq_mode:
|
||
|
|
- if (rex & REX_W)
|
||
|
|
- names = names64;
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
+ names = ins->names64;
|
||
|
|
else
|
||
|
|
- names = names32;
|
||
|
|
+ names = ins->names32;
|
||
|
|
break;
|
||
|
|
case mask_bd_mode:
|
||
|
|
case mask_mode:
|
||
|
|
if (reg > 0x7)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- names = names_mask;
|
||
|
|
+ names = ins->names_mask;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
@@ -13406,112 +13442,112 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case x_mode:
|
||
|
|
- names = names_ymm;
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
break;
|
||
|
|
case mask_bd_mode:
|
||
|
|
case mask_mode:
|
||
|
|
if (reg > 0x7)
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
- names = names_mask;
|
||
|
|
+ names = ins->names_mask;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
/* See PR binutils/20893 for a reproducer. */
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 512:
|
||
|
|
- names = names_zmm;
|
||
|
|
+ names = ins->names_zmm;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_VexR (int bytemode, int sizeflag)
|
||
|
|
+OP_VexR (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
- OP_VEX (bytemode, sizeflag);
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
+ OP_VEX (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_VexW (int bytemode, int sizeflag)
|
||
|
|
+OP_VexW (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- OP_VEX (bytemode, sizeflag);
|
||
|
|
+ OP_VEX (ins, bytemode, sizeflag);
|
||
|
|
|
||
|
|
- if (vex.w)
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
{
|
||
|
|
/* Swap 2nd and 3rd operands. */
|
||
|
|
- strcpy (scratchbuf, op_out[2]);
|
||
|
|
- strcpy (op_out[2], op_out[1]);
|
||
|
|
- strcpy (op_out[1], scratchbuf);
|
||
|
|
+ strcpy (ins->scratchbuf, ins->op_out[2]);
|
||
|
|
+ strcpy (ins->op_out[2], ins->op_out[1]);
|
||
|
|
+ strcpy (ins->op_out[1], ins->scratchbuf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_REG_VexI4 (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
int reg;
|
||
|
|
- const char **names = names_xmm;
|
||
|
|
+ const char **names = ins->names_xmm;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- reg = *codep++;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ reg = *ins->codep++;
|
||
|
|
|
||
|
|
if (bytemode != x_mode && bytemode != scalar_mode)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
reg >>= 4;
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
reg &= 7;
|
||
|
|
|
||
|
|
- if (bytemode == x_mode && vex.length == 256)
|
||
|
|
- names = names_ymm;
|
||
|
|
+ if (bytemode == x_mode && ins->vex.length == 256)
|
||
|
|
+ names = ins->names_ymm;
|
||
|
|
|
||
|
|
- oappend (names[reg]);
|
||
|
|
+ oappend (ins, names[reg]);
|
||
|
|
|
||
|
|
- if (vex.w)
|
||
|
|
+ if (ins->vex.w)
|
||
|
|
{
|
||
|
|
/* Swap 3rd and 4th operands. */
|
||
|
|
- strcpy (scratchbuf, op_out[3]);
|
||
|
|
- strcpy (op_out[3], op_out[2]);
|
||
|
|
- strcpy (op_out[2], scratchbuf);
|
||
|
|
+ strcpy (ins->scratchbuf, ins->op_out[3]);
|
||
|
|
+ strcpy (ins->op_out[3], ins->op_out[2]);
|
||
|
|
+ strcpy (ins->op_out[2], ins->scratchbuf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_VexI4 (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+OP_VexI4 (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, codep[-1] & 0xf);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, ins->codep[-1] & 0xf);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-VPCMP_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+VPCMP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
unsigned int cmp_type;
|
||
|
|
|
||
|
|
- if (!vex.evex)
|
||
|
|
+ if (!ins->vex.evex)
|
||
|
|
abort ();
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- cmp_type = *codep++ & 0xff;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ cmp_type = *ins->codep++ & 0xff;
|
||
|
|
/* There are aliases for immediates 0, 1, 2, 4, 5, 6.
|
||
|
|
If it's the case, print suffix, otherwise - print the immediate. */
|
||
|
|
if (cmp_type < ARRAY_SIZE (simd_cmp_op)
|
||
|
|
&& cmp_type != 3
|
||
|
|
&& cmp_type != 7)
|
||
|
|
{
|
||
|
|
- char suffix [3];
|
||
|
|
- char *p = mnemonicendp - 2;
|
||
|
|
+ char suffix[3];
|
||
|
|
+ char *p = ins->mnemonicendp - 2;
|
||
|
|
|
||
|
|
/* vpcmp* can have both one- and two-lettered suffix. */
|
||
|
|
if (p[0] == 'p')
|
||
|
|
@@ -13528,15 +13564,15 @@ VPCMP_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
}
|
||
|
|
|
||
|
|
sprintf (p, "%s%s", simd_cmp_op[cmp_type].name, suffix);
|
||
|
|
- mnemonicendp += simd_cmp_op[cmp_type].len;
|
||
|
|
+ ins->mnemonicendp += simd_cmp_op[cmp_type].len;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* We have a reserved extension byte. Output it directly. */
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, cmp_type);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, cmp_type);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -13553,17 +13589,17 @@ static const struct op xop_cmp_op[] =
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
-VPCOM_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+VPCOM_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
unsigned int cmp_type;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- cmp_type = *codep++ & 0xff;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ cmp_type = *ins->codep++ & 0xff;
|
||
|
|
if (cmp_type < ARRAY_SIZE (xop_cmp_op))
|
||
|
|
{
|
||
|
|
char suffix[3];
|
||
|
|
- char *p = mnemonicendp - 2;
|
||
|
|
+ char *p = ins->mnemonicendp - 2;
|
||
|
|
|
||
|
|
/* vpcom* can have both one- and two-lettered suffix. */
|
||
|
|
if (p[0] == 'm')
|
||
|
|
@@ -13580,15 +13616,15 @@ VPCOM_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
}
|
||
|
|
|
||
|
|
sprintf (p, "%s%s", xop_cmp_op[cmp_type].name, suffix);
|
||
|
|
- mnemonicendp += xop_cmp_op[cmp_type].len;
|
||
|
|
+ ins->mnemonicendp += xop_cmp_op[cmp_type].len;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* We have a reserved extension byte. Output it directly. */
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, cmp_type);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, cmp_type);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -13601,13 +13637,13 @@ static const struct op pclmul_op[] =
|
||
|
|
};
|
||
|
|
|
||
|
|
static void
|
||
|
|
-PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
+PCLMUL_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
unsigned int pclmul_type;
|
||
|
|
|
||
|
|
- FETCH_DATA (the_info, codep + 1);
|
||
|
|
- pclmul_type = *codep++ & 0xff;
|
||
|
|
+ FETCH_DATA (ins->info, ins->codep + 1);
|
||
|
|
+ pclmul_type = *ins->codep++ & 0xff;
|
||
|
|
switch (pclmul_type)
|
||
|
|
{
|
||
|
|
case 0x10:
|
||
|
|
@@ -13621,38 +13657,38 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
|
||
|
|
}
|
||
|
|
if (pclmul_type < ARRAY_SIZE (pclmul_op))
|
||
|
|
{
|
||
|
|
- char suffix [4];
|
||
|
|
- char *p = mnemonicendp - 3;
|
||
|
|
+ char suffix[4];
|
||
|
|
+ char *p = ins->mnemonicendp - 3;
|
||
|
|
suffix[0] = p[0];
|
||
|
|
suffix[1] = p[1];
|
||
|
|
suffix[2] = p[2];
|
||
|
|
suffix[3] = '\0';
|
||
|
|
sprintf (p, "%s%s", pclmul_op[pclmul_type].name, suffix);
|
||
|
|
- mnemonicendp += pclmul_op[pclmul_type].len;
|
||
|
|
+ ins->mnemonicendp += pclmul_op[pclmul_type].len;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* We have a reserved extension byte. Output it directly. */
|
||
|
|
- scratchbuf[0] = '$';
|
||
|
|
- print_operand_value (scratchbuf + 1, 1, pclmul_type);
|
||
|
|
- oappend_maybe_intel (scratchbuf);
|
||
|
|
- scratchbuf[0] = '\0';
|
||
|
|
+ ins->scratchbuf[0] = '$';
|
||
|
|
+ print_operand_value (ins, ins->scratchbuf + 1, 1, pclmul_type);
|
||
|
|
+ oappend_maybe_intel (ins, ins->scratchbuf);
|
||
|
|
+ ins->scratchbuf[0] = '\0';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-MOVSXD_Fixup (int bytemode, int sizeflag)
|
||
|
|
+MOVSXD_Fixup (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
/* Add proper suffix to "movsxd". */
|
||
|
|
- char *p = mnemonicendp;
|
||
|
|
+ char *p = ins->mnemonicendp;
|
||
|
|
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case movsxd_mode:
|
||
|
|
- if (!intel_syntax)
|
||
|
|
+ if (!ins->intel_syntax)
|
||
|
|
{
|
||
|
|
USED_REX (REX_W);
|
||
|
|
- if (rex & REX_W)
|
||
|
|
+ if (ins->rex & REX_W)
|
||
|
|
{
|
||
|
|
*p++ = 'l';
|
||
|
|
*p++ = 'q';
|
||
|
|
@@ -13664,77 +13700,77 @@ MOVSXD_Fixup (int bytemode, int sizeflag)
|
||
|
|
*p++ = 'd';
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
- oappend (INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
+ oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
- mnemonicendp = p;
|
||
|
|
+ ins->mnemonicendp = p;
|
||
|
|
*p = '\0';
|
||
|
|
- OP_E (bytemode, sizeflag);
|
||
|
|
+ OP_E (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-DistinctDest_Fixup (int bytemode, int sizeflag)
|
||
|
|
+DistinctDest_Fixup (instr_info *ins, int bytemode, int sizeflag)
|
||
|
|
{
|
||
|
|
- unsigned int reg = vex.register_specifier;
|
||
|
|
- unsigned int modrm_reg = modrm.reg;
|
||
|
|
- unsigned int modrm_rm = modrm.rm;
|
||
|
|
+ unsigned int reg = ins->vex.register_specifier;
|
||
|
|
+ unsigned int modrm_reg = ins->modrm.reg;
|
||
|
|
+ unsigned int modrm_rm = ins->modrm.rm;
|
||
|
|
|
||
|
|
/* Calc destination register number. */
|
||
|
|
- if (rex & REX_R)
|
||
|
|
+ if (ins->rex & REX_R)
|
||
|
|
modrm_reg += 8;
|
||
|
|
- if (!vex.r)
|
||
|
|
+ if (!ins->vex.r)
|
||
|
|
modrm_reg += 16;
|
||
|
|
|
||
|
|
/* Calc src1 register number. */
|
||
|
|
- if (address_mode != mode_64bit)
|
||
|
|
+ if (ins->address_mode != mode_64bit)
|
||
|
|
reg &= 7;
|
||
|
|
- else if (vex.evex && !vex.v)
|
||
|
|
+ else if (ins->vex.evex && !ins->vex.v)
|
||
|
|
reg += 16;
|
||
|
|
|
||
|
|
/* Calc src2 register number. */
|
||
|
|
- if (modrm.mod == 3)
|
||
|
|
+ if (ins->modrm.mod == 3)
|
||
|
|
{
|
||
|
|
- if (rex & REX_B)
|
||
|
|
+ if (ins->rex & REX_B)
|
||
|
|
modrm_rm += 8;
|
||
|
|
- if (rex & REX_X)
|
||
|
|
+ if (ins->rex & REX_X)
|
||
|
|
modrm_rm += 16;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Destination and source registers must be distinct, output bad if
|
||
|
|
dest == src1 or dest == src2. */
|
||
|
|
if (modrm_reg == reg
|
||
|
|
- || (modrm.mod == 3
|
||
|
|
+ || (ins->modrm.mod == 3
|
||
|
|
&& modrm_reg == modrm_rm))
|
||
|
|
{
|
||
|
|
- oappend ("(bad)");
|
||
|
|
+ oappend (ins, "(bad)");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
- OP_XMM (bytemode, sizeflag);
|
||
|
|
+ OP_XMM (ins, bytemode, sizeflag);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void
|
||
|
|
-OP_Rounding (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
+OP_Rounding (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
- if (modrm.mod != 3 || !vex.b)
|
||
|
|
+ if (ins->modrm.mod != 3 || !ins->vex.b)
|
||
|
|
return;
|
||
|
|
|
||
|
|
switch (bytemode)
|
||
|
|
{
|
||
|
|
case evex_rounding_64_mode:
|
||
|
|
- if (address_mode != mode_64bit || !vex.w)
|
||
|
|
+ if (ins->address_mode != mode_64bit || !ins->vex.w)
|
||
|
|
return;
|
||
|
|
/* Fall through. */
|
||
|
|
case evex_rounding_mode:
|
||
|
|
- evex_used |= EVEX_b_used;
|
||
|
|
- oappend (names_rounding[vex.ll]);
|
||
|
|
+ ins->evex_used |= EVEX_b_used;
|
||
|
|
+ oappend (ins, names_rounding[ins->vex.ll]);
|
||
|
|
break;
|
||
|
|
case evex_sae_mode:
|
||
|
|
- evex_used |= EVEX_b_used;
|
||
|
|
- oappend ("{");
|
||
|
|
+ ins->evex_used |= EVEX_b_used;
|
||
|
|
+ oappend (ins, "{");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
abort ();
|
||
|
|
}
|
||
|
|
- oappend ("sae}");
|
||
|
|
+ oappend (ins, "sae}");
|
||
|
|
}
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|