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 ****************************************************************************/
42 #if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
51 #include "x86emu/x86emui.h"
53 /*----------------------------- Implementation ----------------------------*/
55 /****************************************************************************
57 Handles any pending asychronous interrupts.
58 ****************************************************************************/
60 x86emu_intr_handle(void)
64 if (M
.x86
.intr
& INTR_SYNCH
) {
66 if (_X86EMU_intrTab
[intno
]) {
67 (*_X86EMU_intrTab
[intno
]) (intno
);
70 push_word((u16
) M
.x86
.R_FLG
);
73 push_word(M
.x86
.R_CS
);
74 M
.x86
.R_CS
= mem_access_word(intno
* 4 + 2);
75 push_word(M
.x86
.R_IP
);
76 M
.x86
.R_IP
= mem_access_word(intno
* 4);
82 /****************************************************************************
84 intrnum - Interrupt number to raise
87 Raise the specified interrupt to be handled before the execution of the
89 ****************************************************************************/
91 x86emu_intr_raise(u8 intrnum
)
93 M
.x86
.intno
= intrnum
;
94 M
.x86
.intr
|= INTR_SYNCH
;
97 /****************************************************************************
99 Main execution loop for the emulator. We return from here when the system
100 halts, which is normally caused by a stack fault when we return from the
101 original real mode call.
102 ****************************************************************************/
109 DB(x86emu_end_instr();
113 DB(if (CHECK_IP_FETCH())
114 x86emu_check_ip_access();)
115 /* If debugging, save the IP and CS values. */
116 SAVE_IP_CS(M
.x86
.R_CS
, M
.x86
.R_IP
);
117 INC_DECODED_INST_LEN(1);
119 if (M
.x86
.intr
& INTR_HALTED
) {
120 DB(if (M
.x86
.R_SP
!= 0) {
121 printk("halted\n"); X86EMU_trace_regs();}
124 printk("Service completed successfully\n");}
128 if (((M
.x86
.intr
& INTR_SYNCH
) &&
129 (M
.x86
.intno
== 0 || M
.x86
.intno
== 2)) ||
130 !ACCESS_FLAG(F_IF
)) {
131 x86emu_intr_handle();
134 op1
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
135 (*x86emu_optab
[op1
]) (op1
);
136 if (M
.x86
.debug
& DEBUG_EXIT
) {
137 M
.x86
.debug
&= ~DEBUG_EXIT
;
143 /****************************************************************************
145 Halts the system by setting the halted system flag.
146 ****************************************************************************/
148 X86EMU_halt_sys(void)
150 M
.x86
.intr
|= INTR_HALTED
;
153 /****************************************************************************
155 mod - Mod value from decoded byte
156 regh - Reg h value from decoded byte
157 regl - Reg l value from decoded byte
160 Raise the specified interrupt to be handled before the execution of the
163 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
164 ****************************************************************************/
166 fetch_decode_modrm(int *mod
, int *regh
, int *regl
)
170 DB(if (CHECK_IP_FETCH())
171 x86emu_check_ip_access();)
172 fetched
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
173 INC_DECODED_INST_LEN(1);
174 *mod
= (fetched
>> 6) & 0x03;
175 *regh
= (fetched
>> 3) & 0x07;
176 *regl
= (fetched
>> 0) & 0x07;
179 /****************************************************************************
181 Immediate byte value read from instruction queue
184 This function returns the immediate byte from the instruction queue, and
185 moves the instruction pointer to the next value.
187 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
188 ****************************************************************************/
194 DB(if (CHECK_IP_FETCH())
195 x86emu_check_ip_access();)
196 fetched
= (*sys_rdb
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
197 INC_DECODED_INST_LEN(1);
201 /****************************************************************************
203 Immediate word value read from instruction queue
206 This function returns the immediate byte from the instruction queue, and
207 moves the instruction pointer to the next value.
209 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
210 ****************************************************************************/
216 DB(if (CHECK_IP_FETCH())
217 x86emu_check_ip_access();)
218 fetched
= (*sys_rdw
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
220 INC_DECODED_INST_LEN(2);
224 /****************************************************************************
226 Immediate lone value read from instruction queue
229 This function returns the immediate byte from the instruction queue, and
230 moves the instruction pointer to the next value.
232 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
233 ****************************************************************************/
239 DB(if (CHECK_IP_FETCH())
240 x86emu_check_ip_access();)
241 fetched
= (*sys_rdl
) (((u32
) M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
243 INC_DECODED_INST_LEN(4);
247 /****************************************************************************
249 Value of the default data segment
252 Inline function that returns the default data segment for the current
255 On the x86 processor, the default segment is not always DS if there is
256 no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
257 addresses relative to SS (ie: on the stack). So, at the minimum, all
258 decodings of addressing modes would have to set/clear a bit describing
259 whether the access is relative to DS or SS. That is the function of the
260 cpu-state-varible M.x86.mode. There are several potential states:
262 repe prefix seen (handled elsewhere)
263 repne prefix seen (ditto)
272 ds/ss select (in absense of override)
274 Each of the above 7 items are handled with a bit in the mode field.
275 ****************************************************************************/
277 get_data_segment(void)
279 #define GET_SEGMENT(segment)
280 switch (M
.x86
.mode
& SYSMODE_SEGMASK
) {
281 case 0: /* default case: use ds register */
282 case SYSMODE_SEGOVR_DS
:
283 case SYSMODE_SEGOVR_DS
| SYSMODE_SEG_DS_SS
:
285 case SYSMODE_SEG_DS_SS
: /* non-overridden, use ss register */
287 case SYSMODE_SEGOVR_CS
:
288 case SYSMODE_SEGOVR_CS
| SYSMODE_SEG_DS_SS
:
290 case SYSMODE_SEGOVR_ES
:
291 case SYSMODE_SEGOVR_ES
| SYSMODE_SEG_DS_SS
:
293 case SYSMODE_SEGOVR_FS
:
294 case SYSMODE_SEGOVR_FS
| SYSMODE_SEG_DS_SS
:
296 case SYSMODE_SEGOVR_GS
:
297 case SYSMODE_SEGOVR_GS
| SYSMODE_SEG_DS_SS
:
299 case SYSMODE_SEGOVR_SS
:
300 case SYSMODE_SEGOVR_SS
| SYSMODE_SEG_DS_SS
:
304 printk("error: should not happen: multiple overrides.\n");
311 /****************************************************************************
313 offset - Offset to load data from
316 Byte value read from the absolute memory location.
318 NOTE: Do not inline this function as (*sys_rdX) is already inline!
319 ****************************************************************************/
321 fetch_data_byte(uint offset
)
324 if (CHECK_DATA_ACCESS())
325 x86emu_check_data_access((u16
) get_data_segment(), offset
);
327 return (*sys_rdb
) ((get_data_segment() << 4) + offset
);
330 /****************************************************************************
332 offset - Offset to load data from
335 Word value read from the absolute memory location.
337 NOTE: Do not inline this function as (*sys_rdX) is already inline!
338 ****************************************************************************/
340 fetch_data_word(uint offset
)
343 if (CHECK_DATA_ACCESS())
344 x86emu_check_data_access((u16
) get_data_segment(), offset
);
346 return (*sys_rdw
) ((get_data_segment() << 4) + offset
);
349 /****************************************************************************
351 offset - Offset to load data from
354 Long value read from the absolute memory location.
356 NOTE: Do not inline this function as (*sys_rdX) is already inline!
357 ****************************************************************************/
359 fetch_data_long(uint offset
)
362 if (CHECK_DATA_ACCESS())
363 x86emu_check_data_access((u16
) get_data_segment(), offset
);
365 return (*sys_rdl
) ((get_data_segment() << 4) + offset
);
368 /****************************************************************************
370 segment - Segment to load data from
371 offset - Offset to load data from
374 Byte value read from the absolute memory location.
376 NOTE: Do not inline this function as (*sys_rdX) is already inline!
377 ****************************************************************************/
379 fetch_data_byte_abs(uint segment
, uint offset
)
382 if (CHECK_DATA_ACCESS())
383 x86emu_check_data_access(segment
, offset
);
385 return (*sys_rdb
) (((u32
) segment
<< 4) + offset
);
388 /****************************************************************************
390 segment - Segment to load data from
391 offset - Offset to load data from
394 Word value read from the absolute memory location.
396 NOTE: Do not inline this function as (*sys_rdX) is already inline!
397 ****************************************************************************/
399 fetch_data_word_abs(uint segment
, uint offset
)
402 if (CHECK_DATA_ACCESS())
403 x86emu_check_data_access(segment
, offset
);
405 return (*sys_rdw
) (((u32
) segment
<< 4) + offset
);
408 /****************************************************************************
410 segment - Segment to load data from
411 offset - Offset to load data from
414 Long value read from the absolute memory location.
416 NOTE: Do not inline this function as (*sys_rdX) is already inline!
417 ****************************************************************************/
419 fetch_data_long_abs(uint segment
, uint offset
)
422 if (CHECK_DATA_ACCESS())
423 x86emu_check_data_access(segment
, offset
);
425 return (*sys_rdl
) (((u32
) segment
<< 4) + offset
);
428 /****************************************************************************
430 offset - Offset to store data at
434 Writes a word value to an segmented memory location. The segment used is
435 the current 'default' segment, which may have been overridden.
437 NOTE: Do not inline this function as (*sys_wrX) is already inline!
438 ****************************************************************************/
440 store_data_byte(uint offset
, u8 val
)
443 if (CHECK_DATA_ACCESS())
444 x86emu_check_data_access((u16
) get_data_segment(), offset
);
446 (*sys_wrb
) ((get_data_segment() << 4) + offset
, val
);
449 /****************************************************************************
451 offset - Offset to store data at
455 Writes a word value to an segmented memory location. The segment used is
456 the current 'default' segment, which may have been overridden.
458 NOTE: Do not inline this function as (*sys_wrX) is already inline!
459 ****************************************************************************/
461 store_data_word(uint offset
, u16 val
)
464 if (CHECK_DATA_ACCESS())
465 x86emu_check_data_access((u16
) get_data_segment(), offset
);
467 (*sys_wrw
) ((get_data_segment() << 4) + offset
, val
);
470 /****************************************************************************
472 offset - Offset to store data at
476 Writes a long value to an segmented memory location. The segment used is
477 the current 'default' segment, which may have been overridden.
479 NOTE: Do not inline this function as (*sys_wrX) is already inline!
480 ****************************************************************************/
482 store_data_long(uint offset
, u32 val
)
485 if (CHECK_DATA_ACCESS())
486 x86emu_check_data_access((u16
) get_data_segment(), offset
);
488 (*sys_wrl
) ((get_data_segment() << 4) + offset
, val
);
491 /****************************************************************************
493 segment - Segment to store data at
494 offset - Offset to store data at
498 Writes a byte value to an absolute memory location.
500 NOTE: Do not inline this function as (*sys_wrX) is already inline!
501 ****************************************************************************/
503 store_data_byte_abs(uint segment
, uint offset
, u8 val
)
506 if (CHECK_DATA_ACCESS())
507 x86emu_check_data_access(segment
, offset
);
509 (*sys_wrb
) (((u32
) segment
<< 4) + offset
, val
);
512 /****************************************************************************
514 segment - Segment to store data at
515 offset - Offset to store data at
519 Writes a word value to an absolute memory location.
521 NOTE: Do not inline this function as (*sys_wrX) is already inline!
522 ****************************************************************************/
524 store_data_word_abs(uint segment
, uint offset
, u16 val
)
527 if (CHECK_DATA_ACCESS())
528 x86emu_check_data_access(segment
, offset
);
530 (*sys_wrw
) (((u32
) segment
<< 4) + offset
, val
);
533 /****************************************************************************
535 segment - Segment to store data at
536 offset - Offset to store data at
540 Writes a long value to an absolute memory location.
542 NOTE: Do not inline this function as (*sys_wrX) is already inline!
543 ****************************************************************************/
545 store_data_long_abs(uint segment
, uint offset
, u32 val
)
548 if (CHECK_DATA_ACCESS())
549 x86emu_check_data_access(segment
, offset
);
551 (*sys_wrl
) (((u32
) segment
<< 4) + offset
, val
);
554 /****************************************************************************
556 reg - Register to decode
559 Pointer to the appropriate register
562 Return a pointer to the register given by the R/RM field of the
563 modrm byte, for byte operands. Also enables the decoding of instructions.
564 ****************************************************************************/
566 decode_rm_byte_register(int reg
)
595 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
598 /****************************************************************************
600 reg - Register to decode
603 Pointer to the appropriate register
606 Return a pointer to the register given by the R/RM field of the
607 modrm byte, for word operands. Also enables the decoding of instructions.
608 ****************************************************************************/
610 decode_rm_word_register(int reg
)
639 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
642 /****************************************************************************
644 reg - Register to decode
647 Pointer to the appropriate register
650 Return a pointer to the register given by the R/RM field of the
651 modrm byte, for dword operands. Also enables the decoding of instructions.
652 ****************************************************************************/
654 decode_rm_long_register(int reg
)
658 DECODE_PRINTF("EAX");
661 DECODE_PRINTF("ECX");
664 DECODE_PRINTF("EDX");
667 DECODE_PRINTF("EBX");
670 DECODE_PRINTF("ESP");
673 DECODE_PRINTF("EBP");
676 DECODE_PRINTF("ESI");
679 DECODE_PRINTF("EDI");
683 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
686 /****************************************************************************
688 reg - Register to decode
691 Pointer to the appropriate register
694 Return a pointer to the register given by the R/RM field of the
695 modrm byte, for word operands, modified from above for the weirdo
696 special case of segreg operands. Also enables the decoding of instructions.
697 ****************************************************************************/
699 decode_rm_seg_register(int reg
)
722 DECODE_PRINTF("ILLEGAL SEGREG");
726 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
731 * return offset from the SIB Byte
734 decode_sib_address(int sib
, int mod
)
736 u32 base
= 0, i
= 0, scale
= 1;
738 switch (sib
& 0x07) {
740 DECODE_PRINTF("[EAX]");
744 DECODE_PRINTF("[ECX]");
748 DECODE_PRINTF("[EDX]");
752 DECODE_PRINTF("[EBX]");
756 DECODE_PRINTF("[ESP]");
758 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
762 base
= fetch_long_imm();
763 DECODE_PRINTF2("%08x", base
);
766 DECODE_PRINTF("[EBP]");
768 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
772 DECODE_PRINTF("[ESI]");
776 DECODE_PRINTF("[EDI]");
780 switch ((sib
>> 3) & 0x07) {
782 DECODE_PRINTF("[EAX");
786 DECODE_PRINTF("[ECX");
790 DECODE_PRINTF("[EDX");
794 DECODE_PRINTF("[EBX");
801 DECODE_PRINTF("[EBP");
805 DECODE_PRINTF("[ESI");
809 DECODE_PRINTF("[EDI");
813 scale
= 1 << ((sib
>> 6) & 0x03);
814 if (((sib
>> 3) & 0x07) != 4) {
819 DECODE_PRINTF2("*%d]", scale
);
822 return base
+ (i
* scale
);
825 /****************************************************************************
827 rm - RM value to decode
830 Offset in memory for the address decoding
833 Return the offset given by mod=00 addressing. Also enables the
834 decoding of instructions.
836 NOTE: The code which specifies the corresponding segment (ds vs ss)
837 below in the case of [BP+..]. The assumption here is that at the
838 point that this subroutine is called, the bit corresponding to
839 SYSMODE_SEG_DS_SS will be zero. After every instruction
840 except the segment override instructions, this bit (as well
841 as any bits indicating segment overrides) will be clear. So
842 if a SS access is needed, set this bit. Otherwise, DS access
843 occurs (unless any of the segment override bits are set).
844 ****************************************************************************/
846 decode_rm00_address(int rm
)
851 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
852 /* 32-bit addressing */
855 DECODE_PRINTF("[EAX]");
858 DECODE_PRINTF("[ECX]");
861 DECODE_PRINTF("[EDX]");
864 DECODE_PRINTF("[EBX]");
867 sib
= fetch_byte_imm();
868 return decode_sib_address(sib
, 0);
870 offset
= fetch_long_imm();
871 DECODE_PRINTF2("[%08x]", offset
);
874 DECODE_PRINTF("[ESI]");
877 DECODE_PRINTF("[EDI]");
883 /* 16-bit addressing */
886 DECODE_PRINTF("[BX+SI]");
887 return (M
.x86
.R_BX
+ M
.x86
.R_SI
) & 0xffff;
889 DECODE_PRINTF("[BX+DI]");
890 return (M
.x86
.R_BX
+ M
.x86
.R_DI
) & 0xffff;
892 DECODE_PRINTF("[BP+SI]");
893 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
894 return (M
.x86
.R_BP
+ M
.x86
.R_SI
) & 0xffff;
896 DECODE_PRINTF("[BP+DI]");
897 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
898 return (M
.x86
.R_BP
+ M
.x86
.R_DI
) & 0xffff;
900 DECODE_PRINTF("[SI]");
903 DECODE_PRINTF("[DI]");
906 offset
= fetch_word_imm();
907 DECODE_PRINTF2("[%04x]", offset
);
910 DECODE_PRINTF("[BX]");
918 /****************************************************************************
920 rm - RM value to decode
923 Offset in memory for the address decoding
926 Return the offset given by mod=01 addressing. Also enables the
927 decoding of instructions.
928 ****************************************************************************/
930 decode_rm01_address(int rm
)
932 int displacement
= 0;
935 /* Fetch disp8 if no SIB byte */
936 if (!((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) && (rm
== 4)))
937 displacement
= (s8
) fetch_byte_imm();
939 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
940 /* 32-bit addressing */
943 DECODE_PRINTF2("%d[EAX]", displacement
);
944 return M
.x86
.R_EAX
+ displacement
;
946 DECODE_PRINTF2("%d[ECX]", displacement
);
947 return M
.x86
.R_ECX
+ displacement
;
949 DECODE_PRINTF2("%d[EDX]", displacement
);
950 return M
.x86
.R_EDX
+ displacement
;
952 DECODE_PRINTF2("%d[EBX]", displacement
);
953 return M
.x86
.R_EBX
+ displacement
;
955 sib
= fetch_byte_imm();
956 displacement
= (s8
) fetch_byte_imm();
957 DECODE_PRINTF2("%d", displacement
);
958 return decode_sib_address(sib
, 1) + displacement
;
960 DECODE_PRINTF2("%d[EBP]", displacement
);
961 return M
.x86
.R_EBP
+ displacement
;
963 DECODE_PRINTF2("%d[ESI]", displacement
);
964 return M
.x86
.R_ESI
+ displacement
;
966 DECODE_PRINTF2("%d[EDI]", displacement
);
967 return M
.x86
.R_EDI
+ displacement
;
972 /* 16-bit addressing */
975 DECODE_PRINTF2("%d[BX+SI]", displacement
);
976 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
978 DECODE_PRINTF2("%d[BX+DI]", displacement
);
979 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
981 DECODE_PRINTF2("%d[BP+SI]", displacement
);
982 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
983 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
985 DECODE_PRINTF2("%d[BP+DI]", displacement
);
986 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
987 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
989 DECODE_PRINTF2("%d[SI]", displacement
);
990 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
992 DECODE_PRINTF2("%d[DI]", displacement
);
993 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
995 DECODE_PRINTF2("%d[BP]", displacement
);
996 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
997 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
999 DECODE_PRINTF2("%d[BX]", displacement
);
1000 return (M
.x86
.R_BX
+ displacement
) & 0xffff;
1004 return 0; /* SHOULD NOT HAPPEN */
1007 /****************************************************************************
1009 rm - RM value to decode
1012 Offset in memory for the address decoding
1015 Return the offset given by mod=10 addressing. Also enables the
1016 decoding of instructions.
1017 ****************************************************************************/
1019 decode_rm10_address(int rm
)
1021 u32 displacement
= 0;
1024 /* Fetch disp16 if 16-bit addr mode */
1025 if (!(M
.x86
.mode
& SYSMODE_PREFIX_ADDR
))
1026 displacement
= (u16
) fetch_word_imm();
1028 /* Fetch disp32 if no SIB byte */
1030 displacement
= (u32
) fetch_long_imm();
1033 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
1034 /* 32-bit addressing */
1037 DECODE_PRINTF2("%08x[EAX]", displacement
);
1038 return M
.x86
.R_EAX
+ displacement
;
1040 DECODE_PRINTF2("%08x[ECX]", displacement
);
1041 return M
.x86
.R_ECX
+ displacement
;
1043 DECODE_PRINTF2("%08x[EDX]", displacement
);
1044 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1045 return M
.x86
.R_EDX
+ displacement
;
1047 DECODE_PRINTF2("%08x[EBX]", displacement
);
1048 return M
.x86
.R_EBX
+ displacement
;
1050 sib
= fetch_byte_imm();
1051 displacement
= (u32
) fetch_long_imm();
1052 DECODE_PRINTF2("%08x", displacement
);
1053 return decode_sib_address(sib
, 2) + displacement
;
1056 DECODE_PRINTF2("%08x[EBP]", displacement
);
1057 return M
.x86
.R_EBP
+ displacement
;
1059 DECODE_PRINTF2("%08x[ESI]", displacement
);
1060 return M
.x86
.R_ESI
+ displacement
;
1062 DECODE_PRINTF2("%08x[EDI]", displacement
);
1063 return M
.x86
.R_EDI
+ displacement
;
1068 /* 16-bit addressing */
1071 DECODE_PRINTF2("%04x[BX+SI]", displacement
);
1072 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1074 DECODE_PRINTF2("%04x[BX+DI]", displacement
);
1075 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1077 DECODE_PRINTF2("%04x[BP+SI]", displacement
);
1078 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1079 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1081 DECODE_PRINTF2("%04x[BP+DI]", displacement
);
1082 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1083 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1085 DECODE_PRINTF2("%04x[SI]", displacement
);
1086 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
1088 DECODE_PRINTF2("%04x[DI]", displacement
);
1089 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
1091 DECODE_PRINTF2("%04x[BP]", displacement
);
1092 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1093 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
1095 DECODE_PRINTF2("%04x[BX]", displacement
);
1096 return (M
.x86
.R_BX
+ displacement
) & 0xffff;