diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2006-03-07 20:18:06 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2006-03-07 20:18:06 +0000 |
commit | 35c52694b90bd065db54fa6034886b5a17c50353 (patch) | |
tree | fdffd8990f8b554ba2a79c508ef479c93893d49e /opcodes/i386-dis.c | |
parent | 4b1d9c58548086d46f2883b5ed780c0156e08964 (diff) | |
download | gdb-35c52694b90bd065db54fa6034886b5a17c50353.zip gdb-35c52694b90bd065db54fa6034886b5a17c50353.tar.gz gdb-35c52694b90bd065db54fa6034886b5a17c50353.tar.bz2 |
gas/testsuite/
2006-03-07 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2428
* gas/i386/i386.exp: Add rep, rep-suffix, x86-64-rep and
x86-64-rep-suffix.
* gas/i386/naked.d: Replace repz with rep.
* gas/i386/x86_64.d: Likewise.
* gas/i386/rep-suffix.d: New file.
* gas/i386/rep-suffix.s: Likewise.
* gas/i386/rep.d: Likewise.
* gas/i386/rep.s: Likewise.
* gas/i386/x86-64-rep-suffix.d: Likewise.
* gas/i386/x86-64-rep-suffix.s: Likewise.
* gas/i386/x86-64-rep.d: Likewise.
* gas/i386/x86-64-rep.s: Likewise.
opcodes/
2006-03-07 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2428
* i386-dis.c (REP_Fixup): New function.
(AL): Remove duplicate.
(Xbr): New.
(Xvr): Likewise.
(Ybr): Likewise.
(Yvr): Likewise.
(indirDXr): Likewise.
(ALr): Likewise.
(eAXr): Likewise.
(dis386): Updated entries of ins, outs, movs, lods and stos.
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r-- | opcodes/i386-dis.c | 104 |
1 files changed, 93 insertions, 11 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 06a842e..f73e883 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -101,6 +101,7 @@ static void INVLPG_Fixup (int, int); static void BadOp (void); static void SEG_Fixup (int, int); static void VMX_Fixup (int, int); +static void REP_Fixup (int, int); struct dis_private { /* Points to first byte not fetched. */ @@ -276,7 +277,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define eSI OP_IMREG, eSI_reg #define eDI OP_IMREG, eDI_reg #define AL OP_IMREG, al_reg -#define AL OP_IMREG, al_reg #define CL OP_IMREG, cl_reg #define DL OP_IMREG, dl_reg #define BL OP_IMREG, bl_reg @@ -315,6 +315,15 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define OPSUF OP_3DNowSuffix, 0 #define OPSIMD OP_SIMD_Suffix, 0 +/* Used handle "rep" prefix for string instructions. */ +#define Xbr REP_Fixup, eSI_reg +#define Xvr REP_Fixup, eSI_reg +#define Ybr REP_Fixup, eDI_reg +#define Yvr REP_Fixup, eDI_reg +#define indirDXr REP_Fixup, indir_dx_reg +#define ALr REP_Fixup, al_reg +#define eAXr REP_Fixup, eAX_reg + #define cond_jump_flag NULL, cond_jump_mode #define loop_jcxz_flag NULL, loop_jcxz_mode @@ -629,10 +638,10 @@ static const struct dis386 dis386[] = { { "imulS", Gv, Ev, Iv }, { "pushT", sIb, XX, XX }, { "imulS", Gv, Ev, sIb }, - { "ins{b||b|}", Yb, indirDX, XX }, - { "ins{R||R|}", Yv, indirDX, XX }, - { "outs{b||b|}", indirDX, Xb, XX }, - { "outs{R||R|}", indirDX, Xv, XX }, + { "ins{b||b|}", Ybr, indirDX, XX }, + { "ins{R||R|}", Yvr, indirDX, XX }, + { "outs{b||b|}", indirDXr, Xb, XX }, + { "outs{R||R|}", indirDXr, Xv, XX }, /* 70 */ { "joH", Jb, XX, cond_jump_flag }, { "jnoH", Jb, XX, cond_jump_flag }, @@ -692,17 +701,17 @@ static const struct dis386 dis386[] = { { "movS", eAX, Ov, XX }, { "movB", Ob, AL, XX }, { "movS", Ov, eAX, XX }, - { "movs{b||b|}", Yb, Xb, XX }, - { "movs{R||R|}", Yv, Xv, XX }, + { "movs{b||b|}", Ybr, Xb, XX }, + { "movs{R||R|}", Yvr, Xv, XX }, { "cmps{b||b|}", Xb, Yb, XX }, { "cmps{R||R|}", Xv, Yv, XX }, /* a8 */ { "testB", AL, Ib, XX }, { "testS", eAX, Iv, XX }, - { "stosB", Yb, AL, XX }, - { "stosS", Yv, eAX, XX }, - { "lodsB", AL, Xb, XX }, - { "lodsS", eAX, Xv, XX }, + { "stosB", Ybr, AL, XX }, + { "stosS", Yvr, eAX, XX }, + { "lodsB", ALr, Xb, XX }, + { "lodsS", eAXr, Xv, XX }, { "scasB", AL, Yb, XX }, { "scasS", eAX, Yv, XX }, /* b0 */ @@ -4777,3 +4786,76 @@ OP_VMX (int bytemode, int sizeflag) strcpy (obuf, "vmptrld"); OP_E (bytemode, sizeflag); } + +static void +REP_Fixup (int bytemode, int sizeflag) +{ + /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs, + lods and stos. */ + size_t ilen = 0; + + if (prefixes & PREFIX_REPZ) + switch (*insn_codep) + { + case 0x6e: /* outsb */ + case 0x6f: /* outsw/outsl */ + case 0xa4: /* movsb */ + case 0xa5: /* movsw/movsl/movsq */ + if (!intel_syntax) + ilen = 5; + else + ilen = 4; + break; + case 0xaa: /* stosb */ + case 0xab: /* stosw/stosl/stosq */ + case 0xac: /* lodsb */ + case 0xad: /* lodsw/lodsl/lodsq */ + if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS)) + ilen = 5; + else + ilen = 4; + break; + case 0x6c: /* insb */ + case 0x6d: /* insl/insw */ + if (!intel_syntax) + ilen = 4; + else + ilen = 3; + break; + default: + abort (); + break; + } + + if (ilen != 0) + { + size_t olen; + char *p; + + olen = strlen (obuf); + p = obuf + olen - ilen - 1 - 4; + /* Handle "repz [addr16|addr32]". */ + if ((prefixes & PREFIX_ADDR)) + p -= 1 + 6; + + memmove (p + 3, p + 4, olen - (p + 3 - obuf)); + } + + switch (bytemode) + { + case al_reg: + case eAX_reg: + case indir_dx_reg: + OP_IMREG (bytemode, sizeflag); + break; + case eDI_reg: + OP_ESreg (bytemode, sizeflag); + break; + case eSI_reg: + OP_DSreg (bytemode, sizeflag); + break; + default: + abort (); + break; + } +} |