1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines which are related to
36 * instruction decoding and accessess of immediate data via IP. etc.
38 ****************************************************************************/
41 #include "x86emu/x86emui.h"
43 /*----------------------------- Implementation ----------------------------*/
45 /****************************************************************************
47 Handles any pending asychronous interrupts.
48 ****************************************************************************/
49 static void x86emu_intr_handle(void)
53 if (M
.x86
.intr
& INTR_SYNCH
) {
55 if (_X86EMU_intrTab
[intno
]) {
56 (*_X86EMU_intrTab
[intno
])(intno
);
58 push_word((u16
)M
.x86
.R_FLG
);
61 push_word(M
.x86
.R_CS
);
62 M
.x86
.R_CS
= mem_access_word(intno
* 4 + 2);
63 push_word(M
.x86
.R_IP
);
64 M
.x86
.R_IP
= mem_access_word(intno
* 4);
70 /****************************************************************************
72 intrnum - Interrupt number to raise
75 Raise the specified interrupt to be handled before the execution of the
77 ****************************************************************************/
78 void x86emu_intr_raise(
81 M
.x86
.intno
= intrnum
;
82 M
.x86
.intr
|= INTR_SYNCH
;
85 /****************************************************************************
87 Main execution loop for the emulator. We return from here when the system
88 halts, which is normally caused by a stack fault when we return from the
89 original real mode call.
90 ****************************************************************************/
91 void X86EMU_exec(void)
96 DB(x86emu_end_instr();)
99 DB( if (CHECK_IP_FETCH())
100 x86emu_check_ip_access();)
101 /* If debugging, save the IP and CS values. */
102 SAVE_IP_CS(M
.x86
.R_CS
, M
.x86
.R_IP
);
103 INC_DECODED_INST_LEN(1);
105 if (M
.x86
.intr
& INTR_HALTED
) {
106 DB( if (M
.x86
.R_SP
!= 0) {
112 printk("Service completed successfully\n");
116 if (((M
.x86
.intr
& INTR_SYNCH
) && (M
.x86
.intno
== 0 || M
.x86
.intno
== 2)) ||
117 !ACCESS_FLAG(F_IF
)) {
118 x86emu_intr_handle();
122 op1
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
123 (*x86emu_optab
[op1
])(op1
);
124 if (M
.x86
.debug
& DEBUG_EXIT
) {
125 M
.x86
.debug
&= ~DEBUG_EXIT
;
131 /****************************************************************************
133 Halts the system by setting the halted system flag.
134 ****************************************************************************/
135 void X86EMU_halt_sys(void)
137 M
.x86
.intr
|= INTR_HALTED
;
140 /****************************************************************************
142 mod - Mod value from decoded byte
143 regh - Reg h value from decoded byte
144 regl - Reg l value from decoded byte
147 Raise the specified interrupt to be handled before the execution of the
150 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
151 ****************************************************************************/
152 void fetch_decode_modrm(
159 DB( if (CHECK_IP_FETCH())
160 x86emu_check_ip_access();)
161 fetched
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
162 INC_DECODED_INST_LEN(1);
163 *mod
= (fetched
>> 6) & 0x03;
164 *regh
= (fetched
>> 3) & 0x07;
165 *regl
= (fetched
>> 0) & 0x07;
168 /****************************************************************************
170 Immediate byte value read from instruction queue
173 This function returns the immediate byte from the instruction queue, and
174 moves the instruction pointer to the next value.
176 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
177 ****************************************************************************/
178 u8
fetch_byte_imm(void)
182 DB( if (CHECK_IP_FETCH())
183 x86emu_check_ip_access();)
184 fetched
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
185 INC_DECODED_INST_LEN(1);
189 /****************************************************************************
191 Immediate word value read from instruction queue
194 This function returns the immediate byte from the instruction queue, and
195 moves the instruction pointer to the next value.
197 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
198 ****************************************************************************/
199 u16
fetch_word_imm(void)
203 DB( if (CHECK_IP_FETCH())
204 x86emu_check_ip_access();)
205 fetched
= (*sys_rdw
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
207 INC_DECODED_INST_LEN(2);
211 /****************************************************************************
213 Immediate lone value read from instruction queue
216 This function returns the immediate byte from the instruction queue, and
217 moves the instruction pointer to the next value.
219 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
220 ****************************************************************************/
221 u32
fetch_long_imm(void)
225 DB( if (CHECK_IP_FETCH())
226 x86emu_check_ip_access();)
227 fetched
= (*sys_rdl
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
229 INC_DECODED_INST_LEN(4);
233 /****************************************************************************
235 Value of the default data segment
238 Inline function that returns the default data segment for the current
241 On the x86 processor, the default segment is not always DS if there is
242 no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
243 addresses relative to SS (ie: on the stack). So, at the minimum, all
244 decodings of addressing modes would have to set/clear a bit describing
245 whether the access is relative to DS or SS. That is the function of the
246 cpu-state-varible M.x86.mode. There are several potential states:
248 repe prefix seen (handled elsewhere)
249 repne prefix seen (ditto)
258 ds/ss select (in absense of override)
260 Each of the above 7 items are handled with a bit in the mode field.
261 ****************************************************************************/
262 _INLINE u32
get_data_segment(void)
264 #define GET_SEGMENT(segment)
265 switch (M
.x86
.mode
& SYSMODE_SEGMASK
) {
266 case 0: /* default case: use ds register */
267 case SYSMODE_SEGOVR_DS
:
268 case SYSMODE_SEGOVR_DS
| SYSMODE_SEG_DS_SS
:
270 case SYSMODE_SEG_DS_SS
: /* non-overridden, use ss register */
272 case SYSMODE_SEGOVR_CS
:
273 case SYSMODE_SEGOVR_CS
| SYSMODE_SEG_DS_SS
:
275 case SYSMODE_SEGOVR_ES
:
276 case SYSMODE_SEGOVR_ES
| SYSMODE_SEG_DS_SS
:
278 case SYSMODE_SEGOVR_FS
:
279 case SYSMODE_SEGOVR_FS
| SYSMODE_SEG_DS_SS
:
281 case SYSMODE_SEGOVR_GS
:
282 case SYSMODE_SEGOVR_GS
| SYSMODE_SEG_DS_SS
:
284 case SYSMODE_SEGOVR_SS
:
285 case SYSMODE_SEGOVR_SS
| SYSMODE_SEG_DS_SS
:
289 printk("error: should not happen: multiple overrides.\n");
296 /****************************************************************************
298 offset - Offset to load data from
301 Byte value read from the absolute memory location.
303 NOTE: Do not inline this function as (*sys_rdX) is already inline!
304 ****************************************************************************/
309 if (CHECK_DATA_ACCESS())
310 x86emu_check_data_access((u16
)get_data_segment(), offset
);
312 return (*sys_rdb
)((get_data_segment() << 4) + offset
);
315 /****************************************************************************
317 offset - Offset to load data from
320 Word value read from the absolute memory location.
322 NOTE: Do not inline this function as (*sys_rdX) is already inline!
323 ****************************************************************************/
328 if (CHECK_DATA_ACCESS())
329 x86emu_check_data_access((u16
)get_data_segment(), offset
);
331 return (*sys_rdw
)((get_data_segment() << 4) + offset
);
334 /****************************************************************************
336 offset - Offset to load data from
339 Long value read from the absolute memory location.
341 NOTE: Do not inline this function as (*sys_rdX) is already inline!
342 ****************************************************************************/
347 if (CHECK_DATA_ACCESS())
348 x86emu_check_data_access((u16
)get_data_segment(), offset
);
350 return (*sys_rdl
)((get_data_segment() << 4) + offset
);
353 /****************************************************************************
355 segment - Segment to load data from
356 offset - Offset to load data from
359 Byte value read from the absolute memory location.
361 NOTE: Do not inline this function as (*sys_rdX) is already inline!
362 ****************************************************************************/
363 u8
fetch_data_byte_abs(
368 if (CHECK_DATA_ACCESS())
369 x86emu_check_data_access(segment
, offset
);
371 return (*sys_rdb
)(((u32
)segment
<< 4) + offset
);
374 /****************************************************************************
376 segment - Segment to load data from
377 offset - Offset to load data from
380 Word value read from the absolute memory location.
382 NOTE: Do not inline this function as (*sys_rdX) is already inline!
383 ****************************************************************************/
384 u16
fetch_data_word_abs(
389 if (CHECK_DATA_ACCESS())
390 x86emu_check_data_access(segment
, offset
);
392 return (*sys_rdw
)(((u32
)segment
<< 4) + offset
);
395 /****************************************************************************
397 segment - Segment to load data from
398 offset - Offset to load data from
401 Long value read from the absolute memory location.
403 NOTE: Do not inline this function as (*sys_rdX) is already inline!
404 ****************************************************************************/
405 u32
fetch_data_long_abs(
410 if (CHECK_DATA_ACCESS())
411 x86emu_check_data_access(segment
, offset
);
413 return (*sys_rdl
)(((u32
)segment
<< 4) + offset
);
416 /****************************************************************************
418 offset - Offset to store data at
422 Writes a word value to an segmented memory location. The segment used is
423 the current 'default' segment, which may have been overridden.
425 NOTE: Do not inline this function as (*sys_wrX) is already inline!
426 ****************************************************************************/
427 void store_data_byte(
432 if (CHECK_DATA_ACCESS())
433 x86emu_check_data_access((u16
)get_data_segment(), offset
);
435 (*sys_wrb
)((get_data_segment() << 4) + offset
, val
);
438 /****************************************************************************
440 offset - Offset to store data at
444 Writes a word value to an segmented memory location. The segment used is
445 the current 'default' segment, which may have been overridden.
447 NOTE: Do not inline this function as (*sys_wrX) is already inline!
448 ****************************************************************************/
449 void store_data_word(
454 if (CHECK_DATA_ACCESS())
455 x86emu_check_data_access((u16
)get_data_segment(), offset
);
457 (*sys_wrw
)((get_data_segment() << 4) + offset
, val
);
460 /****************************************************************************
462 offset - Offset to store data at
466 Writes a long value to an segmented memory location. The segment used is
467 the current 'default' segment, which may have been overridden.
469 NOTE: Do not inline this function as (*sys_wrX) is already inline!
470 ****************************************************************************/
471 void store_data_long(
476 if (CHECK_DATA_ACCESS())
477 x86emu_check_data_access((u16
)get_data_segment(), offset
);
479 (*sys_wrl
)((get_data_segment() << 4) + offset
, val
);
482 /****************************************************************************
484 segment - Segment to store data at
485 offset - Offset to store data at
489 Writes a byte value to an absolute memory location.
491 NOTE: Do not inline this function as (*sys_wrX) is already inline!
492 ****************************************************************************/
493 void store_data_byte_abs(
499 if (CHECK_DATA_ACCESS())
500 x86emu_check_data_access(segment
, offset
);
502 (*sys_wrb
)(((u32
)segment
<< 4) + offset
, val
);
505 /****************************************************************************
507 segment - Segment to store data at
508 offset - Offset to store data at
512 Writes a word value to an absolute memory location.
514 NOTE: Do not inline this function as (*sys_wrX) is already inline!
515 ****************************************************************************/
516 void store_data_word_abs(
522 if (CHECK_DATA_ACCESS())
523 x86emu_check_data_access(segment
, offset
);
525 (*sys_wrw
)(((u32
)segment
<< 4) + offset
, val
);
528 /****************************************************************************
530 segment - Segment to store data at
531 offset - Offset to store data at
535 Writes a long value to an absolute memory location.
537 NOTE: Do not inline this function as (*sys_wrX) is already inline!
538 ****************************************************************************/
539 void store_data_long_abs(
545 if (CHECK_DATA_ACCESS())
546 x86emu_check_data_access(segment
, offset
);
548 (*sys_wrl
)(((u32
)segment
<< 4) + offset
, val
);
551 /****************************************************************************
553 reg - Register to decode
556 Pointer to the appropriate register
559 Return a pointer to the register given by the R/RM field of the
560 modrm byte, for byte operands. Also enables the decoding of instructions.
561 ****************************************************************************/
562 u8
* decode_rm_byte_register(
592 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
595 /****************************************************************************
597 reg - Register to decode
600 Pointer to the appropriate register
603 Return a pointer to the register given by the R/RM field of the
604 modrm byte, for word operands. Also enables the decoding of instructions.
605 ****************************************************************************/
606 u16
* decode_rm_word_register(
636 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
639 /****************************************************************************
641 reg - Register to decode
644 Pointer to the appropriate register
647 Return a pointer to the register given by the R/RM field of the
648 modrm byte, for dword operands. Also enables the decoding of instructions.
649 ****************************************************************************/
650 u32
* decode_rm_long_register(
655 DECODE_PRINTF("EAX");
658 DECODE_PRINTF("ECX");
661 DECODE_PRINTF("EDX");
664 DECODE_PRINTF("EBX");
667 DECODE_PRINTF("ESP");
670 DECODE_PRINTF("EBP");
673 DECODE_PRINTF("ESI");
676 DECODE_PRINTF("EDI");
680 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
683 /****************************************************************************
685 reg - Register to decode
688 Pointer to the appropriate register
691 Return a pointer to the register given by the R/RM field of the
692 modrm byte, for word operands, modified from above for the weirdo
693 special case of segreg operands. Also enables the decoding of instructions.
694 ****************************************************************************/
695 u16
* decode_rm_seg_register(
719 DECODE_PRINTF("ILLEGAL SEGREG");
723 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
728 * return offset from the SIB Byte
730 u32
decode_sib_address(int sib
, int mod
)
732 u32 base
= 0, i
= 0, scale
= 1;
736 DECODE_PRINTF("[EAX]");
740 DECODE_PRINTF("[ECX]");
744 DECODE_PRINTF("[EDX]");
748 DECODE_PRINTF("[EBX]");
752 DECODE_PRINTF("[ESP]");
754 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
758 base
= fetch_long_imm();
759 DECODE_PRINTF2("%08x", base
);
761 DECODE_PRINTF("[EBP]");
763 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
767 DECODE_PRINTF("[ESI]");
771 DECODE_PRINTF("[EDI]");
775 switch ((sib
>> 3) & 0x07) {
777 DECODE_PRINTF("[EAX");
781 DECODE_PRINTF("[ECX");
785 DECODE_PRINTF("[EDX");
789 DECODE_PRINTF("[EBX");
796 DECODE_PRINTF("[EBP");
800 DECODE_PRINTF("[ESI");
804 DECODE_PRINTF("[EDI");
808 scale
= 1 << ((sib
>> 6) & 0x03);
809 if (((sib
>> 3) & 0x07) != 4) {
813 DECODE_PRINTF2("*%d]", scale
);
816 return base
+ (i
* scale
);
819 /****************************************************************************
821 rm - RM value to decode
824 Offset in memory for the address decoding
827 Return the offset given by mod=00 addressing. Also enables the
828 decoding of instructions.
830 NOTE: The code which specifies the corresponding segment (ds vs ss)
831 below in the case of [BP+..]. The assumption here is that at the
832 point that this subroutine is called, the bit corresponding to
833 SYSMODE_SEG_DS_SS will be zero. After every instruction
834 except the segment override instructions, this bit (as well
835 as any bits indicating segment overrides) will be clear. So
836 if a SS access is needed, set this bit. Otherwise, DS access
837 occurs (unless any of the segment override bits are set).
838 ****************************************************************************/
839 u32
decode_rm00_address(
845 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
846 /* 32-bit addressing */
849 DECODE_PRINTF("[EAX]");
852 DECODE_PRINTF("[ECX]");
855 DECODE_PRINTF("[EDX]");
858 DECODE_PRINTF("[EBX]");
861 sib
= fetch_byte_imm();
862 return decode_sib_address(sib
, 0);
864 offset
= fetch_long_imm();
865 DECODE_PRINTF2("[%08x]", offset
);
868 DECODE_PRINTF("[ESI]");
871 DECODE_PRINTF("[EDI]");
876 /* 16-bit addressing */
879 DECODE_PRINTF("[BX+SI]");
880 return (M
.x86
.R_BX
+ M
.x86
.R_SI
) & 0xffff;
882 DECODE_PRINTF("[BX+DI]");
883 return (M
.x86
.R_BX
+ M
.x86
.R_DI
) & 0xffff;
885 DECODE_PRINTF("[BP+SI]");
886 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
887 return (M
.x86
.R_BP
+ M
.x86
.R_SI
) & 0xffff;
889 DECODE_PRINTF("[BP+DI]");
890 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
891 return (M
.x86
.R_BP
+ M
.x86
.R_DI
) & 0xffff;
893 DECODE_PRINTF("[SI]");
896 DECODE_PRINTF("[DI]");
899 offset
= fetch_word_imm();
900 DECODE_PRINTF2("[%04x]", offset
);
903 DECODE_PRINTF("[BX]");
911 /****************************************************************************
913 rm - RM value to decode
916 Offset in memory for the address decoding
919 Return the offset given by mod=01 addressing. Also enables the
920 decoding of instructions.
921 ****************************************************************************/
922 u32
decode_rm01_address(
925 int displacement
= 0;
928 /* Fetch disp8 if no SIB byte */
929 if (!((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) && (rm
== 4)))
930 displacement
= (s8
)fetch_byte_imm();
932 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
933 /* 32-bit addressing */
936 DECODE_PRINTF2("%d[EAX]", displacement
);
937 return M
.x86
.R_EAX
+ displacement
;
939 DECODE_PRINTF2("%d[ECX]", displacement
);
940 return M
.x86
.R_ECX
+ displacement
;
942 DECODE_PRINTF2("%d[EDX]", displacement
);
943 return M
.x86
.R_EDX
+ displacement
;
945 DECODE_PRINTF2("%d[EBX]", displacement
);
946 return M
.x86
.R_EBX
+ displacement
;
948 sib
= fetch_byte_imm();
949 displacement
= (s8
)fetch_byte_imm();
950 DECODE_PRINTF2("%d", displacement
);
951 return decode_sib_address(sib
, 1) + displacement
;
953 DECODE_PRINTF2("%d[EBP]", displacement
);
954 return M
.x86
.R_EBP
+ displacement
;
956 DECODE_PRINTF2("%d[ESI]", displacement
);
957 return M
.x86
.R_ESI
+ displacement
;
959 DECODE_PRINTF2("%d[EDI]", displacement
);
960 return M
.x86
.R_EDI
+ displacement
;
964 /* 16-bit addressing */
967 DECODE_PRINTF2("%d[BX+SI]", displacement
);
968 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
970 DECODE_PRINTF2("%d[BX+DI]", displacement
);
971 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
973 DECODE_PRINTF2("%d[BP+SI]", displacement
);
974 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
975 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
977 DECODE_PRINTF2("%d[BP+DI]", displacement
);
978 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
979 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
981 DECODE_PRINTF2("%d[SI]", displacement
);
982 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
984 DECODE_PRINTF2("%d[DI]", displacement
);
985 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
987 DECODE_PRINTF2("%d[BP]", displacement
);
988 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
989 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
991 DECODE_PRINTF2("%d[BX]", displacement
);
992 return (M
.x86
.R_BX
+ displacement
) & 0xffff;
996 return 0; /* SHOULD NOT HAPPEN */
999 /****************************************************************************
1001 rm - RM value to decode
1004 Offset in memory for the address decoding
1007 Return the offset given by mod=10 addressing. Also enables the
1008 decoding of instructions.
1009 ****************************************************************************/
1010 u32
decode_rm10_address(
1013 u32 displacement
= 0;
1016 /* Fetch disp16 if 16-bit addr mode */
1017 if (!(M
.x86
.mode
& SYSMODE_PREFIX_ADDR
))
1018 displacement
= (u16
)fetch_word_imm();
1020 /* Fetch disp32 if no SIB byte */
1022 displacement
= (u32
)fetch_long_imm();
1025 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
1026 /* 32-bit addressing */
1029 DECODE_PRINTF2("%08x[EAX]", displacement
);
1030 return M
.x86
.R_EAX
+ displacement
;
1032 DECODE_PRINTF2("%08x[ECX]", displacement
);
1033 return M
.x86
.R_ECX
+ displacement
;
1035 DECODE_PRINTF2("%08x[EDX]", displacement
);
1036 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1037 return M
.x86
.R_EDX
+ displacement
;
1039 DECODE_PRINTF2("%08x[EBX]", displacement
);
1040 return M
.x86
.R_EBX
+ displacement
;
1042 sib
= fetch_byte_imm();
1043 displacement
= (u32
)fetch_long_imm();
1044 DECODE_PRINTF2("%08x", displacement
);
1045 return decode_sib_address(sib
, 2) + displacement
;
1048 DECODE_PRINTF2("%08x[EBP]", displacement
);
1049 return M
.x86
.R_EBP
+ displacement
;
1051 DECODE_PRINTF2("%08x[ESI]", displacement
);
1052 return M
.x86
.R_ESI
+ displacement
;
1054 DECODE_PRINTF2("%08x[EDI]", displacement
);
1055 return M
.x86
.R_EDI
+ displacement
;
1059 /* 16-bit addressing */
1062 DECODE_PRINTF2("%04x[BX+SI]", displacement
);
1063 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1065 DECODE_PRINTF2("%04x[BX+DI]", displacement
);
1066 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1068 DECODE_PRINTF2("%04x[BP+SI]", displacement
);
1069 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1070 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1072 DECODE_PRINTF2("%04x[BP+DI]", displacement
);
1073 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1074 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1076 DECODE_PRINTF2("%04x[SI]", displacement
);
1077 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
1079 DECODE_PRINTF2("%04x[DI]", displacement
);
1080 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
1082 DECODE_PRINTF2("%04x[BP]", displacement
);
1083 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1084 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
1086 DECODE_PRINTF2("%04x[BX]", displacement
);
1087 return (M
.x86
.R_BX
+ displacement
) & 0xffff;