#include <setjmp.h>
typedef struct instr_info 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 bool dofloat (instr_info *, int);
static int putop (instr_info *, const char *, int);
static void oappend_with_style (instr_info *, const char *,
enum disassembler_style);
static void oappend (instr_info *, const char *);
static void append_seg (instr_info *);
-static void OP_indirE (instr_info *, int, int);
-static void OP_E_memory (instr_info *, int, int);
-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, bool);
-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_Fixup (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);
-static void PREFETCHI_Fixup (instr_info *, int, int);
+
+static bool OP_E (instr_info *, int, int);
+static bool OP_E_memory (instr_info *, int, int);
+static bool OP_indirE (instr_info *, int, int);
+static bool OP_G (instr_info *, int, int);
+static bool OP_ST (instr_info *, int, int);
+static bool OP_STi (instr_info *, int, int);
+static bool OP_Skip_MODRM (instr_info *, int, int);
+static bool OP_REG (instr_info *, int, int);
+static bool OP_IMREG (instr_info *, int, int);
+static bool OP_I (instr_info *, int, int);
+static bool OP_I64 (instr_info *, int, int);
+static bool OP_sI (instr_info *, int, int);
+static bool OP_J (instr_info *, int, int);
+static bool OP_SEG (instr_info *, int, int);
+static bool OP_DIR (instr_info *, int, int);
+static bool OP_OFF (instr_info *, int, int);
+static bool OP_OFF64 (instr_info *, int, int);
+static bool OP_ESreg (instr_info *, int, int);
+static bool OP_DSreg (instr_info *, int, int);
+static bool OP_C (instr_info *, int, int);
+static bool OP_D (instr_info *, int, int);
+static bool OP_T (instr_info *, int, int);
+static bool OP_MMX (instr_info *, int, int);
+static bool OP_XMM (instr_info *, int, int);
+static bool OP_EM (instr_info *, int, int);
+static bool OP_EX (instr_info *, int, int);
+static bool OP_EMC (instr_info *, int,int);
+static bool OP_MXC (instr_info *, int,int);
+static bool OP_MS (instr_info *, int, int);
+static bool OP_XS (instr_info *, int, int);
+static bool OP_M (instr_info *, int, int);
+static bool OP_VEX (instr_info *, int, int);
+static bool OP_VexR (instr_info *, int, int);
+static bool OP_VexW (instr_info *, int, int);
+static bool OP_Rounding (instr_info *, int, int);
+static bool OP_REG_VexI4 (instr_info *, int, int);
+static bool OP_VexI4 (instr_info *, int, int);
+static bool OP_0f07 (instr_info *, int, int);
+static bool OP_Monitor (instr_info *, int, int);
+static bool OP_Mwait (instr_info *, int, int);
+
+static bool BadOp (instr_info *);
+
+static bool PCLMUL_Fixup (instr_info *, int, int);
+static bool VPCMP_Fixup (instr_info *, int, int);
+static bool VPCOM_Fixup (instr_info *, int, int);
+static bool NOP_Fixup (instr_info *, int, int);
+static bool OP_3DNowSuffix (instr_info *, int, int);
+static bool CMP_Fixup (instr_info *, int, int);
+static bool REP_Fixup (instr_info *, int, int);
+static bool SEP_Fixup (instr_info *, int, int);
+static bool BND_Fixup (instr_info *, int, int);
+static bool NOTRACK_Fixup (instr_info *, int, int);
+static bool HLE_Fixup1 (instr_info *, int, int);
+static bool HLE_Fixup2 (instr_info *, int, int);
+static bool HLE_Fixup3 (instr_info *, int, int);
+static bool CMPXCHG8B_Fixup (instr_info *, int, int);
+static bool XMM_Fixup (instr_info *, int, int);
+static bool FXSAVE_Fixup (instr_info *, int, int);
+static bool MOVSXD_Fixup (instr_info *, int, int);
+static bool DistinctDest_Fixup (instr_info *, int, int);
+static bool PREFETCHI_Fixup (instr_info *, int, int);
static void ATTRIBUTE_PRINTF_3 i386_dis_printf (const instr_info *,
enum disassembler_style,
EVEX_W_MAP5_7A_P_3,
};
-typedef void (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
+typedef bool (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
struct dis386 {
const char *name;
if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
{
- if (!get_sib (&ins, sizeflag))
+ if (!get_sib (&ins, sizeflag)
+ || !dofloat (&ins, sizeflag))
return fetch_error (&ins);
- dofloat (&ins, sizeflag);
}
else
{
{
ins.obufp = ins.op_out[i];
ins.op_ad = MAX_OPERANDS - 1 - i;
- if (dp->op[i].rtn)
- (*dp->op[i].rtn) (&ins, dp->op[i].bytemode, sizeflag);
+ if (dp->op[i].rtn
+ && !dp->op[i].rtn (&ins, dp->op[i].bytemode, sizeflag))
+ return fetch_error (&ins);
/* For EVEX instruction after the last operand masking
should be printed. */
if (i == 0 && ins.vex.evex)
ins->mnemonicendp += 2;
}
-static void
+static bool
OP_Skip_MODRM (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
/* Skip mod/rm byte. */
MODRM_CHECK;
ins->codep++;
+ return true;
}
-static void
+static bool
dofloat (instr_info *ins, int sizeflag)
{
const struct dis386 *dp;
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;
+ return OP_E (ins, float_mem_mode[fp_indx], sizeflag);
}
/* Skip mod/rm byte. */
MODRM_CHECK;
ins->obufp = ins->op_out[0];
ins->op_ad = 2;
- if (dp->op[0].rtn)
- (*dp->op[0].rtn) (ins, dp->op[0].bytemode, sizeflag);
+ if (dp->op[0].rtn
+ && !dp->op[0].rtn (ins, dp->op[0].bytemode, sizeflag))
+ return false;
ins->obufp = ins->op_out[1];
ins->op_ad = 1;
- if (dp->op[1].rtn)
- (*dp->op[1].rtn) (ins, dp->op[1].bytemode, sizeflag);
+ if (dp->op[1].rtn
+ && !dp->op[1].rtn (ins, dp->op[1].bytemode, sizeflag))
+ return false;
}
+ return true;
}
-static void
+static bool
OP_ST (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
oappend_register (ins, "%st");
+ return true;
}
-static void
+static bool
OP_STi (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (res < 0 || (size_t) res >= ARRAY_SIZE (scratch))
abort ();
oappend_register (ins, scratch);
+ return true;
}
/* Capital letters in template are macros. */
oappend_char (ins, ':');
}
-static void
+static bool
OP_indirE (instr_info *ins, int bytemode, int sizeflag)
{
if (!ins->intel_syntax)
oappend (ins, "*");
- OP_E (ins, bytemode, sizeflag);
+ return OP_E (ins, bytemode, sizeflag);
}
static void
oappend_register (ins, names[reg]);
}
-static void
+static bool
OP_E_memory (instr_info *ins, int bytemode, int sizeflag)
{
bfd_vma disp = 0;
|| bytemode == vex_sibmem_mode)
{
oappend (ins, "(bad)");
- return;
+ return true;
}
}
rbase = base + add;
if (riprel && bytemode == v_bndmk_mode)
{
oappend (ins, "(bad)");
- return;
+ return true;
}
}
break;
case 1:
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
disp = *ins->codep++;
if ((disp & 0x80) != 0)
disp -= 0x100;
|| bytemode == vex_vsib_q_w_dq_mode)
{
oappend (ins, "(bad)");
- return;
+ return true;
}
else
{
}
break;
case 1:
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
disp = *ins->codep++;
if ((disp & 0x80) != 0)
disp -= 0x100;
if (ins->vex.no_broadcast)
oappend (ins, "{bad}");
}
+
+ return true;
}
-static void
+static bool
OP_E (instr_info *ins, int bytemode, int sizeflag)
{
/* Skip mod/rm byte. */
swap_operand (ins);
print_register (ins, ins->modrm.rm, REX_B, bytemode, sizeflag);
+ return true;
}
- else
- OP_E_memory (ins, bytemode, sizeflag);
+
+ return OP_E_memory (ins, bytemode, sizeflag);
}
-static void
+static bool
OP_G (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->vex.evex && !ins->vex.r && ins->address_mode == mode_64bit)
- {
- oappend (ins, "(bad)");
- return;
- }
-
- print_register (ins, ins->modrm.reg, REX_R, bytemode, sizeflag);
+ oappend (ins, "(bad)");
+ else
+ print_register (ins, ins->modrm.reg, REX_R, bytemode, sizeflag);
+ return true;
}
#ifdef BFD64
ins->op_riprel[ins->op_ad] = riprel;
}
-static void
+static bool
OP_REG (instr_info *ins, int code, int sizeflag)
{
const char *s;
case es_reg: case ss_reg: case cs_reg:
case ds_reg: case fs_reg: case gs_reg:
oappend_register (ins, att_names_seg[code - es_reg]);
- return;
+ return true;
}
USED_REX (REX_B);
break;
default:
oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
- return;
+ return true;
}
oappend_register (ins, s);
+ return true;
}
-static void
+static bool
OP_IMREG (instr_info *ins, int code, int sizeflag)
{
const char *s;
if (!ins->intel_syntax)
{
oappend (ins, "(%dx)");
- return;
+ return true;
}
s = att_names16[dx_reg - ax_reg];
break;
break;
default:
oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
- return;
+ return true;
}
oappend_register (ins, s);
+ return true;
}
-static void
+static bool
OP_I (instr_info *ins, int bytemode, int sizeflag)
{
bfd_signed_vma op;
switch (bytemode)
{
case b_mode:
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
op = *ins->codep++;
mask = 0xff;
break;
case const_1_mode:
if (ins->intel_syntax)
oappend (ins, "1");
- return;
+ return true;
default:
oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
- return;
+ return true;
}
op &= mask;
oappend_immediate (ins, op);
+ return true;
}
-static void
+static bool
OP_I64 (instr_info *ins, int bytemode, int sizeflag)
{
if (bytemode != v_mode || ins->address_mode != mode_64bit
|| !(ins->rex & REX_W))
- {
- OP_I (ins, bytemode, sizeflag);
- return;
- }
+ return OP_I (ins, bytemode, sizeflag);
USED_REX (REX_W);
oappend_immediate (ins, get64 (ins));
+ return true;
}
-static void
+static bool
OP_sI (instr_info *ins, int bytemode, int sizeflag)
{
bfd_signed_vma op;
{
case b_mode:
case b_T_mode:
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
op = *ins->codep++;
if ((op & 0x80) != 0)
op -= 0x100;
break;
default:
oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
- return;
+ return true;
}
oappend_immediate (ins, op);
+ return true;
}
-static void
+static bool
OP_J (instr_info *ins, int bytemode, int sizeflag)
{
bfd_vma disp;
switch (bytemode)
{
case b_mode:
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
disp = *ins->codep++;
if ((disp & 0x80) != 0)
disp -= 0x100;
break;
default:
oappend (ins, INTERNAL_DISASSEMBLER_ERROR);
- return;
+ return true;
}
disp = ((ins->start_pc + (ins->codep - ins->start_codep) + disp) & mask)
| segment;
set_op (ins, disp, false);
print_operand_value (ins, disp, dis_style_text);
+ return true;
}
-static void
+static bool
OP_SEG (instr_info *ins, int bytemode, int sizeflag)
{
if (bytemode == w_mode)
- oappend_register (ins, att_names_seg[ins->modrm.reg]);
- else
- OP_E (ins, ins->modrm.mod == 3 ? bytemode : w_mode, sizeflag);
+ {
+ oappend_register (ins, att_names_seg[ins->modrm.reg]);
+ return true;
+ }
+ return OP_E (ins, ins->modrm.mod == 3 ? bytemode : w_mode, sizeflag);
}
-static void
+static bool
OP_DIR (instr_info *ins, int dummy ATTRIBUTE_UNUSED, int sizeflag)
{
int seg, offset, res;
if (res < 0 || (size_t) res >= ARRAY_SIZE (scratch))
abort ();
oappend (ins, scratch);
+ return true;
}
-static void
+static bool
OP_OFF (instr_info *ins, int bytemode, int sizeflag)
{
bfd_vma off;
}
}
print_operand_value (ins, off, dis_style_address_offset);
+ return true;
}
-static void
+static bool
OP_OFF64 (instr_info *ins, int bytemode, int sizeflag)
{
bfd_vma off;
if (ins->address_mode != mode_64bit
|| (ins->prefixes & PREFIX_ADDR))
- {
- OP_OFF (ins, bytemode, sizeflag);
- return;
- }
+ return OP_OFF (ins, bytemode, sizeflag);
if (ins->intel_syntax && (sizeflag & SUFFIX_ALWAYS))
intel_operand_size (ins, bytemode, sizeflag);
}
}
print_operand_value (ins, off, dis_style_address_offset);
+ return true;
}
static void
oappend_char (ins, ins->close_char);
}
-static void
+static bool
OP_ESreg (instr_info *ins, int code, int sizeflag)
{
if (ins->intel_syntax)
oappend_register (ins, att_names_seg[0]);
oappend_char (ins, ':');
ptr_reg (ins, code, sizeflag);
+ return true;
}
-static void
+static bool
OP_DSreg (instr_info *ins, int code, int sizeflag)
{
if (ins->intel_syntax)
ins->active_seg_prefix = PREFIX_DS;
append_seg (ins);
ptr_reg (ins, code, sizeflag);
+ return true;
}
-static void
+static bool
OP_C (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (res < 0 || (size_t) res >= ARRAY_SIZE (scratch))
abort ();
oappend_register (ins, scratch);
+ return true;
}
-static void
+static bool
OP_D (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (res < 0 || (size_t) res >= ARRAY_SIZE (scratch))
abort ();
oappend (ins, scratch);
+ return true;
}
-static void
+static bool
OP_T (instr_info *ins, int dummy ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (res < 0 || (size_t) res >= ARRAY_SIZE (scratch))
abort ();
oappend_register (ins, scratch);
+ return true;
}
-static void
+static bool
OP_MMX (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
else
names = att_names_mm;
oappend_register (ins, names[reg]);
+ return true;
}
static void
oappend_register (ins, names[reg]);
}
-static void
+static bool
OP_XMM (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
unsigned int reg = ins->modrm.reg;
ins->vex.no_broadcast = true;
print_vector_reg (ins, reg, bytemode);
+ return true;
}
-static void
+static bool
OP_EM (instr_info *ins, int bytemode, int sizeflag)
{
int reg;
bytemode = (ins->prefixes & PREFIX_DATA) ? x_mode : q_mode;
ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
}
- OP_E (ins, bytemode, sizeflag);
- return;
+ return OP_E (ins, bytemode, sizeflag);
}
if ((sizeflag & SUFFIX_ALWAYS) && bytemode == v_swap_mode)
else
names = att_names_mm;
oappend_register (ins, names[reg]);
+ return true;
}
/* cvt* are the only instructions in sse2 which have
in their opcode. 0x66 was originally used to differentiate
between SSE and MMX instruction(operands). So we have to handle the
cvt* separately using OP_EMC and OP_MXC */
-static void
+static bool
OP_EMC (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 3)
bytemode = (ins->prefixes & PREFIX_DATA) ? x_mode : q_mode;
ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
}
- OP_E (ins, bytemode, sizeflag);
- return;
+ return OP_E (ins, bytemode, sizeflag);
}
/* Skip mod/rm byte. */
ins->codep++;
ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
oappend_register (ins, att_names_mm[ins->modrm.rm]);
+ return true;
}
-static void
+static bool
OP_MXC (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
oappend_register (ins, att_names_mm[ins->modrm.reg]);
+ return true;
}
-static void
+static bool
OP_EX (instr_info *ins, int bytemode, int sizeflag)
{
int reg;
bytemode = ins->vex.w ? q_mode : d_mode;
if (ins->modrm.mod != 3)
- {
- OP_E_memory (ins, bytemode, sizeflag);
- return;
- }
+ return OP_E_memory (ins, bytemode, sizeflag);
reg = ins->modrm.rm;
USED_REX (REX_B);
ins->modrm.rm = reg;
print_vector_reg (ins, reg, bytemode);
+ return true;
}
-static void
+static bool
OP_MS (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod == 3)
- OP_EM (ins, bytemode, sizeflag);
- else
- BadOp (ins);
+ return OP_EM (ins, bytemode, sizeflag);
+ return BadOp (ins);
}
-static void
+static bool
OP_XS (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod == 3)
- OP_EX (ins, bytemode, sizeflag);
- else
- BadOp (ins);
+ return OP_EX (ins, bytemode, sizeflag);
+ return BadOp (ins);
}
-static void
+static bool
OP_M (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod == 3)
/* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
- BadOp (ins);
- else
- OP_E (ins, bytemode, sizeflag);
+ return BadOp (ins);
+ return OP_E (ins, bytemode, sizeflag);
}
-static void
+static bool
OP_0f07 (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 3 || ins->modrm.rm != 0)
- BadOp (ins);
- else
- OP_E (ins, bytemode, sizeflag);
+ return BadOp (ins);
+ return 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
+static bool
NOP_Fixup (instr_info *ins, int opnd, int sizeflag)
{
if ((ins->prefixes & PREFIX_DATA) == 0 && (ins->rex & REX_B) == 0)
- ins->mnemonicendp = stpcpy (ins->obuf, "nop");
- else if (opnd == 0)
- OP_REG (ins, eAX_reg, sizeflag);
- else
- OP_IMREG (ins, eAX_reg, sizeflag);
+ {
+ ins->mnemonicendp = stpcpy (ins->obuf, "nop");
+ return true;
+ }
+ if (opnd == 0)
+ return OP_REG (ins, eAX_reg, sizeflag);
+ return OP_IMREG (ins, eAX_reg, sizeflag);
}
static const char *const Suffix3DNow[] = {
/* FC */ NULL, NULL, NULL, NULL,
};
-static void
+static bool
OP_3DNowSuffix (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
const char *mnemonic;
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
/* 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. */
BadOp (ins);
}
ins->mnemonicendp = ins->obufp;
+ return true;
}
static const struct op simd_cmp_op[] =
{ STRING_COMMA_LEN ("true_us") },
};
-static void
+static bool
CMP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
unsigned int cmp_type;
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
cmp_type = *ins->codep++ & 0xff;
if (cmp_type < ARRAY_SIZE (simd_cmp_op))
{
/* We have a reserved extension byte. Output it directly. */
oappend_immediate (ins, cmp_type);
}
+ return true;
}
-static void
+static bool
OP_Mwait (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
/* mwait %eax,%ecx / mwaitx %eax,%ecx,%ebx */
/* Skip mod/rm byte. */
MODRM_CHECK;
ins->codep++;
+ return true;
}
-static void
+static bool
OP_Monitor (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
/* Skip mod/rm byte. */
MODRM_CHECK;
ins->codep++;
+ return true;
}
-static void
+static bool
BadOp (instr_info *ins)
{
/* Throw away prefixes and 1st. opcode byte. */
ins->codep = ins->insn_codep + 1;
ins->obufp = stpcpy (ins->obufp, "(bad)");
+ return true;
}
-static void
+static bool
REP_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
/* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
case al_reg:
case eAX_reg:
case indir_dx_reg:
- OP_IMREG (ins, bytemode, sizeflag);
- break;
+ return OP_IMREG (ins, bytemode, sizeflag);
case eDI_reg:
- OP_ESreg (ins, bytemode, sizeflag);
- break;
+ return OP_ESreg (ins, bytemode, sizeflag);
case eSI_reg:
- OP_DSreg (ins, bytemode, sizeflag);
- break;
+ return OP_DSreg (ins, bytemode, sizeflag);
default:
abort ();
break;
}
+ return true;
}
-static void
+static bool
SEP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (ins->isa64 != amd64)
- return;
+ return true;
ins->obufp = ins->obuf;
BadOp (ins);
ins->mnemonicendp = ins->obufp;
++ins->codep;
+ return true;
}
/* For BND-prefixed instructions 0xF2 prefix should be displayed as
"bnd". */
-static void
+static bool
BND_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (ins->prefixes & PREFIX_REPNZ)
ins->all_prefixes[ins->last_repnz_prefix] = BND_PREFIX;
+ return true;
}
/* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
"notrack". */
-static void
+static bool
NOTRACK_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
ins->active_seg_prefix = 0;
ins->all_prefixes[ins->last_seg_prefix] = NOTRACK_PREFIX;
}
+ return true;
}
/* 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
+static bool
HLE_Fixup1 (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 3
ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
}
- OP_E (ins, bytemode, sizeflag);
+ return OP_E (ins, bytemode, sizeflag);
}
/* 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
+static bool
HLE_Fixup2 (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 3)
ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
}
- OP_E (ins, bytemode, sizeflag);
+ return 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
+static bool
HLE_Fixup3 (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 3
&& (ins->prefixes & PREFIX_REPZ) != 0)
ins->all_prefixes[ins->last_repz_prefix] = XRELEASE_PREFIX;
- OP_E (ins, bytemode, sizeflag);
+ return OP_E (ins, bytemode, sizeflag);
}
-static void
+static bool
CMPXCHG8B_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
USED_REX (REX_W);
ins->all_prefixes[ins->last_repnz_prefix] = XACQUIRE_PREFIX;
}
- OP_M (ins, bytemode, sizeflag);
+ return OP_M (ins, bytemode, sizeflag);
}
-static void
+static bool
XMM_Fixup (instr_info *ins, int reg, int sizeflag ATTRIBUTE_UNUSED)
{
const char (*names)[8] = att_names_xmm;
}
}
oappend_register (ins, names[reg]);
+ return true;
}
-static void
+static bool
FXSAVE_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
/* Add proper suffix to "fxsave" and "fxrstor". */
*p = '\0';
ins->mnemonicendp = p;
}
- OP_M (ins, bytemode, sizeflag);
+ return OP_M (ins, bytemode, sizeflag);
}
/* Display the destination register operand for instructions with
VEX. */
-static void
+static bool
OP_VEX (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
int reg, modrm_reg, sib_index = -1;
if (ins->vex.evex && !ins->vex.v)
{
oappend (ins, "(bad)");
- return;
+ return true;
}
reg &= 7;
{
case scalar_mode:
oappend_register (ins, att_names_xmm[reg]);
- return;
+ return true;
case vex_vsib_d_w_dq_mode:
case vex_vsib_q_w_dq_mode:
if (sib_index == modrm_reg || sib_index == reg)
strcat (ins->op_out[1], "/(bad)");
- return;
+ return true;
case tmm_mode:
/* All 3 TMM registers must be distinct. */
strcat (ins->op_out[1], "/(bad)");
}
- return;
+ return true;
}
switch (ins->vex.length)
if (reg > 0x7)
{
oappend (ins, "(bad)");
- return;
+ return true;
}
names = att_names_mask;
break;
default:
abort ();
- return;
+ return true;
}
break;
case 256:
break;
case mask_bd_mode:
case mask_mode:
- if (reg > 0x7)
+ if (reg <= 0x7)
{
- oappend (ins, "(bad)");
- return;
+ names = att_names_mask;
+ break;
}
- names = att_names_mask;
- break;
+ /* Fall through. */
default:
/* See PR binutils/20893 for a reproducer. */
oappend (ins, "(bad)");
- return;
+ return true;
}
break;
case 512:
break;
}
oappend_register (ins, names[reg]);
+ return true;
}
-static void
+static bool
OP_VexR (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod == 3)
- OP_VEX (ins, bytemode, sizeflag);
+ return OP_VEX (ins, bytemode, sizeflag);
+ return true;
}
-static void
+static bool
OP_VexW (instr_info *ins, int bytemode, int sizeflag)
{
OP_VEX (ins, bytemode, sizeflag);
ins->op_out[2] = ins->op_out[1];
ins->op_out[1] = tmp;
}
+ return true;
}
-static void
+static bool
OP_REG_VexI4 (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
int reg;
const char (*names)[8] = att_names_xmm;
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
reg = *ins->codep++;
if (bytemode != x_mode && bytemode != scalar_mode)
ins->op_out[3] = ins->op_out[2];
ins->op_out[2] = tmp;
}
+ return true;
}
-static void
+static bool
OP_VexI4 (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
oappend_immediate (ins, ins->codep[-1] & 0xf);
+ return true;
}
-static void
+static bool
VPCMP_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
if (!ins->vex.evex)
abort ();
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
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. */
/* We have a reserved extension byte. Output it directly. */
oappend_immediate (ins, cmp_type);
}
+ return true;
}
static const struct op xop_cmp_op[] =
{ STRING_COMMA_LEN ("true") }
};
-static void
+static bool
VPCOM_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
unsigned int cmp_type;
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
cmp_type = *ins->codep++ & 0xff;
if (cmp_type < ARRAY_SIZE (xop_cmp_op))
{
/* We have a reserved extension byte. Output it directly. */
oappend_immediate (ins, cmp_type);
}
+ return true;
}
static const struct op pclmul_op[] =
{ STRING_COMMA_LEN ("hqh") }
};
-static void
+static bool
PCLMUL_Fixup (instr_info *ins, int bytemode ATTRIBUTE_UNUSED,
int sizeflag ATTRIBUTE_UNUSED)
{
unsigned int pclmul_type;
- FETCH_DATA (ins->info, ins->codep + 1);
+ if (!fetch_code (ins->info, ins->codep + 1))
+ return false;
pclmul_type = *ins->codep++ & 0xff;
switch (pclmul_type)
{
/* We have a reserved extension byte. Output it directly. */
oappend_immediate (ins, pclmul_type);
}
+ return true;
}
-static void
+static bool
MOVSXD_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
/* Add proper suffix to "movsxd". */
ins->mnemonicendp = p;
*p = '\0';
- OP_E (ins, bytemode, sizeflag);
+ return OP_E (ins, bytemode, sizeflag);
}
-static void
+static bool
DistinctDest_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
unsigned int reg = ins->vex.register_specifier;
&& modrm_reg == modrm_rm))
{
oappend (ins, "(bad)");
+ return true;
}
- else
- OP_XMM (ins, bytemode, sizeflag);
+ return OP_XMM (ins, bytemode, sizeflag);
}
-static void
+static bool
OP_Rounding (instr_info *ins, int bytemode, int sizeflag ATTRIBUTE_UNUSED)
{
if (ins->modrm.mod != 3 || !ins->vex.b)
- return;
+ return true;
switch (bytemode)
{
case evex_rounding_64_mode:
if (ins->address_mode != mode_64bit || !ins->vex.w)
- return;
+ return true;
/* Fall through. */
case evex_rounding_mode:
ins->evex_used |= EVEX_b_used;
abort ();
}
oappend (ins, "sae}");
+ return true;
}
-static void
+static bool
PREFETCHI_Fixup (instr_info *ins, int bytemode, int sizeflag)
{
if (ins->modrm.mod != 0 || ins->modrm.rm != 5)
bytemode = v_mode;
}
- OP_M (ins, bytemode, sizeflag);
+ return OP_M (ins, bytemode, sizeflag);
}