]>
git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/hwinfo/src/x86emu/decode.c
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 ****************************************************************************/
40 /* $XFree86: xc/extras/x86emu/src/x86emu/decode.c,v 1.11 2002/07/23 20:20:43 tsi Exp $ */
42 #include "x86emu/x86emui.h"
44 /*----------------------------- Implementation ----------------------------*/
46 /****************************************************************************
48 Handles any pending asychronous interrupts.
49 ****************************************************************************/
50 static void x86emu_intr_handle(void)
54 if (M
.x86
.intr
& INTR_SYNCH
) {
56 if (_X86EMU_intrTab
[intno
]) {
57 (*_X86EMU_intrTab
[intno
])(intno
);
59 push_word((u16
)M
.x86
.R_FLG
);
62 push_word(M
.x86
.R_CS
);
63 M
.x86
.R_CS
= mem_access_word(intno
* 4 + 2);
64 push_word(M
.x86
.R_IP
);
65 M
.x86
.R_IP
= mem_access_word(intno
* 4);
71 /****************************************************************************
73 intrnum - Interrupt number to raise
76 Raise the specified interrupt to be handled before the execution of the
78 ****************************************************************************/
79 void x86emu_intr_raise(
82 M
.x86
.intno
= intrnum
;
83 M
.x86
.intr
|= INTR_SYNCH
;
86 /****************************************************************************
88 Main execution loop for the emulator. We return from here when the system
89 halts, which is normally caused by a stack fault when we return from the
90 original real mode call.
91 ****************************************************************************/
93 void X86EMU_exec(unsigned timeout
)
96 unsigned instr_cnt
= 0;
97 unsigned debug
= timeout
& (1 << 31);
98 time_t t0
= time(NULL
);
100 timeout
&= ~(1 << 31);
103 DB(x86emu_end_instr();)
106 DB( if (CHECK_IP_FETCH())
107 x86emu_check_ip_access();)
108 /* If debugging, save the IP and CS values. */
109 SAVE_IP_CS(M
.x86
.R_CS
, M
.x86
.R_IP
);
110 INC_DECODED_INST_LEN(1);
112 if (M
.x86
.intr
& INTR_HALTED
) {
113 DB( if (M
.x86
.R_SP
!= 0) {
119 printk("Service completed successfully\n");
123 if (((M
.x86
.intr
& INTR_SYNCH
) && (M
.x86
.intno
== 0 || M
.x86
.intno
== 2)) ||
124 !ACCESS_FLAG(F_IF
)) {
125 x86emu_intr_handle();
128 op1
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
130 fprintf(stderr
, "%6u: %04x:%04x %02x\n", instr_cnt
++, M
.x86
.R_CS
, M
.x86
.R_IP
- 1, op1
);
132 if(!(instr_cnt
& 0xffff) && timeout
&& time(NULL
) - t0
> timeout
) {
134 fprintf(stderr
, "*** %us timeout ***\n", timeout
);
138 (*x86emu_optab
[op1
])(op1
);
139 if (M
.x86
.debug
& DEBUG_EXIT
) {
140 M
.x86
.debug
&= ~DEBUG_EXIT
;
146 /****************************************************************************
148 Halts the system by setting the halted system flag.
149 ****************************************************************************/
150 void X86EMU_halt_sys(void)
152 M
.x86
.intr
|= INTR_HALTED
;
155 /****************************************************************************
157 mod - Mod value from decoded byte
158 regh - Reg h value from decoded byte
159 regl - Reg l value from decoded byte
162 Raise the specified interrupt to be handled before the execution of the
165 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
166 ****************************************************************************/
167 void fetch_decode_modrm(
174 DB( if (CHECK_IP_FETCH())
175 x86emu_check_ip_access();)
176 fetched
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
177 INC_DECODED_INST_LEN(1);
178 *mod
= (fetched
>> 6) & 0x03;
179 *regh
= (fetched
>> 3) & 0x07;
180 *regl
= (fetched
>> 0) & 0x07;
183 /****************************************************************************
185 Immediate byte value read from instruction queue
188 This function returns the immediate byte from the instruction queue, and
189 moves the instruction pointer to the next value.
191 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
192 ****************************************************************************/
193 u8
fetch_byte_imm(void)
197 DB( if (CHECK_IP_FETCH())
198 x86emu_check_ip_access();)
199 fetched
= (*sys_rdb
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
++));
200 INC_DECODED_INST_LEN(1);
204 /****************************************************************************
206 Immediate word value read from instruction queue
209 This function returns the immediate byte from the instruction queue, and
210 moves the instruction pointer to the next value.
212 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
213 ****************************************************************************/
214 u16
fetch_word_imm(void)
218 DB( if (CHECK_IP_FETCH())
219 x86emu_check_ip_access();)
220 fetched
= (*sys_rdw
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
222 INC_DECODED_INST_LEN(2);
226 /****************************************************************************
228 Immediate lone value read from instruction queue
231 This function returns the immediate byte from the instruction queue, and
232 moves the instruction pointer to the next value.
234 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
235 ****************************************************************************/
236 u32
fetch_long_imm(void)
240 DB( if (CHECK_IP_FETCH())
241 x86emu_check_ip_access();)
242 fetched
= (*sys_rdl
)(((u32
)M
.x86
.R_CS
<< 4) + (M
.x86
.R_IP
));
244 INC_DECODED_INST_LEN(4);
248 /****************************************************************************
250 Value of the default data segment
253 Inline function that returns the default data segment for the current
256 On the x86 processor, the default segment is not always DS if there is
257 no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
258 addresses relative to SS (ie: on the stack). So, at the minimum, all
259 decodings of addressing modes would have to set/clear a bit describing
260 whether the access is relative to DS or SS. That is the function of the
261 cpu-state-varible M.x86.mode. There are several potential states:
263 repe prefix seen (handled elsewhere)
264 repne prefix seen (ditto)
273 ds/ss select (in absense of override)
275 Each of the above 7 items are handled with a bit in the mode field.
276 ****************************************************************************/
277 _INLINE u32
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 ****************************************************************************/
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 ****************************************************************************/
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 ****************************************************************************/
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 ****************************************************************************/
378 u8
fetch_data_byte_abs(
383 if (CHECK_DATA_ACCESS())
384 x86emu_check_data_access(segment
, offset
);
386 return (*sys_rdb
)(((u32
)segment
<< 4) + offset
);
389 /****************************************************************************
391 segment - Segment to load data from
392 offset - Offset to load data from
395 Word value read from the absolute memory location.
397 NOTE: Do not inline this function as (*sys_rdX) is already inline!
398 ****************************************************************************/
399 u16
fetch_data_word_abs(
404 if (CHECK_DATA_ACCESS())
405 x86emu_check_data_access(segment
, offset
);
407 return (*sys_rdw
)(((u32
)segment
<< 4) + offset
);
410 /****************************************************************************
412 segment - Segment to load data from
413 offset - Offset to load data from
416 Long value read from the absolute memory location.
418 NOTE: Do not inline this function as (*sys_rdX) is already inline!
419 ****************************************************************************/
420 u32
fetch_data_long_abs(
425 if (CHECK_DATA_ACCESS())
426 x86emu_check_data_access(segment
, offset
);
428 return (*sys_rdl
)(((u32
)segment
<< 4) + offset
);
431 /****************************************************************************
433 offset - Offset to store data at
437 Writes a word value to an segmented memory location. The segment used is
438 the current 'default' segment, which may have been overridden.
440 NOTE: Do not inline this function as (*sys_wrX) is already inline!
441 ****************************************************************************/
442 void store_data_byte(
447 if (CHECK_DATA_ACCESS())
448 x86emu_check_data_access((u16
)get_data_segment(), offset
);
450 (*sys_wrb
)((get_data_segment() << 4) + offset
, val
);
453 /****************************************************************************
455 offset - Offset to store data at
459 Writes a word value to an segmented memory location. The segment used is
460 the current 'default' segment, which may have been overridden.
462 NOTE: Do not inline this function as (*sys_wrX) is already inline!
463 ****************************************************************************/
464 void store_data_word(
469 if (CHECK_DATA_ACCESS())
470 x86emu_check_data_access((u16
)get_data_segment(), offset
);
472 (*sys_wrw
)((get_data_segment() << 4) + offset
, val
);
475 /****************************************************************************
477 offset - Offset to store data at
481 Writes a long value to an segmented memory location. The segment used is
482 the current 'default' segment, which may have been overridden.
484 NOTE: Do not inline this function as (*sys_wrX) is already inline!
485 ****************************************************************************/
486 void store_data_long(
491 if (CHECK_DATA_ACCESS())
492 x86emu_check_data_access((u16
)get_data_segment(), offset
);
494 (*sys_wrl
)((get_data_segment() << 4) + offset
, val
);
497 /****************************************************************************
499 segment - Segment to store data at
500 offset - Offset to store data at
504 Writes a byte value to an absolute memory location.
506 NOTE: Do not inline this function as (*sys_wrX) is already inline!
507 ****************************************************************************/
508 void store_data_byte_abs(
514 if (CHECK_DATA_ACCESS())
515 x86emu_check_data_access(segment
, offset
);
517 (*sys_wrb
)(((u32
)segment
<< 4) + offset
, val
);
520 /****************************************************************************
522 segment - Segment to store data at
523 offset - Offset to store data at
527 Writes a word value to an absolute memory location.
529 NOTE: Do not inline this function as (*sys_wrX) is already inline!
530 ****************************************************************************/
531 void store_data_word_abs(
537 if (CHECK_DATA_ACCESS())
538 x86emu_check_data_access(segment
, offset
);
540 (*sys_wrw
)(((u32
)segment
<< 4) + offset
, val
);
543 /****************************************************************************
545 segment - Segment to store data at
546 offset - Offset to store data at
550 Writes a long value to an absolute memory location.
552 NOTE: Do not inline this function as (*sys_wrX) is already inline!
553 ****************************************************************************/
554 void store_data_long_abs(
560 if (CHECK_DATA_ACCESS())
561 x86emu_check_data_access(segment
, offset
);
563 (*sys_wrl
)(((u32
)segment
<< 4) + offset
, val
);
566 /****************************************************************************
568 reg - Register to decode
571 Pointer to the appropriate register
574 Return a pointer to the register given by the R/RM field of the
575 modrm byte, for byte operands. Also enables the decoding of instructions.
576 ****************************************************************************/
577 u8
* decode_rm_byte_register(
607 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
610 /****************************************************************************
612 reg - Register to decode
615 Pointer to the appropriate register
618 Return a pointer to the register given by the R/RM field of the
619 modrm byte, for word operands. Also enables the decoding of instructions.
620 ****************************************************************************/
621 u16
* decode_rm_word_register(
651 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
654 /****************************************************************************
656 reg - Register to decode
659 Pointer to the appropriate register
662 Return a pointer to the register given by the R/RM field of the
663 modrm byte, for dword operands. Also enables the decoding of instructions.
664 ****************************************************************************/
665 u32
* decode_rm_long_register(
670 DECODE_PRINTF("EAX");
673 DECODE_PRINTF("ECX");
676 DECODE_PRINTF("EDX");
679 DECODE_PRINTF("EBX");
682 DECODE_PRINTF("ESP");
685 DECODE_PRINTF("EBP");
688 DECODE_PRINTF("ESI");
691 DECODE_PRINTF("EDI");
695 return NULL
; /* NOTREACHED OR REACHED ON ERROR */
698 /****************************************************************************
700 reg - Register to decode
703 Pointer to the appropriate register
706 Return a pointer to the register given by the R/RM field of the
707 modrm byte, for word operands, modified from above for the weirdo
708 special case of segreg operands. Also enables the decoding of instructions.
709 ****************************************************************************/
710 u16
* decode_rm_seg_register(
734 DECODE_PRINTF("ILLEGAL SEGREG");
738 return NULL
; /* NOT REACHED OR REACHED ON ERROR */
743 * return offset from the SIB Byte
745 u32
decode_sib_address(int sib
, int mod
)
747 u32 base
= 0, i
= 0, scale
= 1;
751 DECODE_PRINTF("[EAX]");
755 DECODE_PRINTF("[ECX]");
759 DECODE_PRINTF("[EDX]");
763 DECODE_PRINTF("[EBX]");
767 DECODE_PRINTF("[ESP]");
769 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
773 base
= fetch_long_imm();
774 DECODE_PRINTF2("%08x", base
);
776 DECODE_PRINTF("[EBP]");
778 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
782 DECODE_PRINTF("[ESI]");
786 DECODE_PRINTF("[EDI]");
790 switch ((sib
>> 3) & 0x07) {
792 DECODE_PRINTF("[EAX");
796 DECODE_PRINTF("[ECX");
800 DECODE_PRINTF("[EDX");
804 DECODE_PRINTF("[EBX");
811 DECODE_PRINTF("[EBP");
815 DECODE_PRINTF("[ESI");
819 DECODE_PRINTF("[EDI");
823 scale
= 1 << ((sib
>> 6) & 0x03);
824 if (((sib
>> 3) & 0x07) != 4) {
828 DECODE_PRINTF2("*%d]", scale
);
831 return base
+ (i
* scale
);
834 /****************************************************************************
836 rm - RM value to decode
839 Offset in memory for the address decoding
842 Return the offset given by mod=00 addressing. Also enables the
843 decoding of instructions.
845 NOTE: The code which specifies the corresponding segment (ds vs ss)
846 below in the case of [BP+..]. The assumption here is that at the
847 point that this subroutine is called, the bit corresponding to
848 SYSMODE_SEG_DS_SS will be zero. After every instruction
849 except the segment override instructions, this bit (as well
850 as any bits indicating segment overrides) will be clear. So
851 if a SS access is needed, set this bit. Otherwise, DS access
852 occurs (unless any of the segment override bits are set).
853 ****************************************************************************/
854 u32
decode_rm00_address(
860 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
861 /* 32-bit addressing */
864 DECODE_PRINTF("[EAX]");
867 DECODE_PRINTF("[ECX]");
870 DECODE_PRINTF("[EDX]");
873 DECODE_PRINTF("[EBX]");
876 sib
= fetch_byte_imm();
877 return decode_sib_address(sib
, 0);
879 offset
= fetch_long_imm();
880 DECODE_PRINTF2("[%08x]", offset
);
883 DECODE_PRINTF("[ESI]");
886 DECODE_PRINTF("[EDI]");
891 /* 16-bit addressing */
894 DECODE_PRINTF("[BX+SI]");
895 return (M
.x86
.R_BX
+ M
.x86
.R_SI
) & 0xffff;
897 DECODE_PRINTF("[BX+DI]");
898 return (M
.x86
.R_BX
+ M
.x86
.R_DI
) & 0xffff;
900 DECODE_PRINTF("[BP+SI]");
901 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
902 return (M
.x86
.R_BP
+ M
.x86
.R_SI
) & 0xffff;
904 DECODE_PRINTF("[BP+DI]");
905 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
906 return (M
.x86
.R_BP
+ M
.x86
.R_DI
) & 0xffff;
908 DECODE_PRINTF("[SI]");
911 DECODE_PRINTF("[DI]");
914 offset
= fetch_word_imm();
915 DECODE_PRINTF2("[%04x]", offset
);
918 DECODE_PRINTF("[BX]");
926 /****************************************************************************
928 rm - RM value to decode
931 Offset in memory for the address decoding
934 Return the offset given by mod=01 addressing. Also enables the
935 decoding of instructions.
936 ****************************************************************************/
937 u32
decode_rm01_address(
940 int displacement
= 0;
943 /* Fetch disp8 if no SIB byte */
944 if (!((M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) && (rm
== 4)))
945 displacement
= (s8
)fetch_byte_imm();
947 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
948 /* 32-bit addressing */
951 DECODE_PRINTF2("%d[EAX]", displacement
);
952 return M
.x86
.R_EAX
+ displacement
;
954 DECODE_PRINTF2("%d[ECX]", displacement
);
955 return M
.x86
.R_ECX
+ displacement
;
957 DECODE_PRINTF2("%d[EDX]", displacement
);
958 return M
.x86
.R_EDX
+ displacement
;
960 DECODE_PRINTF2("%d[EBX]", displacement
);
961 return M
.x86
.R_EBX
+ displacement
;
963 sib
= fetch_byte_imm();
964 displacement
= (s8
)fetch_byte_imm();
965 DECODE_PRINTF2("%d", displacement
);
966 return decode_sib_address(sib
, 1) + displacement
;
968 DECODE_PRINTF2("%d[EBP]", displacement
);
969 return M
.x86
.R_EBP
+ displacement
;
971 DECODE_PRINTF2("%d[ESI]", displacement
);
972 return M
.x86
.R_ESI
+ displacement
;
974 DECODE_PRINTF2("%d[EDI]", displacement
);
975 return M
.x86
.R_EDI
+ displacement
;
979 /* 16-bit addressing */
982 DECODE_PRINTF2("%d[BX+SI]", displacement
);
983 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
985 DECODE_PRINTF2("%d[BX+DI]", displacement
);
986 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
988 DECODE_PRINTF2("%d[BP+SI]", displacement
);
989 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
990 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
992 DECODE_PRINTF2("%d[BP+DI]", displacement
);
993 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
994 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
996 DECODE_PRINTF2("%d[SI]", displacement
);
997 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
999 DECODE_PRINTF2("%d[DI]", displacement
);
1000 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
1002 DECODE_PRINTF2("%d[BP]", displacement
);
1003 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1004 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
1006 DECODE_PRINTF2("%d[BX]", displacement
);
1007 return (M
.x86
.R_BX
+ displacement
) & 0xffff;
1011 return 0; /* SHOULD NOT HAPPEN */
1014 /****************************************************************************
1016 rm - RM value to decode
1019 Offset in memory for the address decoding
1022 Return the offset given by mod=10 addressing. Also enables the
1023 decoding of instructions.
1024 ****************************************************************************/
1025 u32
decode_rm10_address(
1028 u32 displacement
= 0;
1031 /* Fetch disp16 if 16-bit addr mode */
1032 if (!(M
.x86
.mode
& SYSMODE_PREFIX_ADDR
))
1033 displacement
= (u16
)fetch_word_imm();
1035 /* Fetch disp32 if no SIB byte */
1037 displacement
= (u32
)fetch_long_imm();
1040 if (M
.x86
.mode
& SYSMODE_PREFIX_ADDR
) {
1041 /* 32-bit addressing */
1044 DECODE_PRINTF2("%08x[EAX]", displacement
);
1045 return M
.x86
.R_EAX
+ displacement
;
1047 DECODE_PRINTF2("%08x[ECX]", displacement
);
1048 return M
.x86
.R_ECX
+ displacement
;
1050 DECODE_PRINTF2("%08x[EDX]", displacement
);
1051 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1052 return M
.x86
.R_EDX
+ displacement
;
1054 DECODE_PRINTF2("%08x[EBX]", displacement
);
1055 return M
.x86
.R_EBX
+ displacement
;
1057 sib
= fetch_byte_imm();
1058 displacement
= (u32
)fetch_long_imm();
1059 DECODE_PRINTF2("%08x", displacement
);
1060 return decode_sib_address(sib
, 2) + displacement
;
1063 DECODE_PRINTF2("%08x[EBP]", displacement
);
1064 return M
.x86
.R_EBP
+ displacement
;
1066 DECODE_PRINTF2("%08x[ESI]", displacement
);
1067 return M
.x86
.R_ESI
+ displacement
;
1069 DECODE_PRINTF2("%08x[EDI]", displacement
);
1070 return M
.x86
.R_EDI
+ displacement
;
1074 /* 16-bit addressing */
1077 DECODE_PRINTF2("%04x[BX+SI]", displacement
);
1078 return (M
.x86
.R_BX
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1080 DECODE_PRINTF2("%04x[BX+DI]", displacement
);
1081 return (M
.x86
.R_BX
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1083 DECODE_PRINTF2("%04x[BP+SI]", displacement
);
1084 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1085 return (M
.x86
.R_BP
+ M
.x86
.R_SI
+ displacement
) & 0xffff;
1087 DECODE_PRINTF2("%04x[BP+DI]", displacement
);
1088 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1089 return (M
.x86
.R_BP
+ M
.x86
.R_DI
+ displacement
) & 0xffff;
1091 DECODE_PRINTF2("%04x[SI]", displacement
);
1092 return (M
.x86
.R_SI
+ displacement
) & 0xffff;
1094 DECODE_PRINTF2("%04x[DI]", displacement
);
1095 return (M
.x86
.R_DI
+ displacement
) & 0xffff;
1097 DECODE_PRINTF2("%04x[BP]", displacement
);
1098 M
.x86
.mode
|= SYSMODE_SEG_DS_SS
;
1099 return (M
.x86
.R_BP
+ displacement
) & 0xffff;
1101 DECODE_PRINTF2("%04x[BX]", displacement
);
1102 return (M
.x86
.R_BX
+ displacement
) & 0xffff;