diff options
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r-- | opcodes/i386-dis.c | 162 |
1 files changed, 104 insertions, 58 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 40f10ac..72e39a1 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -2362,6 +2362,44 @@ 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" +}; +static const char *att_names_mm[] = { + "%mm0", "%mm1", "%mm2", "%mm3", + "%mm4", "%mm5", "%mm6", "%mm7" +}; + +static const char **names_xmm; +static const char *intel_names_xmm[] = { + "xmm0", "xmm1", "xmm2", "xmm3", + "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", + "xmm12", "xmm13", "xmm14", "xmm15" +}; +static const char *att_names_xmm[] = { + "%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7", + "%xmm8", "%xmm9", "%xmm10", "%xmm11", + "%xmm12", "%xmm13", "%xmm14", "%xmm15" +}; + +static const char **names_ymm; +static const char *intel_names_ymm[] = { + "ymm0", "ymm1", "ymm2", "ymm3", + "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", + "ymm12", "ymm13", "ymm14", "ymm15" +}; +static const char *att_names_ymm[] = { + "%ymm0", "%ymm1", "%ymm2", "%ymm3", + "%ymm4", "%ymm5", "%ymm6", "%ymm7", + "%ymm8", "%ymm9", "%ymm10", "%ymm11", + "%ymm12", "%ymm13", "%ymm14", "%ymm15" +}; + static const struct dis386 reg_table[][8] = { /* REG_80 */ { @@ -12126,6 +12164,9 @@ print_insn (bfd_vma pc, disassemble_info *info) names8 = intel_names8; names8rex = intel_names8rex; names_seg = intel_names_seg; + names_mm = intel_names_mm; + names_xmm = intel_names_xmm; + names_ymm = intel_names_ymm; index64 = intel_index64; index32 = intel_index32; index16 = intel_index16; @@ -12142,6 +12183,9 @@ print_insn (bfd_vma pc, disassemble_info *info) names8 = att_names8; names8rex = att_names8rex; names_seg = att_names_seg; + names_mm = att_names_mm; + names_xmm = att_names_xmm; + names_ymm = att_names_ymm; index64 = att_index64; index32 = att_index32; index16 = att_index16; @@ -14625,53 +14669,56 @@ OP_R (int bytemode, int sizeflag) static void OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { + int reg = modrm.reg; + const char **names; + used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) { - int add; + names = names_xmm; USED_REX (REX_R); if (rex & REX_R) - add = 8; - else - add = 0; - sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); + reg += 8; } else - sprintf (scratchbuf, "%%mm%d", modrm.reg); - oappend (scratchbuf + intel_syntax); + names = names_mm; + oappend (names[reg]); } static void OP_XMM (int bytemode, int sizeflag ATTRIBUTE_UNUSED) { - int add; + int reg = modrm.reg; + const char **names; + USED_REX (REX_R); if (rex & REX_R) - add = 8; - else - add = 0; + reg += 8; if (need_vex && bytemode != xmm_mode) { switch (vex.length) { case 128: - sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); + names = names_xmm; break; case 256: - sprintf (scratchbuf, "%%ymm%d", modrm.reg + add); + names = names_ymm; break; default: abort (); } } else - sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); - oappend (scratchbuf + intel_syntax); + names = names_xmm; + oappend (names[reg]); } static void OP_EM (int bytemode, int sizeflag) { + int reg; + const char **names; + if (modrm.mod != 3) { if (intel_syntax @@ -14691,20 +14738,17 @@ OP_EM (int bytemode, int sizeflag) MODRM_CHECK; codep++; used_prefixes |= (prefixes & PREFIX_DATA); + reg = modrm.rm; if (prefixes & PREFIX_DATA) { - int add; - + names = names_xmm; USED_REX (REX_B); if (rex & REX_B) - add = 8; - else - add = 0; - sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); + reg += 8; } else - sprintf (scratchbuf, "%%mm%d", modrm.rm); - oappend (scratchbuf + intel_syntax); + names = names_mm; + oappend (names[reg]); } /* cvt* are the only instructions in sse2 which have @@ -14730,22 +14774,21 @@ OP_EMC (int bytemode, int sizeflag) MODRM_CHECK; codep++; used_prefixes |= (prefixes & PREFIX_DATA); - sprintf (scratchbuf, "%%mm%d", modrm.rm); - oappend (scratchbuf + intel_syntax); + oappend (names_mm[modrm.rm]); } static void OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { used_prefixes |= (prefixes & PREFIX_DATA); - sprintf (scratchbuf, "%%mm%d", modrm.reg); - oappend (scratchbuf + intel_syntax); + oappend (names_mm[modrm.reg]); } static void OP_EX (int bytemode, int sizeflag) { - int add; + int reg; + const char **names; /* Skip mod/rm byte. */ MODRM_CHECK; @@ -14757,11 +14800,10 @@ OP_EX (int bytemode, int sizeflag) return; } + reg = modrm.rm; USED_REX (REX_B); if (rex & REX_B) - add = 8; - else - add = 0; + reg += 8; if ((sizeflag & SUFFIX_ALWAYS) && (bytemode == x_swap_mode @@ -14776,18 +14818,18 @@ OP_EX (int bytemode, int sizeflag) switch (vex.length) { case 128: - sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); + names = names_xmm; break; case 256: - sprintf (scratchbuf, "%%ymm%d", modrm.rm + add); + names = names_ymm; break; default: abort (); } } else - sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); - oappend (scratchbuf + intel_syntax); + names = names_xmm; + oappend (names[reg]); } static void @@ -15086,23 +15128,25 @@ CMPXCHG8B_Fixup (int bytemode, int sizeflag) static void XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED) { + const char **names; + if (need_vex) { switch (vex.length) { case 128: - sprintf (scratchbuf, "%%xmm%d", reg); + names = names_xmm; break; case 256: - sprintf (scratchbuf, "%%ymm%d", reg); + names = names_ymm; break; default: abort (); } } else - sprintf (scratchbuf, "%%xmm%d", reg); - oappend (scratchbuf + intel_syntax); + names = names_xmm; + oappend (names[reg]); } static void @@ -15198,6 +15242,8 @@ FXSAVE_Fixup (int bytemode, int sizeflag) static void OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED) { + const char **names; + if (!need_vex) abort (); @@ -15217,7 +15263,7 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED) return; } - sprintf (scratchbuf, "%%xmm%d", vex.register_specifier); + names = names_xmm; break; case 256: switch (bytemode) @@ -15230,13 +15276,13 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED) return; } - sprintf (scratchbuf, "%%ymm%d", vex.register_specifier); + names = names_ymm; break; default: abort (); break; } - oappend (scratchbuf + intel_syntax); + oappend (names[vex.register_specifier]); } /* Get the VEX immediate byte without moving codep. */ @@ -15331,6 +15377,8 @@ get_vex_imm8 (int sizeflag, int opnum) static void OP_EX_VexReg (int bytemode, int sizeflag, int reg) { + const char **names; + if (reg == -1 && modrm.mod != 3) { OP_E_memory (bytemode, sizeflag); @@ -15352,15 +15400,15 @@ OP_EX_VexReg (int bytemode, int sizeflag, int reg) switch (vex.length) { case 128: - sprintf (scratchbuf, "%%xmm%d", reg); + names = names_xmm; break; case 256: - sprintf (scratchbuf, "%%ymm%d", reg); + names = names_ymm; break; default: abort (); } - oappend (scratchbuf + intel_syntax); + oappend (names[reg]); } static void @@ -15368,9 +15416,11 @@ OP_Vex_2src (int bytemode, int sizeflag) { if (modrm.mod == 3) { + int reg = modrm.rm; USED_REX (REX_B); - sprintf (scratchbuf, "%%xmm%d", rex & REX_B ? modrm.rm + 8 : modrm.rm); - oappend (scratchbuf + intel_syntax); + if (rex & REX_B) + reg += 8; + oappend (names_xmm[reg]); } else { @@ -15395,10 +15445,7 @@ OP_Vex_2src_1 (int bytemode, int sizeflag) } if (vex.w) - { - sprintf (scratchbuf, "%%xmm%d", vex.register_specifier); - oappend (scratchbuf + intel_syntax); - } + oappend (names_xmm[vex.register_specifier]); else OP_Vex_2src (bytemode, sizeflag); } @@ -15409,10 +15456,7 @@ OP_Vex_2src_2 (int bytemode, int sizeflag) if (vex.w) OP_Vex_2src (bytemode, sizeflag); else - { - sprintf (scratchbuf, "%%xmm%d", vex.register_specifier); - oappend (scratchbuf + intel_syntax); - } + oappend (names_xmm[vex.register_specifier]); } static void @@ -15454,6 +15498,8 @@ static void OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED) { int reg; + const char **names; + FETCH_DATA (the_info, codep + 1); reg = *codep++; @@ -15470,15 +15516,15 @@ OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED) switch (vex.length) { case 128: - sprintf (scratchbuf, "%%xmm%d", reg); + names = names_xmm; break; case 256: - sprintf (scratchbuf, "%%ymm%d", reg); + names = names_ymm; break; default: abort (); } - oappend (scratchbuf + intel_syntax); + oappend (names[reg]); } static void |