1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1991-2004 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 #include "x86emu/x86emui.h"
42 /*----------------------------- Implementation ----------------------------*/
44 /****************************************************************************
46 Handles any pending asychronous interrupts.
47 ****************************************************************************/
48 static void x86emu_intr_handle(void)
52 if (M.x86.intr & INTR_SYNCH) {
54 if (_X86EMU_intrTab[intno]) {
55 (*_X86EMU_intrTab[intno])(intno);
57 push_word((u16)M.x86.R_FLG);
60 push_word(M.x86.R_CS);
61 M.x86.R_CS = mem_access_word(intno * 4 + 2);
62 push_word(M.x86.R_IP);
63 M.x86.R_IP = mem_access_word(intno * 4);
69 /****************************************************************************
71 intrnum - Interrupt number to raise
74 Raise the specified interrupt to be handled before the execution of the
76 ****************************************************************************/
77 void x86emu_intr_raise(
80 M.x86.intno = intrnum;
81 M.x86.intr |= INTR_SYNCH;
84 /****************************************************************************
86 Main execution loop for the emulator. We return from here when the system
87 halts, which is normally caused by a stack fault when we return from the
88 original real mode call.
89 ****************************************************************************/
90 void X86EMU_exec(void)
95 DB(x86emu_end_instr();)
98 DB( if (CHECK_IP_FETCH())
99 x86emu_check_ip_access();)
100 /* If debugging, save the IP and CS values. */
101 SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
102 INC_DECODED_INST_LEN(1);
104 if (M.x86.intr & INTR_HALTED) {
105 DB( if (M.x86.R_SP != 0) {
111 printk("Service completed successfully\n");
115 if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
116 !ACCESS_FLAG(F_IF)) {
117 x86emu_intr_handle();
120 op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
121 (*x86emu_optab[op1])(op1);
122 if (M.x86.debug & DEBUG_EXIT) {
123 M.x86.debug &= ~DEBUG_EXIT;
129 /****************************************************************************
131 Halts the system by setting the halted system flag.
132 ****************************************************************************/
133 void X86EMU_halt_sys(void)
135 M.x86.intr |= INTR_HALTED;
138 /****************************************************************************
140 mod - Mod value from decoded byte
141 regh - Reg h value from decoded byte
142 regl - Reg l value from decoded byte
145 Raise the specified interrupt to be handled before the execution of the
148 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
149 ****************************************************************************/
150 void fetch_decode_modrm(
157 DB( if (CHECK_IP_FETCH())
158 x86emu_check_ip_access();)
159 fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
160 INC_DECODED_INST_LEN(1);
161 *mod = (fetched >> 6) & 0x03;
162 *regh = (fetched >> 3) & 0x07;
163 *regl = (fetched >> 0) & 0x07;
166 /****************************************************************************
168 Immediate byte value read from instruction queue
171 This function returns the immediate byte from the instruction queue, and
172 moves the instruction pointer to the next value.
174 NOTE: Do not inline this function, as (*sys_rdb) is already inline!
175 ****************************************************************************/
176 u8 fetch_byte_imm(void)
180 DB( if (CHECK_IP_FETCH())
181 x86emu_check_ip_access();)
182 fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
183 INC_DECODED_INST_LEN(1);
187 /****************************************************************************
189 Immediate word value read from instruction queue
192 This function returns the immediate byte from the instruction queue, and
193 moves the instruction pointer to the next value.
195 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
196 ****************************************************************************/
197 u16 fetch_word_imm(void)
201 DB( if (CHECK_IP_FETCH())
202 x86emu_check_ip_access();)
203 fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
205 INC_DECODED_INST_LEN(2);
209 /****************************************************************************
211 Immediate lone value read from instruction queue
214 This function returns the immediate byte from the instruction queue, and
215 moves the instruction pointer to the next value.
217 NOTE: Do not inline this function, as (*sys_rdw) is already inline!
218 ****************************************************************************/
219 u32 fetch_long_imm(void)
223 DB( if (CHECK_IP_FETCH())
224 x86emu_check_ip_access();)
225 fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
227 INC_DECODED_INST_LEN(4);
231 /****************************************************************************
233 Value of the default data segment
236 Inline function that returns the default data segment for the current
239 On the x86 processor, the default segment is not always DS if there is
240 no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
241 addresses relative to SS (ie: on the stack). So, at the minimum, all
242 decodings of addressing modes would have to set/clear a bit describing
243 whether the access is relative to DS or SS. That is the function of the
244 cpu-state-variable M.x86.mode. There are several potential states:
246 repe prefix seen (handled elsewhere)
247 repne prefix seen (ditto)
256 ds/ss select (in absense of override)
258 Each of the above 7 items are handled with a bit in the mode field.
259 ****************************************************************************/
260 _INLINE u32 get_data_segment(void)
262 #define GET_SEGMENT(segment)
263 switch (M.x86.mode & SYSMODE_SEGMASK) {
264 case 0: /* default case: use ds register */
265 case SYSMODE_SEGOVR_DS:
266 case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
268 case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
270 case SYSMODE_SEGOVR_CS:
271 case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
273 case SYSMODE_SEGOVR_ES:
274 case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
276 case SYSMODE_SEGOVR_FS:
277 case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
279 case SYSMODE_SEGOVR_GS:
280 case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
282 case SYSMODE_SEGOVR_SS:
283 case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
287 printk("error: should not happen: multiple overrides.\n");
294 /****************************************************************************
296 offset - Offset to load data from
299 Byte value read from the absolute memory location.
301 NOTE: Do not inline this function as (*sys_rdX) is already inline!
302 ****************************************************************************/
306 #ifdef CONFIG_X86EMU_DEBUG
307 if (CHECK_DATA_ACCESS())
308 x86emu_check_data_access((u16)get_data_segment(), offset);
310 return (*sys_rdb)((get_data_segment() << 4) + offset);
313 /****************************************************************************
315 offset - Offset to load data from
318 Word value read from the absolute memory location.
320 NOTE: Do not inline this function as (*sys_rdX) is already inline!
321 ****************************************************************************/
325 #ifdef CONFIG_X86EMU_DEBUG
326 if (CHECK_DATA_ACCESS())
327 x86emu_check_data_access((u16)get_data_segment(), offset);
329 return (*sys_rdw)((get_data_segment() << 4) + offset);
332 /****************************************************************************
334 offset - Offset to load data from
337 Long value read from the absolute memory location.
339 NOTE: Do not inline this function as (*sys_rdX) is already inline!
340 ****************************************************************************/
344 #ifdef CONFIG_X86EMU_DEBUG
345 if (CHECK_DATA_ACCESS())
346 x86emu_check_data_access((u16)get_data_segment(), offset);
348 return (*sys_rdl)((get_data_segment() << 4) + offset);
351 /****************************************************************************
353 segment - Segment to load data from
354 offset - Offset to load data from
357 Byte value read from the absolute memory location.
359 NOTE: Do not inline this function as (*sys_rdX) is already inline!
360 ****************************************************************************/
361 u8 fetch_data_byte_abs(
365 #ifdef CONFIG_X86EMU_DEBUG
366 if (CHECK_DATA_ACCESS())
367 x86emu_check_data_access(segment, offset);
369 return (*sys_rdb)(((u32)segment << 4) + offset);
372 /****************************************************************************
374 segment - Segment to load data from
375 offset - Offset to load data from
378 Word value read from the absolute memory location.
380 NOTE: Do not inline this function as (*sys_rdX) is already inline!
381 ****************************************************************************/
382 u16 fetch_data_word_abs(
386 #ifdef CONFIG_X86EMU_DEBUG
387 if (CHECK_DATA_ACCESS())
388 x86emu_check_data_access(segment, offset);
390 return (*sys_rdw)(((u32)segment << 4) + offset);
393 /****************************************************************************
395 segment - Segment to load data from
396 offset - Offset to load data from
399 Long value read from the absolute memory location.
401 NOTE: Do not inline this function as (*sys_rdX) is already inline!
402 ****************************************************************************/
403 u32 fetch_data_long_abs(
407 #ifdef CONFIG_X86EMU_DEBUG
408 if (CHECK_DATA_ACCESS())
409 x86emu_check_data_access(segment, offset);
411 return (*sys_rdl)(((u32)segment << 4) + offset);
414 /****************************************************************************
416 offset - Offset to store data at
420 Writes a word value to an segmented memory location. The segment used is
421 the current 'default' segment, which may have been overridden.
423 NOTE: Do not inline this function as (*sys_wrX) is already inline!
424 ****************************************************************************/
425 void store_data_byte(
429 #ifdef CONFIG_X86EMU_DEBUG
430 if (CHECK_DATA_ACCESS())
431 x86emu_check_data_access((u16)get_data_segment(), offset);
433 (*sys_wrb)((get_data_segment() << 4) + offset, val);
436 /****************************************************************************
438 offset - Offset to store data at
442 Writes a word value to an segmented memory location. The segment used is
443 the current 'default' segment, which may have been overridden.
445 NOTE: Do not inline this function as (*sys_wrX) is already inline!
446 ****************************************************************************/
447 void store_data_word(
451 #ifdef CONFIG_X86EMU_DEBUG
452 if (CHECK_DATA_ACCESS())
453 x86emu_check_data_access((u16)get_data_segment(), offset);
455 (*sys_wrw)((get_data_segment() << 4) + offset, val);
458 /****************************************************************************
460 offset - Offset to store data at
464 Writes a long value to an segmented memory location. The segment used is
465 the current 'default' segment, which may have been overridden.
467 NOTE: Do not inline this function as (*sys_wrX) is already inline!
468 ****************************************************************************/
469 void store_data_long(
473 #ifdef CONFIG_X86EMU_DEBUG
474 if (CHECK_DATA_ACCESS())
475 x86emu_check_data_access((u16)get_data_segment(), offset);
477 (*sys_wrl)((get_data_segment() << 4) + offset, val);
480 /****************************************************************************
482 segment - Segment to store data at
483 offset - Offset to store data at
487 Writes a byte value to an absolute memory location.
489 NOTE: Do not inline this function as (*sys_wrX) is already inline!
490 ****************************************************************************/
491 void store_data_byte_abs(
496 #ifdef CONFIG_X86EMU_DEBUG
497 if (CHECK_DATA_ACCESS())
498 x86emu_check_data_access(segment, offset);
500 (*sys_wrb)(((u32)segment << 4) + offset, val);
503 /****************************************************************************
505 segment - Segment to store data at
506 offset - Offset to store data at
510 Writes a word value to an absolute memory location.
512 NOTE: Do not inline this function as (*sys_wrX) is already inline!
513 ****************************************************************************/
514 void store_data_word_abs(
519 #ifdef CONFIG_X86EMU_DEBUG
520 if (CHECK_DATA_ACCESS())
521 x86emu_check_data_access(segment, offset);
523 (*sys_wrw)(((u32)segment << 4) + offset, val);
526 /****************************************************************************
528 segment - Segment to store data at
529 offset - Offset to store data at
533 Writes a long value to an absolute memory location.
535 NOTE: Do not inline this function as (*sys_wrX) is already inline!
536 ****************************************************************************/
537 void store_data_long_abs(
542 #ifdef CONFIG_X86EMU_DEBUG
543 if (CHECK_DATA_ACCESS())
544 x86emu_check_data_access(segment, offset);
546 (*sys_wrl)(((u32)segment << 4) + offset, val);
549 /****************************************************************************
551 reg - Register to decode
554 Pointer to the appropriate register
557 Return a pointer to the register given by the R/RM field of the
558 modrm byte, for byte operands. Also enables the decoding of instructions.
559 ****************************************************************************/
560 u8* decode_rm_byte_register(
590 return NULL; /* NOT REACHED OR REACHED ON ERROR */
593 /****************************************************************************
595 reg - Register to decode
598 Pointer to the appropriate register
601 Return a pointer to the register given by the R/RM field of the
602 modrm byte, for word operands. Also enables the decoding of instructions.
603 ****************************************************************************/
604 u16* decode_rm_word_register(
634 return NULL; /* NOTREACHED OR REACHED ON ERROR */
637 /****************************************************************************
639 reg - Register to decode
642 Pointer to the appropriate register
645 Return a pointer to the register given by the R/RM field of the
646 modrm byte, for dword operands. Also enables the decoding of instructions.
647 ****************************************************************************/
648 u32* decode_rm_long_register(
653 DECODE_PRINTF("EAX");
656 DECODE_PRINTF("ECX");
659 DECODE_PRINTF("EDX");
662 DECODE_PRINTF("EBX");
665 DECODE_PRINTF("ESP");
668 DECODE_PRINTF("EBP");
671 DECODE_PRINTF("ESI");
674 DECODE_PRINTF("EDI");
678 return NULL; /* NOTREACHED OR REACHED ON ERROR */
681 /****************************************************************************
683 reg - Register to decode
686 Pointer to the appropriate register
689 Return a pointer to the register given by the R/RM field of the
690 modrm byte, for word operands, modified from above for the weirdo
691 special case of segreg operands. Also enables the decoding of instructions.
692 ****************************************************************************/
693 u16* decode_rm_seg_register(
717 DECODE_PRINTF("ILLEGAL SEGREG");
721 return NULL; /* NOT REACHED OR REACHED ON ERROR */
724 /****************************************************************************
726 scale - scale value of SIB byte
727 index - index value of SIB byte
730 Value of scale * index
733 Decodes scale/index of SIB byte and returns relevant offset part of
735 ****************************************************************************/
736 unsigned decode_sib_si(
742 DECODE_PRINTF2("[%d*", scale);
748 DECODE_PRINTF("EAX]");
749 return M.x86.R_EAX * index;
751 DECODE_PRINTF("ECX]");
752 return M.x86.R_ECX * index;
754 DECODE_PRINTF("EDX]");
755 return M.x86.R_EDX * index;
757 DECODE_PRINTF("EBX]");
758 return M.x86.R_EBX * index;
763 DECODE_PRINTF("EBP]");
764 return M.x86.R_EBP * index;
766 DECODE_PRINTF("ESI]");
767 return M.x86.R_ESI * index;
769 DECODE_PRINTF("EDI]");
770 return M.x86.R_EDI * index;
773 return 0; /* NOT REACHED OR REACHED ON ERROR */
776 /****************************************************************************
778 mod - MOD value of preceding ModR/M byte
781 Offset in memory for the address decoding
784 Decodes SIB addressing byte and returns calculated effective address.
785 ****************************************************************************/
786 unsigned decode_sib_address(
789 int sib = fetch_byte_imm();
790 int ss = (sib >> 6) & 0x03;
791 int index = (sib >> 3) & 0x07;
792 int base = sib & 0x07;
798 DECODE_PRINTF("[EAX]");
799 offset = M.x86.R_EAX;
802 DECODE_PRINTF("[ECX]");
803 offset = M.x86.R_ECX;
806 DECODE_PRINTF("[EDX]");
807 offset = M.x86.R_EDX;
810 DECODE_PRINTF("[EBX]");
811 offset = M.x86.R_EBX;
814 DECODE_PRINTF("[ESP]");
815 offset = M.x86.R_ESP;
820 displacement = (s32)fetch_long_imm();
821 DECODE_PRINTF2("[%d]", displacement);
822 offset = displacement;
825 displacement = (s8)fetch_byte_imm();
826 DECODE_PRINTF2("[%d][EBP]", displacement);
827 offset = M.x86.R_EBP + displacement;
830 displacement = (s32)fetch_long_imm();
831 DECODE_PRINTF2("[%d][EBP]", displacement);
832 offset = M.x86.R_EBP + displacement;
837 DECODE_PRINTF("[EAX]");
838 offset = M.x86.R_EAX;
841 DECODE_PRINTF("[ESI]");
842 offset = M.x86.R_ESI;
845 DECODE_PRINTF("[EDI]");
846 offset = M.x86.R_EDI;
851 offset += decode_sib_si(ss, index);
856 /****************************************************************************
858 rm - RM value to decode
861 Offset in memory for the address decoding
864 Return the offset given by mod=00 addressing. Also enables the
865 decoding of instructions.
867 NOTE: The code which specifies the corresponding segment (ds vs ss)
868 below in the case of [BP+..]. The assumption here is that at the
869 point that this subroutine is called, the bit corresponding to
870 SYSMODE_SEG_DS_SS will be zero. After every instruction
871 except the segment override instructions, this bit (as well
872 as any bits indicating segment overrides) will be clear. So
873 if a SS access is needed, set this bit. Otherwise, DS access
874 occurs (unless any of the segment override bits are set).
875 ****************************************************************************/
876 unsigned decode_rm00_address(
881 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
882 /* 32-bit addressing */
885 DECODE_PRINTF("[EAX]");
888 DECODE_PRINTF("[ECX]");
891 DECODE_PRINTF("[EDX]");
894 DECODE_PRINTF("[EBX]");
897 return decode_sib_address(0);
899 offset = fetch_long_imm();
900 DECODE_PRINTF2("[%08x]", offset);
903 DECODE_PRINTF("[ESI]");
906 DECODE_PRINTF("[EDI]");
910 /* 16-bit addressing */
913 DECODE_PRINTF("[BX+SI]");
914 return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
916 DECODE_PRINTF("[BX+DI]");
917 return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
919 DECODE_PRINTF("[BP+SI]");
920 M.x86.mode |= SYSMODE_SEG_DS_SS;
921 return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
923 DECODE_PRINTF("[BP+DI]");
924 M.x86.mode |= SYSMODE_SEG_DS_SS;
925 return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
927 DECODE_PRINTF("[SI]");
930 DECODE_PRINTF("[DI]");
933 offset = fetch_word_imm();
934 DECODE_PRINTF2("[%04x]", offset);
937 DECODE_PRINTF("[BX]");
945 /****************************************************************************
947 rm - RM value to decode
950 Offset in memory for the address decoding
953 Return the offset given by mod=01 addressing. Also enables the
954 decoding of instructions.
955 ****************************************************************************/
956 unsigned decode_rm01_address(
961 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
962 /* 32-bit addressing */
964 displacement = (s8)fetch_byte_imm();
970 DECODE_PRINTF2("%d[EAX]", displacement);
971 return M.x86.R_EAX + displacement;
973 DECODE_PRINTF2("%d[ECX]", displacement);
974 return M.x86.R_ECX + displacement;
976 DECODE_PRINTF2("%d[EDX]", displacement);
977 return M.x86.R_EDX + displacement;
979 DECODE_PRINTF2("%d[EBX]", displacement);
980 return M.x86.R_EBX + displacement;
982 int offset = decode_sib_address(1);
983 displacement = (s8)fetch_byte_imm();
984 DECODE_PRINTF2("[%d]", displacement);
985 return offset + displacement;
988 DECODE_PRINTF2("%d[EBP]", displacement);
989 return M.x86.R_EBP + displacement;
991 DECODE_PRINTF2("%d[ESI]", displacement);
992 return M.x86.R_ESI + displacement;
994 DECODE_PRINTF2("%d[EDI]", displacement);
995 return M.x86.R_EDI + displacement;
998 /* 16-bit addressing */
999 displacement = (s8)fetch_byte_imm();
1002 DECODE_PRINTF2("%d[BX+SI]", displacement);
1003 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1005 DECODE_PRINTF2("%d[BX+DI]", displacement);
1006 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1008 DECODE_PRINTF2("%d[BP+SI]", displacement);
1009 M.x86.mode |= SYSMODE_SEG_DS_SS;
1010 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1012 DECODE_PRINTF2("%d[BP+DI]", displacement);
1013 M.x86.mode |= SYSMODE_SEG_DS_SS;
1014 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1016 DECODE_PRINTF2("%d[SI]", displacement);
1017 return (M.x86.R_SI + displacement) & 0xffff;
1019 DECODE_PRINTF2("%d[DI]", displacement);
1020 return (M.x86.R_DI + displacement) & 0xffff;
1022 DECODE_PRINTF2("%d[BP]", displacement);
1023 M.x86.mode |= SYSMODE_SEG_DS_SS;
1024 return (M.x86.R_BP + displacement) & 0xffff;
1026 DECODE_PRINTF2("%d[BX]", displacement);
1027 return (M.x86.R_BX + displacement) & 0xffff;
1031 return 0; /* SHOULD NOT HAPPEN */
1034 /****************************************************************************
1036 rm - RM value to decode
1039 Offset in memory for the address decoding
1042 Return the offset given by mod=10 addressing. Also enables the
1043 decoding of instructions.
1044 ****************************************************************************/
1045 unsigned decode_rm10_address(
1048 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
1051 /* 32-bit addressing */
1053 displacement = (s32)fetch_long_imm();
1059 DECODE_PRINTF2("%d[EAX]", displacement);
1060 return M.x86.R_EAX + displacement;
1062 DECODE_PRINTF2("%d[ECX]", displacement);
1063 return M.x86.R_ECX + displacement;
1065 DECODE_PRINTF2("%d[EDX]", displacement);
1066 return M.x86.R_EDX + displacement;
1068 DECODE_PRINTF2("%d[EBX]", displacement);
1069 return M.x86.R_EBX + displacement;
1071 int offset = decode_sib_address(2);
1072 displacement = (s32)fetch_long_imm();
1073 DECODE_PRINTF2("[%d]", displacement);
1074 return offset + displacement;
1077 DECODE_PRINTF2("%d[EBP]", displacement);
1078 return M.x86.R_EBP + displacement;
1080 DECODE_PRINTF2("%d[ESI]", displacement);
1081 return M.x86.R_ESI + displacement;
1083 DECODE_PRINTF2("%d[EDI]", displacement);
1084 return M.x86.R_EDI + displacement;
1087 int displacement = (s16)fetch_word_imm();
1089 /* 16-bit addressing */
1092 DECODE_PRINTF2("%d[BX+SI]", displacement);
1093 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1095 DECODE_PRINTF2("%d[BX+DI]", displacement);
1096 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1098 DECODE_PRINTF2("%d[BP+SI]", displacement);
1099 M.x86.mode |= SYSMODE_SEG_DS_SS;
1100 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1102 DECODE_PRINTF2("%d[BP+DI]", displacement);
1103 M.x86.mode |= SYSMODE_SEG_DS_SS;
1104 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1106 DECODE_PRINTF2("%d[SI]", displacement);
1107 return (M.x86.R_SI + displacement) & 0xffff;
1109 DECODE_PRINTF2("%d[DI]", displacement);
1110 return (M.x86.R_DI + displacement) & 0xffff;
1112 DECODE_PRINTF2("%d[BP]", displacement);
1113 M.x86.mode |= SYSMODE_SEG_DS_SS;
1114 return (M.x86.R_BP + displacement) & 0xffff;
1116 DECODE_PRINTF2("%d[BX]", displacement);
1117 return (M.x86.R_BX + displacement) & 0xffff;
1121 return 0; /* SHOULD NOT HAPPEN */
1124 /****************************************************************************
1127 rm - RM value to decode
1130 Offset in memory for the address decoding, multiplexing calls to
1131 the decode_rmXX_address functions
1134 Return the offset given by "mod" addressing.
1135 ****************************************************************************/
1137 unsigned decode_rmXX_address(int mod, int rm)
1140 return decode_rm00_address(rm);
1142 return decode_rm01_address(rm);
1143 return decode_rm10_address(rm);