Mon Jun 8 12:15:52 1998 Alan Modra <alan@spri.levels.unisa.edu.au>

* i386.h (REPNE): Rename to REPNE_PREFIX_OPCODE.
	(REPE): Rename to REPE_PREFIX_OPCODE.
	(i386_regtab_end): Remove.
	(i386_prefixtab, i386_prefixtab_end): Remove.
	(i386_optab): Use NULL as sentinel rather than "" to suit rewrite
	of md_begin.
	(MAX_OPCODE_SIZE): Define.
	(i386_optab_end): Remove.
	(sl_Suf): Define.
	(sl_FP): Use sl_Suf.

	* i386.h (i386_optab): Allow 16 bit displacement for `mov
	mem,acc'.  Combine 16 and 32 bit forms of various insns.  Allow 16
	bit form of ljmp.  Add IsPrefix modifier to prefixes.  Add addr32,
	data32, dword, and adword prefixes.
	(i386_regtab): Add BaseIndex modifier to valid 16 bit base/index
	regs.
This commit is contained in:
Ian Lance Taylor 1998-06-08 16:20:19 +00:00
parent 3f59a76366
commit 038915c98c
2 changed files with 83 additions and 96 deletions

View File

@ -1,3 +1,23 @@
Mon Jun 8 12:15:52 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
* i386.h (REPNE): Rename to REPNE_PREFIX_OPCODE.
(REPE): Rename to REPE_PREFIX_OPCODE.
(i386_regtab_end): Remove.
(i386_prefixtab, i386_prefixtab_end): Remove.
(i386_optab): Use NULL as sentinel rather than "" to suit rewrite
of md_begin.
(MAX_OPCODE_SIZE): Define.
(i386_optab_end): Remove.
(sl_Suf): Define.
(sl_FP): Use sl_Suf.
* i386.h (i386_optab): Allow 16 bit displacement for `mov
mem,acc'. Combine 16 and 32 bit forms of various insns. Allow 16
bit form of ljmp. Add IsPrefix modifier to prefixes. Add addr32,
data32, dword, and adword prefixes.
(i386_regtab): Add BaseIndex modifier to valid 16 bit base/index
regs.
Fri Jun 5 23:42:43 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
* i386.h (i386_regtab): Remove BaseIndex modifier from esp.

View File

@ -50,10 +50,11 @@ static const template i386_optab[] = {
#define bw_Suf (No_lSuf|No_sSuf)
#define bl_Suf (No_wSuf|No_sSuf)
#define wl_Suf (No_bSuf|No_sSuf)
#define sl_Suf (No_bSuf|No_wSuf)
#define bwl_Suf No_sSuf
#define FP (NoSuf|IgnoreDataSize)
#define l_FP (l_Suf|IgnoreDataSize)
#define sl_FP (No_bSuf|No_wSuf|IgnoreDataSize)
#define sl_FP (sl_Suf|IgnoreDataSize)
#if UNIXWARE_COMPAT
#define FloatDR FloatD
#else
@ -62,7 +63,7 @@ static const template i386_optab[] = {
/* move instructions */
#define MOV_AX_DISP32 0xa0
{ "mov", 2, 0xa0, X, bwl_Suf|D|W, { Disp32, Acc, 0 } },
{ "mov", 2, 0xa0, X, bwl_Suf|D|W, { Disp16|Disp32, Acc, 0 } },
{ "mov", 2, 0x88, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0 } },
{ "mov", 2, 0xb0, X, bwl_Suf|W|ShortForm, { Imm, Reg, 0 } },
{ "mov", 2, 0xc6, X, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0 } },
@ -219,8 +220,8 @@ static const template i386_optab[] = {
/* conversion insns */
/* conversion: intel naming */
{"cbw", 0, 0x98, X, NoSuf|Data16, { 0, 0, 0} },
{"cwd", 0, 0x99, X, NoSuf|Data16, { 0, 0, 0} },
{"cwde", 0, 0x98, X, NoSuf|Data32, { 0, 0, 0} },
{"cwd", 0, 0x99, X, NoSuf|Data16, { 0, 0, 0} },
{"cdq", 0, 0x99, X, NoSuf|Data32, { 0, 0, 0} },
/* att naming */
{"cbtw", 0, 0x98, X, NoSuf|Data16, { 0, 0, 0} },
@ -296,31 +297,23 @@ static const template i386_optab[] = {
{"sar", 1, 0xd0, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
/* control transfer instructions */
{"call", 1, 0xe8, X, NoSuf|JumpDword, { Disp32, 0, 0} },
{"call", 1, 0xff, 2, NoSuf|Modrm|Data32, { WordReg|WordMem|JumpAbsolute, 0, 0} },
{"callw", 1, 0xff, 2, NoSuf|Modrm|Data16, { WordReg|WordMem|JumpAbsolute, 0, 0} },
{"lcall", 2, 0x9a, X, NoSuf|JumpInterSegment, { Imm16, Imm32, 0} },
{"lcall", 1, 0xff, 3, NoSuf|Modrm|Data32, { WordMem, 0, 0} },
{"lcallw", 1, 0xff, 3, NoSuf|Modrm|Data16, { WordMem, 0, 0} },
{"call", 1, 0xe8, X, wl_Suf|JumpDword, { Disp16|Disp32, 0, 0} },
{"call", 1, 0xff, 2, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
{"lcall", 2, 0x9a, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
{"lcall", 1, 0xff, 3, wl_Suf|Modrm, { WordMem, 0, 0} },
#define JUMP_PC_RELATIVE 0xeb
{"jmp", 1, 0xeb, X, NoSuf|Jump, { Disp, 0, 0} },
{"jmp", 1, 0xff, 4, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
{"ljmp", 2, 0xea, X, NoSuf|JumpInterSegment, { Imm16, Imm32, 0} },
{"ljmp", 2, 0xea, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
{"ljmp", 1, 0xff, 5, wl_Suf|Modrm, { WordMem, 0, 0} },
{"ret", 0, 0xc3, X, l_Suf|Data32, { 0, 0, 0} },
{"ret", 1, 0xc2, X, l_Suf|Data32, { Imm16, 0, 0} },
{"retw", 0, 0xc3, X, NoSuf|Data16, { 0, 0, 0} },
{"retw", 1, 0xc2, X, NoSuf|Data16, { Imm16, 0, 0} },
{"lret", 0, 0xcb, X, l_Suf|Data32, { 0, 0, 0} },
{"lret", 1, 0xca, X, l_Suf|Data32, { Imm16, 0, 0} },
{"lretw", 0, 0xcb, X, NoSuf|Data16, { 0, 0, 0} },
{"lretw", 1, 0xca, X, NoSuf|Data16, { Imm16, 0, 0} },
{"enter", 2, 0xc8, X, l_Suf|Data32, { Imm16, Imm8, 0} },
{"leave", 0, 0xc9, X, l_Suf|Data32, { 0, 0, 0} },
{"enterw", 2, 0xc8, X, NoSuf|Data16, { Imm16, Imm8, 0} },
{"leavew", 0, 0xc9, X, NoSuf|Data16, { 0, 0, 0} },
{"ret", 0, 0xc3, X, wl_Suf, { 0, 0, 0} },
{"ret", 1, 0xc2, X, wl_Suf, { Imm16, 0, 0} },
{"lret", 0, 0xcb, X, wl_Suf, { 0, 0, 0} },
{"lret", 1, 0xca, X, wl_Suf, { Imm16, 0, 0} },
{"enter", 2, 0xc8, X, wl_Suf, { Imm16, Imm8, 0} },
{"leave", 0, 0xc9, X, wl_Suf, { 0, 0, 0} },
/* conditional jumps */
{"jo", 1, 0x70, X, NoSuf|Jump, { Disp, 0, 0} },
@ -454,15 +447,13 @@ static const template i386_optab[] = {
{"int", 1, 0xcd, X, NoSuf, { Imm8, 0, 0} },
{"int3", 0, 0xcc, X, NoSuf, { 0, 0, 0} },
{"into", 0, 0xce, X, NoSuf, { 0, 0, 0} },
{"iret", 0, 0xcf, X, l_Suf|Data32, { 0, 0, 0} },
{"iretw", 0, 0xcf, X, NoSuf|Data16, { 0, 0, 0} },
{"iret", 0, 0xcf, X, wl_Suf, { 0, 0, 0} },
/* i386sl, i486sl, later 486, and Pentium */
{"rsm", 0, 0x0faa, X, NoSuf, { 0, 0, 0} },
{"bound", 2, 0x62, X, wl_Suf|Modrm, { WordReg, WordMem, 0} },
{"hlt", 0, 0xf4, X, NoSuf, { 0, 0, 0} },
{"wait", 0, 0x9b, X, NoSuf, { 0, 0, 0} },
/* nop is actually 'xchgl %eax, %eax' */
{"nop", 0, 0x90, X, NoSuf, { 0, 0, 0} },
@ -694,17 +685,14 @@ static const template i386_optab[] = {
{"fstsw", 0, 0xdfe0, X, FP|FWait, { 0, 0, 0} },
{"fnclex", 0, 0xdbe2, X, FP, { 0, 0, 0} },
{"fclex", 0, 0xdbe2, X, FP|FWait, { 0, 0, 0} },
{"fnstenv",1, 0xd9, 6, NoSuf|Modrm|Data32, { LLongMem, 0, 0} },
{"fstenv", 1, 0xd9, 6, NoSuf|FWait|Modrm|Data32, { LLongMem, 0, 0} },
{"fldenv", 1, 0xd9, 4, NoSuf|Modrm|Data32, { LLongMem, 0, 0} },
{"fnsave", 1, 0xdd, 6, NoSuf|Modrm, { LLongMem, 0, 0} },
{"fsave", 1, 0xdd, 6, NoSuf|FWait|Modrm, { LLongMem, 0, 0} },
{"frstor", 1, 0xdd, 4, NoSuf|Modrm, { LLongMem, 0, 0} },
/* Short forms of fldenv, fstenv use data size prefix.
FIXME: Are these the right names? */
{"fnstenvs",1, 0xd9, 6, NoSuf|Modrm|Data16, { LLongMem, 0, 0} },
{"fstenvs", 1, 0xd9, 6, NoSuf|FWait|Modrm|Data16, { LLongMem, 0, 0} },
{"fldenvs", 1, 0xd9, 4, NoSuf|Modrm|Data16, { LLongMem, 0, 0} },
FIXME: Are these the right suffixes? */
{"fnstenv",1, 0xd9, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
{"fstenv", 1, 0xd9, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
{"fldenv", 1, 0xd9, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
{"fnsave", 1, 0xdd, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
{"fsave", 1, 0xdd, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
{"frstor", 1, 0xdd, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
{"ffree", 1, 0xddc0, X, FP|ShortForm, { FloatReg, 0, 0} },
/* P6:free st(i), pop st */
@ -715,24 +703,39 @@ static const template i386_optab[] = {
/*
opcode prefixes; we allow them as seperate insns too
(see prefix table below)
*/
{"aword", 0, 0x67, X, NoSuf, { 0, 0, 0} },
{"addr16", 0, 0x67, X, NoSuf, { 0, 0, 0} },
{"word", 0, 0x66, X, NoSuf, { 0, 0, 0} },
{"data16", 0, 0x66, X, NoSuf, { 0, 0, 0} },
{"lock", 0, 0xf0, X, NoSuf, { 0, 0, 0} },
{"cs", 0, 0x2e, X, NoSuf, { 0, 0, 0} },
{"ds", 0, 0x3e, X, NoSuf, { 0, 0, 0} },
{"es", 0, 0x26, X, NoSuf, { 0, 0, 0} },
{"fs", 0, 0x64, X, NoSuf, { 0, 0, 0} },
{"gs", 0, 0x65, X, NoSuf, { 0, 0, 0} },
{"ss", 0, 0x36, X, NoSuf, { 0, 0, 0} },
{"rep", 0, 0xf3, X, NoSuf, { 0, 0, 0} },
{"repe", 0, 0xf3, X, NoSuf, { 0, 0, 0} },
{"repz", 0, 0xf3, X, NoSuf, { 0, 0, 0} },
{"repne", 0, 0xf2, X, NoSuf, { 0, 0, 0} },
{"repnz", 0, 0xf2, X, NoSuf, { 0, 0, 0} },
#define ADDR_PREFIX_OPCODE 0x67
{"addr16", 0, 0x67, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"addr32", 0, 0x67, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"aword", 0, 0x67, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"adword", 0, 0x67, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define DATA_PREFIX_OPCODE 0x66
{"data16", 0, 0x66, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"data32", 0, 0x66, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"word", 0, 0x66, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"dword", 0, 0x66, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define LOCK_PREFIX_OPCODE 0xf0
{"lock", 0, 0xf0, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"wait", 0, 0x9b, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define CS_PREFIX_OPCODE 0x2e
{"cs", 0, 0x2e, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define DS_PREFIX_OPCODE 0x3e
{"ds", 0, 0x3e, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define ES_PREFIX_OPCODE 0x26
{"es", 0, 0x26, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define FS_PREFIX_OPCODE 0x64
{"fs", 0, 0x64, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define GS_PREFIX_OPCODE 0x65
{"gs", 0, 0x65, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define SS_PREFIX_OPCODE 0x36
{"ss", 0, 0x36, X, NoSuf|IsPrefix, { 0, 0, 0} },
#define REPNE_PREFIX_OPCODE 0xf2
#define REPE_PREFIX_OPCODE 0xf3
{"rep", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"repe", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"repz", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"repne", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
{"repnz", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
/* 486 extensions */
@ -848,7 +851,7 @@ static const template i386_optab[] = {
{"punpckldq",2, 0x0f62, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
{"pxor", 2, 0x0fef, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
{"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
{NULL, 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
};
#undef X
#undef ReverseModrm
@ -859,13 +862,14 @@ static const template i386_optab[] = {
#undef bw_Suf
#undef bl_Suf
#undef wl_Suf
#undef sl_Suf
#undef bwl_Suf
#undef FP
#undef l_FP
#undef sl_FP
static const template *const i386_optab_end
= i386_optab + sizeof (i386_optab)/sizeof(i386_optab[0]);
#define MAX_OPCODE_SIZE 16 /* for parsing opcodes from input */
/* 386 register table */
@ -883,11 +887,11 @@ static const reg_entry i386_regtab[] = {
{"ax", Reg16|Acc, 0},
{"cx", Reg16, 1},
{"dx", Reg16|InOutPortReg, 2},
{"bx", Reg16, 3},
{"bx", Reg16|BaseIndex, 3},
{"sp", Reg16, 4},
{"bp", Reg16, 5},
{"si", Reg16, 6},
{"di", Reg16, 7},
{"bp", Reg16|BaseIndex, 5},
{"si", Reg16|BaseIndex, 6},
{"di", Reg16|BaseIndex, 7},
/* 32 bit regs */
{"eax", Reg32|BaseIndex|Acc, 0},
{"ecx", Reg32|BaseIndex, 1},
@ -950,9 +954,6 @@ static const reg_entry i386_regtab[] = {
#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */
static const reg_entry *const i386_regtab_end
= i386_regtab + sizeof(i386_regtab)/sizeof(i386_regtab[0]);
/* segment stuff */
static const seg_entry cs = { "cs", 0x2e };
static const seg_entry ds = { "ds", 0x3e };
@ -961,38 +962,4 @@ static const seg_entry es = { "es", 0x26 };
static const seg_entry fs = { "fs", 0x64 };
static const seg_entry gs = { "gs", 0x65 };
static const prefix_entry i386_prefixtab[] = {
#define ADDR_PREFIX_OPCODE 0x67
{ "addr16", 0x67 }, /* address size prefix ==> 16bit addressing
useful when loop isns should use %cx. */
#define DATA_PREFIX_OPCODE 0x66
{ "data16", 0x66 }, /* operand size prefix */
#define LOCK_PREFIX_OPCODE 0xf0
{ "lock", 0xf0 }, /* bus lock prefix */
{ "wait", FWAIT_OPCODE }, /* wait for coprocessor, not really a prefix */
#define CS_PREFIX_OPCODE 0x2e
{ "cs", 0x2e }, /* segment overrides ... */
#define DS_PREFIX_OPCODE 0x3e
{ "ds", 0x3e },
#define ES_PREFIX_OPCODE 0x26
{ "es", 0x26 },
#define FS_PREFIX_OPCODE 0x64
{ "fs", 0x64 },
#define GS_PREFIX_OPCODE 0x65
{ "gs", 0x65 },
#define SS_PREFIX_OPCODE 0x36
{ "ss", 0x36 },
/* REPE & REPNE used to detect rep/repne with a non-string instruction */
#define REPNE 0xf2
#define REPE 0xf3
{ "rep", 0xf3 }, /* repeat string instructions */
{ "repe", 0xf3 },
{ "repz", 0xf3 },
{ "repne", 0xf2 },
{ "repnz", 0xf2 }
};
static const prefix_entry *const i386_prefixtab_end
= i386_prefixtab + sizeof(i386_prefixtab)/sizeof(i386_prefixtab[0]);
/* end of i386-opcode.h */