From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wayne Scott To: gas2@cygnus.com Cc: wscott@ichips.intel.com Subject: Patches to binutils-2.6 to add support for x86 Multimedia instructions Date: Wed, 17 Apr 1996 12:39:00 -0000 Message-id: <199604171939.MAA28221@ichips.intel.com> X-SW-Source: 1996/msg00015.html The following is a set of patches to GNU binutils 2.6 that adds support for new Intel x86 instructions. This includes: Support for new x86 instructions All new Pentium Pro instructions All MMX instructions (Multimedia simd-type instructions) Patches to the x86 dissembler to correctly handle branches. (The old version forgot to sign extend branch offsets) Patches to objdump to add a --opcodes option to include the opcodes in the dissassembly output. This is extremely useful in my work. (see notes above patch) I release all of these code changes to the public domain and state that to the best of my knowledge these changes contain no information not publicly disclosed by Intel. (In the Pentium Pro users guide and the MMX developors guide. see www.intel.com) ----- Wayne Scott MD6 Architecture wscott@ichips.intel.com Work #: (503) 264-4165 Disclaimer: All views expressed are my own opinions, and not necessarily those of Intel Corporation. Index: fsf/binutils/gas/config/tc-i386.c diff -u fsf/binutils/gas/config/tc-i386.c:1.1.1.1 fsf/binutils/gas/config/tc-i386.c:1.2 --- fsf/binutils/gas/config/tc-i386.c:1.1.1.1 Thu Dec 21 20:00:50 1995 +++ fsf/binutils/gas/config/tc-i386.c Mon Feb 5 12:00:32 1996 @@ -664,6 +664,7 @@ { Reg8, "r8" }, { Reg16, "r16" }, { Reg32, "r32" }, + { RegMMX, "rMMX" }, { Imm8, "i8" }, { Imm8S, "i8s" }, { Imm16, "i16" }, Index: fsf/binutils/gas/config/tc-i386.h diff -u fsf/binutils/gas/config/tc-i386.h:1.1.1.1 fsf/binutils/gas/config/tc-i386.h:1.2 --- fsf/binutils/gas/config/tc-i386.h:1.1.1.1 Thu Dec 21 20:00:52 1995 +++ fsf/binutils/gas/config/tc-i386.h Mon Feb 5 12:00:33 1996 @@ -174,7 +174,8 @@ #define Reg8 0x1 /* 8 bit reg */ #define Reg16 0x2 /* 16 bit reg */ #define Reg32 0x4 /* 32 bit reg */ -#define Reg (Reg8|Reg16|Reg32) /* gen'l register */ +#define RegMMX 0x40000000 +#define Reg (Reg8|Reg16|Reg32|RegMMX) /* gen'l register */ #define WordReg (Reg16|Reg32) /* for push/pop operands */ /* immediate */ #define Imm8 0x8 /* 8 bit immediate */ @@ -218,6 +219,7 @@ #define Byte (Reg8|Imm8|Imm8S) #define Word (Reg16|Imm16) #define DWord (Reg32|Imm32) + #define SMALLEST_DISP_TYPE(num) \ fits_in_signed_byte(num) ? (Disp8|Disp32|Abs8|Abs32) : (Disp32|Abs32) Index: fsf/binutils/include/opcode/i386.h diff -u fsf/binutils/include/opcode/i386.h:1.1.1.1 fsf/binutils/include/opcode/i386.h:1.4 --- fsf/binutils/include/opcode/i386.h:1.1.1.1 Thu Dec 21 20:02:26 1995 +++ fsf/binutils/include/opcode/i386.h Wed Apr 17 11:38:47 1996 @@ -526,6 +526,7 @@ /* comparison (with pop) */ {"fcomp", 1, 0xd8d8, _, ShortForm, { FloatReg, 0, 0} }, +{"fcomp", 0, 0xd9d9, _, NoModrm, {0, 0, 0} }, /* alias for fcomp %st, %st(1) */ {"fcomps", 1, 0xd8, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem float */ {"ficompl", 1, 0xda, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem word */ {"fcompl", 1, 0xdc, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem double */ @@ -757,6 +758,153 @@ {"rdmsr", 0, 0x0f32, _, NoModrm, { 0, 0, 0} }, {"cmpxchg8b", 1, 0x0fc7, 1, Modrm, { Mem, 0, 0} }, +/* Pentium Pro extensions */ +{"cmovo", 2, 0x0f40, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovno", 2, 0x0f41, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovb", 2, 0x0f42, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovc", 2, 0x0f42, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovnae", 2, 0x0f42, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovnb", 2, 0x0f43, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovnc", 2, 0x0f43, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovae", 2, 0x0f43, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmove", 2, 0x0f44, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovz", 2, 0x0f44, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovne", 2, 0x0f45, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovnz", 2, 0x0f45, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovbe", 2, 0x0f46, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovna", 2, 0x0f46, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovnbe", 2, 0x0f47, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmova", 2, 0x0f47, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovs", 2, 0x0f48, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovns", 2, 0x0f49, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovp", 2, 0x0f4a, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovpe", 2, 0x0f4a, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovnp", 2, 0x0f4b, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovpo", 2, 0x0f4b, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovl", 2, 0x0f4c, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovnge", 2, 0x0f4c, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovnl", 2, 0x0f4d, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovge", 2, 0x0f4d, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovle", 2, 0x0f4e, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovng", 2, 0x0f4e, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"cmovnle", 2, 0x0f4f, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, +{"cmovg", 2, 0x0f4f, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} }, + +{"fcmovb", 2, 0xdac0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmove", 2, 0xda80, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmovbe", 2, 0xdad0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmovu", 2, 0xdad8, _, ShortForm, { FloatReg, FloatAcc, 0} }, + +{"fcmovnb", 2, 0xdbc0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmovne", 2, 0xdb80, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmovnbe", 2, 0xdbd0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcmovnu", 2, 0xdbd8, _, ShortForm, { FloatReg, FloatAcc, 0} }, + +{"fcomi", 2, 0xdbf0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fcomip", 2, 0xdff0, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fucomi", 2, 0xdbe8, _, ShortForm, { FloatReg, FloatAcc, 0} }, +{"fucomip", 2, 0xdfe8, _, ShortForm, { FloatReg, FloatAcc, 0} }, + +{"rdpmc", 0, 0x0f33, _, NoModrm, {0, 0, 0} }, + +{"ud2", 0, 0x0fff, _, NoModrm, {0, 0, 0} }, /* official undefined Instruction */ + +/* MMX extensions */ +{"emms", 0, 0x0f77, _, NoModrm, {0, 0, 0} }, + +{"movd", 2, 0x0f6e, _, Modrm|ReverseRegRegmem, { Reg32|Mem, RegMMX } }, +{"movd", 2, 0x0f7e, _, Modrm, { RegMMX, Reg32|Mem} }, + +{"movq", 2, 0x0f6f, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"movq", 2, 0x0f7f, _, Modrm, { RegMMX, RegMMX|Mem} }, + +{"packsswb", 2, 0x0f63, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"packssdw", 2, 0x0f6b, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"packuswb", 2, 0x0f67, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"paddb", 2, 0x0ffc, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"paddw", 2, 0x0ffd, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"paddd", 2, 0x0ffe, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"paddsb", 2, 0x0fec, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"paddsw", 2, 0x0fed, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"paddusb", 2, 0x0fdc, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"paddusw", 2, 0x0fdd, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pand", 2, 0x0fdb, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pandn", 2, 0x0fdf, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pcmpeqb", 2, 0x0f74, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pcmpeqw", 2, 0x0f75, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pcmpeqd", 2, 0x0f76, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pcmpgtb", 2, 0x0f64, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pcmpgtw", 2, 0x0f65, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pcmpgtd", 2, 0x0f66, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pmaddwd", 2, 0x0ff5, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pmulhw", 2, 0x0fe5, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pmullw", 2, 0x0fd5, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"por", 2, 0x0feb, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"psllw", 2, 0x0ff1, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psllw", 2, 0x0f71, 6, Modrm, { Imm8, RegMMX } }, +{"pslld", 2, 0x0ff2, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"pslld", 2, 0x0f72, 6, Modrm, { Imm8, RegMMX } }, +{"psllq", 2, 0x0ff3, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psllq", 2, 0x0f73, 6, Modrm, { Imm8, RegMMX } }, + +{"psraw", 2, 0x0fe1, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psraw", 2, 0x0f71, 4, Modrm, { Imm8, RegMMX } }, +{"psrad", 2, 0x0fe2, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psrad", 2, 0x0f72, 4, Modrm, { Imm8, RegMMX } }, + +{"psrlw", 2, 0x0fd1, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psrlw", 2, 0x0f71, 2, Modrm, { Imm8, RegMMX } }, +{"psrld", 2, 0x0fd2, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psrld", 2, 0x0f72, 2, Modrm, { Imm8, RegMMX } }, +{"psrlq", 2, 0x0fd3, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psrlq", 2, 0x0f73, 2, Modrm, { Imm8, RegMMX } }, + +{"psubb", 2, 0x0ff8, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psubw", 2, 0x0ff9, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psubd", 2, 0x0ffa, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"psubsb", 2, 0x0fe8, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psubsw", 2, 0x0fe9, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"psubusb", 2, 0x0fd8, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"psubusw", 2, 0x0fd9, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"punpckhbw", 2, 0x0f68, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"punpckhwd", 2, 0x0f69, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"punpckhdq", 2, 0x0f6a, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"punpcklbw", 2, 0x0f60, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"punpcklwd", 2, 0x0f61, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, +{"punpckldq", 2, 0x0f62, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + +{"pxor", 2, 0x0fef, _, Modrm|ReverseRegRegmem, { RegMMX|Mem, RegMMX } }, + {"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */ }; #undef _ @@ -795,7 +943,16 @@ {"st", FloatReg|FloatAcc, 0}, {"st(1)", FloatReg, 1}, {"st(2)", FloatReg, 2}, {"st(3)", FloatReg, 3}, {"st(4)", FloatReg, 4}, {"st(5)", FloatReg, 5}, - {"st(6)", FloatReg, 6}, {"st(7)", FloatReg, 7} + {"st(6)", FloatReg, 6}, {"st(7)", FloatReg, 7}, + {"mm0", RegMMX, 0}, + {"mm1", RegMMX, 1}, + {"mm2", RegMMX, 2}, + {"mm3", RegMMX, 3}, + {"mm4", RegMMX, 4}, + {"mm5", RegMMX, 5}, + {"mm6", RegMMX, 6}, + {"mm7", RegMMX, 7} + }; #define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */ Index: fsf/binutils/opcodes/i386-dis.c diff -u fsf/binutils/opcodes/i386-dis.c:1.1.1.1 fsf/binutils/opcodes/i386-dis.c:1.4 --- fsf/binutils/opcodes/i386-dis.c:1.1.1.1 Thu Dec 21 20:02:49 1995 +++ fsf/binutils/opcodes/i386-dis.c Wed Apr 17 11:40:36 1996 @@ -78,6 +78,9 @@ return 1; } +#define Em OP_E, m_mode +#define Gm OP_G, m_mode + #define Eb OP_E, b_mode #define indirEb OP_indirE, b_mode #define Gb OP_G, b_mode @@ -151,6 +154,7 @@ #define v_mode 2 #define w_mode 3 #define d_mode 4 +#define m_mode 5 #define es_reg 100 #define cs_reg 101 @@ -206,6 +210,9 @@ #define GRP7 NULL, NULL, 14 #define GRP8 NULL, NULL, 15 #define GRP9 NULL, NULL, 16 +#define GRP10_71 NULL, NULL, 17 +#define GRP10_72 NULL, NULL, 18 +#define GRP10_73 NULL, NULL, 19 #define FLOATCODE 50 #define FLOAT NULL, NULL, FLOATCODE @@ -546,17 +553,29 @@ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 30 */ - { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "(bad)" }, + { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 38 */ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 40 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "cmovoS", Gv, Ev }, + { "cmovno", Gv, Ev }, + { "cmovb", Gv, Ev }, + { "cmovae", Gv, Ev }, + { "cmove", Gv, Ev }, + { "cmovne", Gv, Ev }, + { "cmovbe", Gv, Ev }, + { "cmova", Gv, Ev }, /* 48 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "cmovs", Gv, Ev }, + { "cmovns", Gv, Ev }, + { "cmovp", Gv, Ev }, + { "cmovnp", Gv, Ev }, + { "cmovl", Gv, Ev }, + { "cmovnl", Gv, Ev }, + { "cmovle", Gv, Ev }, + { "cmovg", Gv, Ev }, /* 50 */ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, @@ -564,17 +583,41 @@ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 60 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "punpcklbw", Gm, Em }, + { "punpcklwd", Gm, Em }, + { "punpckldq", Gm, Em }, + { "packsswb", Gm, Em }, + { "pcmpgtb", Gm, Em }, + { "pcmpgtw", Gm, Em }, + { "pcmpgtd", Gm, Em }, + { "packuswb", Gm, Em }, /* 68 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "punpckhbw", Gm, Em }, + { "punpckhwd", Gm, Em }, + { "punpckhdq", Gm, Em }, + { "packssdw", Gm, Em }, + { "(bad)" }, + { "(bad)" }, + { "movd", Gm, Ev }, + { "movq", Gm, Em }, /* 70 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { GRP10_71 }, + { GRP10_72 }, + { GRP10_73 }, + { "pcmpeqb", Gm, Em }, + { "pcmpeqw", Gm, Em }, + { "pcmpeqd", Gm, Em }, + { "emms" }, /* 78 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "movd", Ev, Gm }, + { "movq", Em, Gm }, /* 80 */ { "jo", Jv }, { "jno", Jv }, @@ -666,23 +709,59 @@ { "bswap", eSI }, { "bswap", eDI }, /* d0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psrlw", Gm, Em }, + { "psrld", Gm, Em }, + { "psrlq", Gm, Em }, + { "(bad)" }, + { "pmullw", Gm, Em }, + { "(bad)" }, + { "(bad)" }, /* d8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubusb", Gm, Em }, + { "psubusw", Gm, Em }, + { "(bad)" }, + { "pand", Gm, Em }, + { "paddusb", Gm, Em }, + { "paddusw", Gm, Em }, + { "(bad)" }, + { "pandn", Gm, Em }, /* e0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psraw", Gm, Em }, + { "psrad", Gm, Em }, + { "(bad)" }, + { "(bad)" }, + { "pmulhw", Gm, Em }, + { "(bad)" }, + { "(bad)" }, /* e8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubsb", Gm, Em }, + { "psubsw", Gm, Em }, + { "(bad)" }, + { "por", Gm, Em }, + { "paddsb", Gm, Em }, + { "paddsw", Gm, Em }, + { "(bad)" }, + { "pxor", Gm, Em}, /* f0 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "psllw", Gm, Em }, + { "pslld", Gm, Em }, + { "psllq", Gm, Em }, + { "(bad)" }, + { "pmaddwd", Gm, Em }, + { "(bad)" }, + { "(bad)" }, /* f8 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "psubb", Gm, Em }, + { "psubw", Gm, Em }, + { "psubq", Gm, Em }, + { "(bad)" }, + { "paddb", Gm, Em }, + { "paddw", Gm, Em }, + { "paddd", Gm, Em }, + { "ud2" }, }; static char obuf[100]; @@ -696,6 +775,9 @@ static int reg; static void oappend (); +static char *namesmm[]={ + "%mm0","%mm1","%mm2","%mm3", "%mm4","%mm5","%mm6","%mm7", +}; static char *names32[]={ "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", }; @@ -896,6 +978,39 @@ { "(bad)" }, { "(bad)" }, { "(bad)" }, + }, + /* GRP10_71 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrlw", Em, Ib }, + { "(bad)" }, + { "psraw", Em, Ib }, + { "(bad)" }, + { "psllw", Em, Ib }, + { "(bad)" }, + }, + /* GRP10_72 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrld", Em, Ib }, + { "(bad)" }, + { "psrad", Em, Ib }, + { "(bad)" }, + { "pslld", Em, Ib }, + { "(bad)" }, + }, + /* GRP10_73 */ + { + { "(bad)" }, + { "(bad)" }, + { "psrlq", Em, Ib }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "psllq", Em, Ib }, + { "(bad)" }, } }; @@ -1270,10 +1385,10 @@ }, /* da */ { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, + { "fcmovb", STi, ST }, + { "fcmove", STi, ST }, + { "fcmovbe", STi, ST }, + { "fcmovu", STi, ST }, { "(bad)" }, { FGRPda_5 }, { "(bad)" }, @@ -1281,13 +1396,13 @@ }, /* db */ { - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, + { "fcmovnb", STi, ST }, + { "fcmovne", STi, ST }, + { "fcmovnbe", STi, ST }, + { "fcmovnu", STi, ST }, { FGRPdb_4 }, - { "(bad)" }, - { "(bad)" }, + { "fucomi", STi, ST }, + { "fcomi", STi, ST }, { "(bad)" }, }, /* dc */ @@ -1330,8 +1445,8 @@ { "(bad)" }, { "(bad)" }, { FGRPdf_4 }, - { "(bad)" }, - { "(bad)" }, + { "fucomip", STi, ST }, + { "fcomip", STi, ST }, { "(bad)" }, }, }; @@ -1547,6 +1662,9 @@ else oappend (names16[rm]); break; + case m_mode: + oappend (namesmm[rm]); + break; default: oappend (""); break; @@ -1653,6 +1771,9 @@ else oappend (names16[reg]); break; + case m_mode: + oappend (namesmm[reg]); + break; default: oappend (""); break; @@ -1800,6 +1921,11 @@ case b_mode: FETCH_DATA (the_info, codep + 1); disp = *(char *)codep++; + + /* sign extend number */ + if (disp >= 1<<7) { + disp -= 1<<8; + } break; case v_mode: if (dflag) @@ -1807,6 +1933,10 @@ else { disp = (short)get16 (); + /* sign extend number */ + if (disp >= 1<<15) { + disp -= 1<<16; + } /* for some reason, a data16 prefix on a jump instruction means that the pc is masked to 16 bits after the displacement is added! */ ---------- This is the one patch that is not as clean as the others. The goal is to include opcodes in the disassembly output when requested by the user. In order to ouput the opcodes you need to know the length of the current instruction. The only way to do this is to call the disassembler. The problem is that the disassembler prints its output as it is working, making is very difficult to print the opcodes BEFORE the disassembly. To work around this problem I call the disassembly routine twice and the first time I send the output to a file handle that writes to /dev/null. I should have put these comments in the patch itself. Please add it to final file. Opcode are very important to me and I have heard many other requests for it. Please try to include this portion or fix the disassembly routines so the /dev/null hack is not needed. ---------- Index: fsf/binutils/binutils/objdump.c diff -u fsf/binutils/binutils/objdump.c:1.1.1.1 fsf/binutils/binutils/objdump.c:1.4 --- fsf/binutils/binutils/objdump.c:1.1.1.1 Thu Dec 21 19:59:23 1995 +++ fsf/binutils/binutils/objdump.c Tue Feb 27 13:17:13 1996 @@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "bfd.h" #include "getopt.h" #include "progress.h" @@ -53,6 +54,7 @@ int dump_stab_section_info; /* --stabs */ boolean disassemble; /* -d */ boolean disassemble_all; /* -D */ +boolean disassemble_opcodes; /* -o */ boolean formats_info; /* -i */ char *only; /* -j secname */ int wide_output; /* -w */ @@ -125,8 +127,8 @@ int status; { fprintf (stream, "\ -Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\ - [--archive-headers] [--target=bfdname] [--disassemble]\n\ +Usage: %s [-ahifdDoprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\ + [--archive-headers] [--target=bfdname] [--disassemble] [--opcodes]\n\ [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\ [--info] [--section=section-name] [--line-numbers] [--source]\n", program_name); @@ -161,6 +163,7 @@ {"help", no_argument, NULL, 'H'}, {"info", no_argument, NULL, 'i'}, {"line-numbers", no_argument, NULL, 'l'}, + {"opcodes", no_argument, NULL, 'o'}, {"reloc", no_argument, NULL, 'r'}, {"section", required_argument, NULL, 'j'}, {"section-headers", no_argument, NULL, 'h'}, @@ -803,6 +806,9 @@ struct objdump_disasm_info aux; asection *section; boolean done_dot = false; + FILE *null_fp; + + null_fp = fopen("/dev/null", "w"); print_files = NULL; prev_functionname = NULL; @@ -945,10 +951,41 @@ aux.require_sec = false; putchar (' '); + if (disassemble_opcodes) { + FILE *old_stream; + int j; + + old_stream = disasm_info.stream; + + disasm_info.stream = null_fp; + + bytes = (*disassemble_fn) (section->vma + i, &disasm_info); + + disasm_info.stream = old_stream; + + for (j=0; j < 16; j++) { + if (j == 8) { + if (bytes > 8) { + printf("\n%29s", ""); + } else { + break; + } + } + + if (j < bytes) { + printf("%02x ", (unsigned)data[i+j]); + } else { + printf(" "); + } + } + } bytes = (*disassemble_fn) (section->vma + i, &disasm_info); if (bytes < 0) break; + + + if (!wide_output) putchar ('\n'); else @@ -1843,7 +1880,7 @@ bfd_init (); - while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:w", long_options, + while ((c = getopt_long (argc, argv, "pib:m:VdDlofahrRtTxsSj:w", long_options, (int *) 0)) != EOF) { @@ -1894,6 +1931,8 @@ case 'D': disassemble = disassemble_all = true; break; + case 'o': + disassemble = disassemble_opcodes = true; case 'S': disassemble = true; with_source_code = true;