From a43022bd720336020cb7b8454504276fe9615b82 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Mon, 6 Feb 1995 08:38:27 +0000 Subject: [PATCH] i386 16-bit mode support from bryan ford --- include/opcode/ChangeLog | 21 ++++++++++ include/opcode/i386.h | 91 ++++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index ca420252478..a05e50630e5 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,24 @@ +Mon Feb 6 03:31:54 1995 Ken Raeburn + + Changes from Bryan Ford for 16-bit + i386 support: + * i386.h (MOV_AX_DISP32): New macro. + (i386_optab): Added Data16 and Data32 as needed. Added "w" forms + of several call/return instructions. + (ADDR_PREFIX_OPCODE): New macro. + +Mon Jan 23 16:45:43 1995 Ken Raeburn + + Sat Jan 21 17:50:38 1995 Pat Rankin (rankin@eql.caltech.edu) + + * ../include/opcode/vax.h (struct vot_wot, field `args'): make + it pointer to const char; + (struct vot, field `name'): ditto. + +Thu Jan 19 14:47:53 1995 Ken Raeburn + + * vax.h: Supply and properly group all values in end sentinel. + Tue Jan 17 10:55:30 1995 Ian Lance Taylor * mips.h (INSN_ISA, INSN_4650): Define. diff --git a/include/opcode/i386.h b/include/opcode/i386.h index 16f3528cb8b..e902a2b0cdc 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -21,6 +21,7 @@ static const template i386_optab[] = { #define _ None /* move instructions */ +#define MOV_AX_DISP32 0xa0 { "mov", 2, 0xa0, _, DW|NoModrm, { Disp32, Acc, 0 } }, { "mov", 2, 0x88, _, DW|Modrm, { Reg, Reg|Mem, 0 } }, { "mov", 2, 0xb0, _, ShortFormW, { Imm, Reg, 0 } }, @@ -36,8 +37,8 @@ static const template i386_optab[] = { conflict with the "movs" string move instruction. Thus, {"movsb", 2, 0x0fbe, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16|Reg32, 0} }, is not kosher; we must seperate the two instructions. */ -{"movsbl", 2, 0x0fbe, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg32, 0} }, -{"movsbw", 2, 0x660fbe, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16, 0} }, +{"movsbl", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data32, { Reg8|Mem, Reg32, 0} }, +{"movsbw", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data16, { Reg8|Mem, Reg16, 0} }, {"movswl", 2, 0x0fbf, _, ReverseRegRegmem|Modrm, { Reg16|Mem, Reg32, 0} }, /* move with zero extend */ @@ -48,7 +49,7 @@ static const template i386_optab[] = { {"push", 1, 0x50, _, ShortForm, { WordReg,0,0 } }, {"push", 1, 0xff, 0x6, Modrm, { WordReg|WordMem, 0, 0 } }, {"push", 1, 0x6a, _, NoModrm, { Imm8S, 0, 0} }, -{"push", 1, 0x68, _, NoModrm, { Imm32, 0, 0} }, +{"push", 1, 0x68, _, NoModrm, { Imm16|Imm32, 0, 0} }, {"push", 1, 0x06, _, Seg2ShortForm, { SReg2,0,0 } }, {"push", 1, 0x0fa0, _, Seg3ShortForm, { SReg3,0,0 } }, /* push all */ @@ -80,17 +81,6 @@ static const template i386_optab[] = { {"out", 1, 0xe6, _, W|NoModrm, { Imm8, 0, 0 } }, {"out", 1, 0xee, _, W|NoModrm, { InOutPortReg, 0, 0 } }, -#if 0 -{"inb", 1, 0xe4, _, NoModrm, { Imm8, 0, 0 } }, -{"inb", 1, 0xec, _, NoModrm, { WordMem, 0, 0 } }, -{"inw", 1, 0x66e5, _, NoModrm, { Imm8, 0, 0 } }, -{"inw", 1, 0x66ed, _, NoModrm, { WordMem, 0, 0 } }, -{"outb", 1, 0xe6, _, NoModrm, { Imm8, 0, 0 } }, -{"outb", 1, 0xee, _, NoModrm, { WordMem, 0, 0 } }, -{"outw", 1, 0x66e7, _, NoModrm, { Imm8, 0, 0 } }, -{"outw", 1, 0x66ef, _, NoModrm, { WordMem, 0, 0 } }, -#endif - /* load effective address */ {"lea", 2, 0x8d, _, Modrm, { WordMem, WordReg, 0 } }, @@ -109,8 +99,10 @@ static const template i386_optab[] = { {"cmc", 0, 0xf5, _, NoModrm, { 0, 0, 0} }, {"lahf", 0, 0x9f, _, NoModrm, { 0, 0, 0} }, {"sahf", 0, 0x9e, _, NoModrm, { 0, 0, 0} }, -{"pushf", 0, 0x9c, _, NoModrm, { 0, 0, 0} }, -{"popf", 0, 0x9d, _, NoModrm, { 0, 0, 0} }, +{"pushf", 0, 0x9c, _, NoModrm|Data32, { 0, 0, 0} }, +{"popf", 0, 0x9d, _, NoModrm|Data32, { 0, 0, 0} }, +{"pushfw", 0, 0x9c, _, NoModrm|Data16, { 0, 0, 0} }, +{"popfw", 0, 0x9d, _, NoModrm|Data16, { 0, 0, 0} }, {"stc", 0, 0xf9, _, NoModrm, { 0, 0, 0} }, {"std", 0, 0xfd, _, NoModrm, { 0, 0, 0} }, {"sti", 0, 0xfb, _, NoModrm, { 0, 0, 0} }, @@ -178,20 +170,20 @@ static const template i386_optab[] = { /* conversion insns */ /* conversion: intel naming */ -{"cbw", 0, 0x6698, _, NoModrm, { 0, 0, 0} }, -{"cwd", 0, 0x6699, _, NoModrm, { 0, 0, 0} }, -{"cwde", 0, 0x98, _, NoModrm, { 0, 0, 0} }, -{"cdq", 0, 0x99, _, NoModrm, { 0, 0, 0} }, +{"cbw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} }, +{"cwd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} }, +{"cwde", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} }, +{"cdq", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} }, /* att naming */ -{"cbtw", 0, 0x6698, _, NoModrm, { 0, 0, 0} }, -{"cwtl", 0, 0x98, _, NoModrm, { 0, 0, 0} }, -{"cwtd", 0, 0x6699, _, NoModrm, { 0, 0, 0} }, -{"cltd", 0, 0x99, _, NoModrm, { 0, 0, 0} }, +{"cbtw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} }, +{"cwtl", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} }, +{"cwtd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} }, +{"cltd", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} }, /* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are expanding 64-bit multiplies, and *cannot* be selected to accomplish 'imul %ebx, %eax' (opcode 0x0faf must be used in this case) - These multiplies can only be selected with single opearnd forms. */ + These multiplies can only be selected with single operand forms. */ {"mul", 1, 0xf6, 4, W|Modrm, { Reg|Mem, 0, 0} }, {"imul", 1, 0xf6, 5, W|Modrm, { Reg|Mem, 0, 0} }, @@ -266,22 +258,28 @@ static const template i386_optab[] = { /* control transfer instructions */ #define CALL_PC_RELATIVE 0xe8 {"call", 1, 0xe8, _, JumpDword, { Disp32, 0, 0} }, -{"call", 1, 0xff, 2, Modrm, { Reg|Mem|JumpAbsolute, 0, 0} }, +{"call", 1, 0xff, 2, Modrm|Data32, { Reg|Mem|JumpAbsolute, 0, 0} }, +{"callw", 1, 0xff, 2, Modrm|Data16, { Reg|Mem|JumpAbsolute, 0, 0} }, #define CALL_FAR_IMMEDIATE 0x9a {"lcall", 2, 0x9a, _, JumpInterSegment, { Imm16, Abs32|Imm32, 0} }, -{"lcall", 1, 0xff, 3, Modrm, { Mem, 0, 0} }, +{"lcall", 1, 0xff, 3, Modrm|Data32, { Mem, 0, 0} }, +{"lcallw", 1, 0xff, 3, Modrm|Data16, { Mem, 0, 0} }, #define JUMP_PC_RELATIVE 0xeb {"jmp", 1, 0xeb, _, Jump, { Disp, 0, 0} }, {"jmp", 1, 0xff, 4, Modrm, { Reg32|Mem|JumpAbsolute, 0, 0} }, #define JUMP_FAR_IMMEDIATE 0xea {"ljmp", 2, 0xea, _, JumpInterSegment, { Imm16, Imm32, 0} }, -{"ljmp", 1, 0xff, 5, Modrm, { Mem, 0, 0} }, - -{"ret", 0, 0xc3, _, NoModrm, { 0, 0, 0} }, -{"ret", 1, 0xc2, _, NoModrm, { Imm16, 0, 0} }, -{"lret", 0, 0xcb, _, NoModrm, { 0, 0, 0} }, -{"lret", 1, 0xca, _, NoModrm, { Imm16, 0, 0} }, +{"ljmp", 1, 0xff, 5, Modrm|Data32, { Mem, 0, 0} }, + +{"ret", 0, 0xc3, _, NoModrm|Data32, { 0, 0, 0} }, +{"ret", 1, 0xc2, _, NoModrm|Data32, { Imm16, 0, 0} }, +{"retw", 0, 0xc3, _, NoModrm|Data16, { 0, 0, 0} }, +{"retw", 1, 0xc2, _, NoModrm|Data16, { Imm16, 0, 0} }, +{"lret", 0, 0xcb, _, NoModrm|Data32, { 0, 0, 0} }, +{"lret", 1, 0xca, _, NoModrm|Data32, { Imm16, 0, 0} }, +{"lretw", 0, 0xcb, _, NoModrm|Data16, { 0, 0, 0} }, +{"lretw", 1, 0xca, _, NoModrm|Data16, { Imm16, 0, 0} }, {"enter", 2, 0xc8, _, NoModrm, { Imm16, Imm8, 0} }, {"leave", 0, 0xc9, _, NoModrm, { 0, 0, 0} }, @@ -332,14 +330,19 @@ static const template i386_optab[] = { {"jnle", 1, 0x7f, _, Jump, { Disp, 0, 0} }, {"jg", 1, 0x7f, _, Jump, { Disp, 0, 0} }, +#if 0 /* XXX where are these macros used? + To get them working again, they need to take + an entire template as the parameter, + and check for Data16/Data32 flags. */ /* these turn into pseudo operations when disp is larger than 8 bits */ #define IS_JUMP_ON_CX_ZERO(o) \ - (o == 0x67e3) + (o == 0x66e3) #define IS_JUMP_ON_ECX_ZERO(o) \ (o == 0xe3) +#endif -{"jcxz", 1, 0x67e3, _, JumpByte, { Disp, 0, 0} }, -{"jecxz", 1, 0xe3, _, JumpByte, { Disp, 0, 0} }, +{"jcxz", 1, 0xe3, _, JumpByte|Data16, { Disp, 0, 0} }, +{"jecxz", 1, 0xe3, _, JumpByte|Data32, { Disp, 0, 0} }, #define IS_LOOP_ECX_TIMES(o) \ (o == 0xe2 || o == 0xe1 || o == 0xe0) @@ -432,16 +435,20 @@ static const template i386_optab[] = { {"bts", 2, 0x0fba, 5, Modrm, { Imm8, Reg|Mem, 0} }, /* interrupts & op. sys insns */ -/* See i386.c for conversion of 'int $3' into the special int 3 insn. */ +/* See gas/config/tc-i386.c for conversion of 'int $3' into the special + int 3 insn. */ #define INT_OPCODE 0xcd #define INT3_OPCODE 0xcc {"int", 1, 0xcd, _, NoModrm, { Imm8, 0, 0} }, {"int3", 0, 0xcc, _, NoModrm, { 0, 0, 0} }, {"into", 0, 0xce, _, NoModrm, { 0, 0, 0} }, -{"iret", 0, 0xcf, _, NoModrm, { 0, 0, 0} }, +{"iret", 0, 0xcf, _, NoModrm|Data32, { 0, 0, 0} }, +{"iretw", 0, 0xcf, _, NoModrm|Data16, { 0, 0, 0} }, +/* i386sl (and i486sl?) only */ +{"rsm", 0, 0x0faa, _, NoModrm,{ 0, 0, 0} }, -{"boundl", 2, 0x62, _, Modrm, { Reg32, Mem, 0} }, -{"boundw", 2, 0x6662, _, Modrm, { Reg16, Mem, 0} }, +{"boundl", 2, 0x62, _, Modrm|Data32, { Reg32, Mem, 0} }, +{"boundw", 2, 0x62, _, Modrm|Data16, { Reg16, Mem, 0} }, {"hlt", 0, 0xf4, _, NoModrm, { 0, 0, 0} }, {"wait", 0, 0x9b, _, NoModrm, { 0, 0, 0} }, @@ -503,6 +510,7 @@ static const template i386_optab[] = { /* exchange %st with %st0 */ {"fxch", 1, 0xd9c8, _, ShortForm, { FloatReg, 0, 0} }, +{"fxch", 0, 0xd9c9, _, NoModrm, { 0, 0, 0} }, /* alias for fxch %st, %st(1) */ /* comparison (without pop) */ {"fcom", 1, 0xd8d0, _, ShortForm, { FloatReg, 0, 0} }, @@ -736,7 +744,7 @@ static const template i386_optab[] = { {"wbinvd", 0, 0x0f09, _, NoModrm, { 0, 0, 0} }, {"invlpg", 1, 0x0f01, 7, Modrm, { Mem, 0, 0} }, -{"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinal */ +{"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */ }; #undef _ @@ -815,6 +823,7 @@ static const seg_entry *const two_byte_segment_defaults[] = { }; static const prefix_entry i386_prefixtab[] = { +#define ADDR_PREFIX_OPCODE 0x67 { "addr16", 0x67 }, /* address size prefix ==> 16bit addressing * (How is this useful?) */ #define WORD_PREFIX_OPCODE 0x66 -- 2.30.2