x86emu.c revision 1.11 1 1.11 msaitoh /* $NetBSD: x86emu.c,v 1.11 2021/12/05 03:24:19 msaitoh Exp $ */
2 1.1 joerg
3 1.1 joerg /****************************************************************************
4 1.1 joerg *
5 1.1 joerg * Realmode X86 Emulator Library
6 1.1 joerg *
7 1.1 joerg * Copyright (C) 1996-1999 SciTech Software, Inc.
8 1.1 joerg * Copyright (C) David Mosberger-Tang
9 1.1 joerg * Copyright (C) 1999 Egbert Eich
10 1.1 joerg * Copyright (C) 2007 Joerg Sonnenberger
11 1.1 joerg *
12 1.1 joerg * ========================================================================
13 1.1 joerg *
14 1.1 joerg * Permission to use, copy, modify, distribute, and sell this software and
15 1.1 joerg * its documentation for any purpose is hereby granted without fee,
16 1.1 joerg * provided that the above copyright notice appear in all copies and that
17 1.1 joerg * both that copyright notice and this permission notice appear in
18 1.1 joerg * supporting documentation, and that the name of the authors not be used
19 1.1 joerg * in advertising or publicity pertaining to distribution of the software
20 1.1 joerg * without specific, written prior permission. The authors makes no
21 1.1 joerg * representations about the suitability of this software for any purpose.
22 1.1 joerg * It is provided "as is" without express or implied warranty.
23 1.1 joerg *
24 1.1 joerg * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25 1.1 joerg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26 1.1 joerg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27 1.1 joerg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28 1.1 joerg * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29 1.1 joerg * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30 1.1 joerg * PERFORMANCE OF THIS SOFTWARE.
31 1.1 joerg *
32 1.1 joerg ****************************************************************************/
33 1.1 joerg
34 1.1 joerg #ifndef _KERNEL
35 1.1 joerg #include <stdbool.h>
36 1.1 joerg #endif
37 1.1 joerg
38 1.2 joerg #include <x86emu/x86emu.h>
39 1.2 joerg #include <x86emu/x86emu_regs.h>
40 1.1 joerg
41 1.1 joerg static void x86emu_intr_raise (struct X86EMU *, uint8_t type);
42 1.1 joerg
43 1.1 joerg static void X86EMU_exec_one_byte(struct X86EMU *);
44 1.1 joerg static void X86EMU_exec_two_byte(struct X86EMU *);
45 1.1 joerg
46 1.1 joerg static void fetch_decode_modrm (struct X86EMU *);
47 1.1 joerg static uint8_t fetch_byte_imm (struct X86EMU *);
48 1.1 joerg static uint16_t fetch_word_imm (struct X86EMU *);
49 1.1 joerg static uint32_t fetch_long_imm (struct X86EMU *);
50 1.1 joerg static uint8_t fetch_data_byte (struct X86EMU *, uint32_t offset);
51 1.1 joerg static uint8_t fetch_byte (struct X86EMU *, uint segment, uint32_t offset);
52 1.1 joerg static uint16_t fetch_data_word (struct X86EMU *, uint32_t offset);
53 1.1 joerg static uint16_t fetch_word (struct X86EMU *, uint32_t segment, uint32_t offset);
54 1.1 joerg static uint32_t fetch_data_long (struct X86EMU *, uint32_t offset);
55 1.1 joerg static uint32_t fetch_long (struct X86EMU *, uint32_t segment, uint32_t offset);
56 1.1 joerg static void store_data_byte (struct X86EMU *, uint32_t offset, uint8_t val);
57 1.1 joerg static void store_byte (struct X86EMU *, uint32_t segment, uint32_t offset, uint8_t val);
58 1.1 joerg static void store_data_word (struct X86EMU *, uint32_t offset, uint16_t val);
59 1.1 joerg static void store_word (struct X86EMU *, uint32_t segment, uint32_t offset, uint16_t val);
60 1.1 joerg static void store_data_long (struct X86EMU *, uint32_t offset, uint32_t val);
61 1.1 joerg static void store_long (struct X86EMU *, uint32_t segment, uint32_t offset, uint32_t val);
62 1.1 joerg static uint8_t* decode_rl_byte_register(struct X86EMU *);
63 1.1 joerg static uint16_t* decode_rl_word_register(struct X86EMU *);
64 1.1 joerg static uint32_t* decode_rl_long_register(struct X86EMU *);
65 1.1 joerg static uint8_t* decode_rh_byte_register(struct X86EMU *);
66 1.1 joerg static uint16_t* decode_rh_word_register(struct X86EMU *);
67 1.1 joerg static uint32_t* decode_rh_long_register(struct X86EMU *);
68 1.1 joerg static uint16_t* decode_rh_seg_register(struct X86EMU *);
69 1.1 joerg static uint32_t decode_rl_address(struct X86EMU *);
70 1.1 joerg
71 1.1 joerg static uint8_t decode_and_fetch_byte(struct X86EMU *);
72 1.1 joerg static uint16_t decode_and_fetch_word(struct X86EMU *);
73 1.1 joerg static uint32_t decode_and_fetch_long(struct X86EMU *);
74 1.1 joerg
75 1.1 joerg static uint8_t decode_and_fetch_byte_imm8(struct X86EMU *, uint8_t *);
76 1.1 joerg static uint16_t decode_and_fetch_word_imm8(struct X86EMU *, uint8_t *);
77 1.1 joerg static uint32_t decode_and_fetch_long_imm8(struct X86EMU *, uint8_t *);
78 1.1 joerg
79 1.1 joerg static uint16_t decode_and_fetch_word_disp(struct X86EMU *, int16_t);
80 1.1 joerg static uint32_t decode_and_fetch_long_disp(struct X86EMU *, int16_t);
81 1.1 joerg
82 1.1 joerg static void write_back_byte(struct X86EMU *, uint8_t);
83 1.1 joerg static void write_back_word(struct X86EMU *, uint16_t);
84 1.1 joerg static void write_back_long(struct X86EMU *, uint32_t);
85 1.1 joerg
86 1.1 joerg static uint16_t aaa_word (struct X86EMU *, uint16_t d);
87 1.1 joerg static uint16_t aas_word (struct X86EMU *, uint16_t d);
88 1.1 joerg static uint16_t aad_word (struct X86EMU *, uint16_t d);
89 1.1 joerg static uint16_t aam_word (struct X86EMU *, uint8_t d);
90 1.1 joerg static uint8_t adc_byte (struct X86EMU *, uint8_t d, uint8_t s);
91 1.1 joerg static uint16_t adc_word (struct X86EMU *, uint16_t d, uint16_t s);
92 1.1 joerg static uint32_t adc_long (struct X86EMU *, uint32_t d, uint32_t s);
93 1.1 joerg static uint8_t add_byte (struct X86EMU *, uint8_t d, uint8_t s);
94 1.1 joerg static uint16_t add_word (struct X86EMU *, uint16_t d, uint16_t s);
95 1.1 joerg static uint32_t add_long (struct X86EMU *, uint32_t d, uint32_t s);
96 1.1 joerg static uint8_t and_byte (struct X86EMU *, uint8_t d, uint8_t s);
97 1.1 joerg static uint16_t and_word (struct X86EMU *, uint16_t d, uint16_t s);
98 1.1 joerg static uint32_t and_long (struct X86EMU *, uint32_t d, uint32_t s);
99 1.1 joerg static uint8_t cmp_byte (struct X86EMU *, uint8_t d, uint8_t s);
100 1.1 joerg static uint16_t cmp_word (struct X86EMU *, uint16_t d, uint16_t s);
101 1.1 joerg static uint32_t cmp_long (struct X86EMU *, uint32_t d, uint32_t s);
102 1.1 joerg static void cmp_byte_no_return (struct X86EMU *, uint8_t d, uint8_t s);
103 1.1 joerg static void cmp_word_no_return (struct X86EMU *, uint16_t d, uint16_t s);
104 1.1 joerg static void cmp_long_no_return (struct X86EMU *, uint32_t d, uint32_t s);
105 1.1 joerg static uint8_t daa_byte (struct X86EMU *, uint8_t d);
106 1.1 joerg static uint8_t das_byte (struct X86EMU *, uint8_t d);
107 1.1 joerg static uint8_t dec_byte (struct X86EMU *, uint8_t d);
108 1.1 joerg static uint16_t dec_word (struct X86EMU *, uint16_t d);
109 1.1 joerg static uint32_t dec_long (struct X86EMU *, uint32_t d);
110 1.1 joerg static uint8_t inc_byte (struct X86EMU *, uint8_t d);
111 1.1 joerg static uint16_t inc_word (struct X86EMU *, uint16_t d);
112 1.1 joerg static uint32_t inc_long (struct X86EMU *, uint32_t d);
113 1.1 joerg static uint8_t or_byte (struct X86EMU *, uint8_t d, uint8_t s);
114 1.1 joerg static uint16_t or_word (struct X86EMU *, uint16_t d, uint16_t s);
115 1.1 joerg static uint32_t or_long (struct X86EMU *, uint32_t d, uint32_t s);
116 1.1 joerg static uint8_t neg_byte (struct X86EMU *, uint8_t s);
117 1.1 joerg static uint16_t neg_word (struct X86EMU *, uint16_t s);
118 1.1 joerg static uint32_t neg_long (struct X86EMU *, uint32_t s);
119 1.1 joerg static uint8_t rcl_byte (struct X86EMU *, uint8_t d, uint8_t s);
120 1.1 joerg static uint16_t rcl_word (struct X86EMU *, uint16_t d, uint8_t s);
121 1.1 joerg static uint32_t rcl_long (struct X86EMU *, uint32_t d, uint8_t s);
122 1.1 joerg static uint8_t rcr_byte (struct X86EMU *, uint8_t d, uint8_t s);
123 1.1 joerg static uint16_t rcr_word (struct X86EMU *, uint16_t d, uint8_t s);
124 1.1 joerg static uint32_t rcr_long (struct X86EMU *, uint32_t d, uint8_t s);
125 1.1 joerg static uint8_t rol_byte (struct X86EMU *, uint8_t d, uint8_t s);
126 1.1 joerg static uint16_t rol_word (struct X86EMU *, uint16_t d, uint8_t s);
127 1.1 joerg static uint32_t rol_long (struct X86EMU *, uint32_t d, uint8_t s);
128 1.1 joerg static uint8_t ror_byte (struct X86EMU *, uint8_t d, uint8_t s);
129 1.1 joerg static uint16_t ror_word (struct X86EMU *, uint16_t d, uint8_t s);
130 1.1 joerg static uint32_t ror_long (struct X86EMU *, uint32_t d, uint8_t s);
131 1.1 joerg static uint8_t shl_byte (struct X86EMU *, uint8_t d, uint8_t s);
132 1.1 joerg static uint16_t shl_word (struct X86EMU *, uint16_t d, uint8_t s);
133 1.1 joerg static uint32_t shl_long (struct X86EMU *, uint32_t d, uint8_t s);
134 1.1 joerg static uint8_t shr_byte (struct X86EMU *, uint8_t d, uint8_t s);
135 1.1 joerg static uint16_t shr_word (struct X86EMU *, uint16_t d, uint8_t s);
136 1.1 joerg static uint32_t shr_long (struct X86EMU *, uint32_t d, uint8_t s);
137 1.1 joerg static uint8_t sar_byte (struct X86EMU *, uint8_t d, uint8_t s);
138 1.1 joerg static uint16_t sar_word (struct X86EMU *, uint16_t d, uint8_t s);
139 1.1 joerg static uint32_t sar_long (struct X86EMU *, uint32_t d, uint8_t s);
140 1.1 joerg static uint16_t shld_word (struct X86EMU *, uint16_t d, uint16_t fill, uint8_t s);
141 1.1 joerg static uint32_t shld_long (struct X86EMU *, uint32_t d, uint32_t fill, uint8_t s);
142 1.1 joerg static uint16_t shrd_word (struct X86EMU *, uint16_t d, uint16_t fill, uint8_t s);
143 1.1 joerg static uint32_t shrd_long (struct X86EMU *, uint32_t d, uint32_t fill, uint8_t s);
144 1.1 joerg static uint8_t sbb_byte (struct X86EMU *, uint8_t d, uint8_t s);
145 1.1 joerg static uint16_t sbb_word (struct X86EMU *, uint16_t d, uint16_t s);
146 1.1 joerg static uint32_t sbb_long (struct X86EMU *, uint32_t d, uint32_t s);
147 1.1 joerg static uint8_t sub_byte (struct X86EMU *, uint8_t d, uint8_t s);
148 1.1 joerg static uint16_t sub_word (struct X86EMU *, uint16_t d, uint16_t s);
149 1.1 joerg static uint32_t sub_long (struct X86EMU *, uint32_t d, uint32_t s);
150 1.1 joerg static void test_byte (struct X86EMU *, uint8_t d, uint8_t s);
151 1.1 joerg static void test_word (struct X86EMU *, uint16_t d, uint16_t s);
152 1.1 joerg static void test_long (struct X86EMU *, uint32_t d, uint32_t s);
153 1.1 joerg static uint8_t xor_byte (struct X86EMU *, uint8_t d, uint8_t s);
154 1.1 joerg static uint16_t xor_word (struct X86EMU *, uint16_t d, uint16_t s);
155 1.1 joerg static uint32_t xor_long (struct X86EMU *, uint32_t d, uint32_t s);
156 1.1 joerg static void imul_byte (struct X86EMU *, uint8_t s);
157 1.1 joerg static void imul_word (struct X86EMU *, uint16_t s);
158 1.1 joerg static void imul_long (struct X86EMU *, uint32_t s);
159 1.1 joerg static void mul_byte (struct X86EMU *, uint8_t s);
160 1.1 joerg static void mul_word (struct X86EMU *, uint16_t s);
161 1.1 joerg static void mul_long (struct X86EMU *, uint32_t s);
162 1.1 joerg static void idiv_byte (struct X86EMU *, uint8_t s);
163 1.1 joerg static void idiv_word (struct X86EMU *, uint16_t s);
164 1.1 joerg static void idiv_long (struct X86EMU *, uint32_t s);
165 1.1 joerg static void div_byte (struct X86EMU *, uint8_t s);
166 1.1 joerg static void div_word (struct X86EMU *, uint16_t s);
167 1.1 joerg static void div_long (struct X86EMU *, uint32_t s);
168 1.1 joerg static void ins (struct X86EMU *, int size);
169 1.1 joerg static void outs (struct X86EMU *, int size);
170 1.1 joerg static void push_word (struct X86EMU *, uint16_t w);
171 1.1 joerg static void push_long (struct X86EMU *, uint32_t w);
172 1.1 joerg static uint16_t pop_word (struct X86EMU *);
173 1.1 joerg static uint32_t pop_long (struct X86EMU *);
174 1.1 joerg
175 1.1 joerg /****************************************************************************
176 1.1 joerg REMARKS:
177 1.1 joerg Handles any pending asychronous interrupts.
178 1.1 joerg ****************************************************************************/
179 1.3 joerg static void
180 1.3 joerg x86emu_intr_dispatch(struct X86EMU *emu, uint8_t intno)
181 1.3 joerg {
182 1.3 joerg if (emu->_X86EMU_intrTab[intno]) {
183 1.3 joerg (*emu->_X86EMU_intrTab[intno]) (emu, intno);
184 1.3 joerg } else {
185 1.3 joerg push_word(emu, (uint16_t) emu->x86.R_FLG);
186 1.3 joerg CLEAR_FLAG(F_IF);
187 1.3 joerg CLEAR_FLAG(F_TF);
188 1.3 joerg push_word(emu, emu->x86.R_CS);
189 1.3 joerg emu->x86.R_CS = fetch_word(emu, 0, intno * 4 + 2);
190 1.3 joerg push_word(emu, emu->x86.R_IP);
191 1.3 joerg emu->x86.R_IP = fetch_word(emu, 0, intno * 4);
192 1.3 joerg }
193 1.3 joerg }
194 1.3 joerg
195 1.1 joerg static void
196 1.1 joerg x86emu_intr_handle(struct X86EMU *emu)
197 1.1 joerg {
198 1.1 joerg uint8_t intno;
199 1.1 joerg
200 1.1 joerg if (emu->x86.intr & INTR_SYNCH) {
201 1.1 joerg intno = emu->x86.intno;
202 1.3 joerg emu->x86.intr = 0;
203 1.3 joerg x86emu_intr_dispatch(emu, intno);
204 1.1 joerg }
205 1.1 joerg }
206 1.1 joerg /****************************************************************************
207 1.1 joerg PARAMETERS:
208 1.1 joerg intrnum - Interrupt number to raise
209 1.1 joerg
210 1.1 joerg REMARKS:
211 1.1 joerg Raise the specified interrupt to be handled before the execution of the
212 1.1 joerg next instruction.
213 1.1 joerg ****************************************************************************/
214 1.1 joerg void
215 1.1 joerg x86emu_intr_raise(struct X86EMU *emu, uint8_t intrnum)
216 1.1 joerg {
217 1.1 joerg emu->x86.intno = intrnum;
218 1.1 joerg emu->x86.intr |= INTR_SYNCH;
219 1.1 joerg }
220 1.1 joerg /****************************************************************************
221 1.1 joerg REMARKS:
222 1.1 joerg Main execution loop for the emulator. We return from here when the system
223 1.1 joerg halts, which is normally caused by a stack fault when we return from the
224 1.1 joerg original real mode call.
225 1.1 joerg ****************************************************************************/
226 1.1 joerg void
227 1.1 joerg X86EMU_exec(struct X86EMU *emu)
228 1.1 joerg {
229 1.1 joerg emu->x86.intr = 0;
230 1.1 joerg
231 1.1 joerg #ifdef _KERNEL
232 1.1 joerg if (setjmp(&emu->exec_state))
233 1.1 joerg return;
234 1.1 joerg #else
235 1.1 joerg if (setjmp(emu->exec_state))
236 1.1 joerg return;
237 1.1 joerg #endif
238 1.1 joerg
239 1.1 joerg for (;;) {
240 1.1 joerg if (emu->x86.intr) {
241 1.1 joerg if (((emu->x86.intr & INTR_SYNCH) && (emu->x86.intno == 0 || emu->x86.intno == 2)) ||
242 1.1 joerg !ACCESS_FLAG(F_IF)) {
243 1.1 joerg x86emu_intr_handle(emu);
244 1.1 joerg }
245 1.1 joerg }
246 1.7 joerg if (emu->x86.R_CS == 0 && emu->x86.R_IP == 0)
247 1.7 joerg return;
248 1.1 joerg X86EMU_exec_one_byte(emu);
249 1.1 joerg ++emu->cur_cycles;
250 1.1 joerg }
251 1.1 joerg }
252 1.1 joerg
253 1.1 joerg void
254 1.1 joerg X86EMU_exec_call(struct X86EMU *emu, uint16_t seg, uint16_t off)
255 1.1 joerg {
256 1.1 joerg push_word(emu, 0);
257 1.1 joerg push_word(emu, 0);
258 1.1 joerg emu->x86.R_CS = seg;
259 1.1 joerg emu->x86.R_IP = off;
260 1.1 joerg
261 1.1 joerg X86EMU_exec(emu);
262 1.1 joerg }
263 1.1 joerg
264 1.1 joerg void
265 1.1 joerg X86EMU_exec_intr(struct X86EMU *emu, uint8_t intr)
266 1.1 joerg {
267 1.1 joerg push_word(emu, emu->x86.R_FLG);
268 1.1 joerg CLEAR_FLAG(F_IF);
269 1.1 joerg CLEAR_FLAG(F_TF);
270 1.1 joerg push_word(emu, 0);
271 1.1 joerg push_word(emu, 0);
272 1.1 joerg emu->x86.R_CS = (*emu->emu_rdw)(emu, intr * 4 + 2);
273 1.1 joerg emu->x86.R_IP = (*emu->emu_rdw)(emu, intr * 4);
274 1.1 joerg emu->x86.intr = 0;
275 1.1 joerg
276 1.1 joerg X86EMU_exec(emu);
277 1.1 joerg }
278 1.1 joerg /****************************************************************************
279 1.1 joerg REMARKS:
280 1.1 joerg Halts the system by setting the halted system flag.
281 1.1 joerg ****************************************************************************/
282 1.1 joerg void
283 1.1 joerg X86EMU_halt_sys(struct X86EMU *emu)
284 1.1 joerg {
285 1.1 joerg #ifdef _KERNEL
286 1.1 joerg longjmp(&emu->exec_state);
287 1.1 joerg #else
288 1.1 joerg longjmp(emu->exec_state, 1);
289 1.1 joerg #endif
290 1.1 joerg }
291 1.1 joerg /****************************************************************************
292 1.1 joerg PARAMETERS:
293 1.1 joerg mod - Mod value from decoded byte
294 1.1 joerg regh - Reg h value from decoded byte
295 1.1 joerg regl - Reg l value from decoded byte
296 1.1 joerg
297 1.1 joerg REMARKS:
298 1.1 joerg Raise the specified interrupt to be handled before the execution of the
299 1.1 joerg next instruction.
300 1.1 joerg
301 1.1 joerg NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
302 1.1 joerg ****************************************************************************/
303 1.1 joerg static void
304 1.1 joerg fetch_decode_modrm(struct X86EMU *emu)
305 1.1 joerg {
306 1.1 joerg int fetched;
307 1.1 joerg
308 1.1 joerg fetched = fetch_byte_imm(emu);
309 1.1 joerg emu->cur_mod = (fetched >> 6) & 0x03;
310 1.1 joerg emu->cur_rh = (fetched >> 3) & 0x07;
311 1.1 joerg emu->cur_rl = (fetched >> 0) & 0x07;
312 1.1 joerg }
313 1.1 joerg /****************************************************************************
314 1.1 joerg RETURNS:
315 1.1 joerg Immediate byte value read from instruction queue
316 1.1 joerg
317 1.1 joerg REMARKS:
318 1.1 joerg This function returns the immediate byte from the instruction queue, and
319 1.1 joerg moves the instruction pointer to the next value.
320 1.1 joerg
321 1.1 joerg NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
322 1.1 joerg ****************************************************************************/
323 1.1 joerg static uint8_t
324 1.1 joerg fetch_byte_imm(struct X86EMU *emu)
325 1.1 joerg {
326 1.1 joerg uint8_t fetched;
327 1.1 joerg
328 1.1 joerg fetched = fetch_byte(emu, emu->x86.R_CS, emu->x86.R_IP);
329 1.1 joerg emu->x86.R_IP++;
330 1.1 joerg return fetched;
331 1.1 joerg }
332 1.1 joerg /****************************************************************************
333 1.1 joerg RETURNS:
334 1.1 joerg Immediate word value read from instruction queue
335 1.1 joerg
336 1.1 joerg REMARKS:
337 1.1 joerg This function returns the immediate byte from the instruction queue, and
338 1.1 joerg moves the instruction pointer to the next value.
339 1.1 joerg
340 1.1 joerg NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
341 1.1 joerg ****************************************************************************/
342 1.1 joerg static uint16_t
343 1.1 joerg fetch_word_imm(struct X86EMU *emu)
344 1.1 joerg {
345 1.1 joerg uint16_t fetched;
346 1.1 joerg
347 1.1 joerg fetched = fetch_word(emu, emu->x86.R_CS, emu->x86.R_IP);
348 1.1 joerg emu->x86.R_IP += 2;
349 1.1 joerg return fetched;
350 1.1 joerg }
351 1.1 joerg /****************************************************************************
352 1.1 joerg RETURNS:
353 1.1 joerg Immediate lone value read from instruction queue
354 1.1 joerg
355 1.1 joerg REMARKS:
356 1.1 joerg This function returns the immediate byte from the instruction queue, and
357 1.1 joerg moves the instruction pointer to the next value.
358 1.1 joerg
359 1.1 joerg NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
360 1.1 joerg ****************************************************************************/
361 1.1 joerg static uint32_t
362 1.1 joerg fetch_long_imm(struct X86EMU *emu)
363 1.1 joerg {
364 1.1 joerg uint32_t fetched;
365 1.1 joerg
366 1.1 joerg fetched = fetch_long(emu, emu->x86.R_CS, emu->x86.R_IP);
367 1.1 joerg emu->x86.R_IP += 4;
368 1.1 joerg return fetched;
369 1.1 joerg }
370 1.1 joerg /****************************************************************************
371 1.1 joerg RETURNS:
372 1.1 joerg Value of the default data segment
373 1.1 joerg
374 1.1 joerg REMARKS:
375 1.1 joerg Inline function that returns the default data segment for the current
376 1.1 joerg instruction.
377 1.1 joerg
378 1.1 joerg On the x86 processor, the default segment is not always DS if there is
379 1.1 joerg no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
380 1.1 joerg addresses relative to SS (ie: on the stack). So, at the minimum, all
381 1.1 joerg decodings of addressing modes would have to set/clear a bit describing
382 1.1 joerg whether the access is relative to DS or SS. That is the function of the
383 1.1 joerg cpu-state-varible emu->x86.mode. There are several potential states:
384 1.1 joerg
385 1.1 joerg repe prefix seen (handled elsewhere)
386 1.1 joerg repne prefix seen (ditto)
387 1.1 joerg
388 1.1 joerg cs segment override
389 1.1 joerg ds segment override
390 1.1 joerg es segment override
391 1.1 joerg fs segment override
392 1.1 joerg gs segment override
393 1.1 joerg ss segment override
394 1.1 joerg
395 1.11 msaitoh ds/ss select (in absence of override)
396 1.1 joerg
397 1.1 joerg Each of the above 7 items are handled with a bit in the mode field.
398 1.1 joerg ****************************************************************************/
399 1.1 joerg static uint32_t
400 1.1 joerg get_data_segment(struct X86EMU *emu)
401 1.1 joerg {
402 1.1 joerg switch (emu->x86.mode & SYSMODE_SEGMASK) {
403 1.1 joerg case 0: /* default case: use ds register */
404 1.1 joerg case SYSMODE_SEGOVR_DS:
405 1.1 joerg case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
406 1.1 joerg return emu->x86.R_DS;
407 1.1 joerg case SYSMODE_SEG_DS_SS:/* non-overridden, use ss register */
408 1.1 joerg return emu->x86.R_SS;
409 1.1 joerg case SYSMODE_SEGOVR_CS:
410 1.1 joerg case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
411 1.1 joerg return emu->x86.R_CS;
412 1.1 joerg case SYSMODE_SEGOVR_ES:
413 1.1 joerg case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
414 1.1 joerg return emu->x86.R_ES;
415 1.1 joerg case SYSMODE_SEGOVR_FS:
416 1.1 joerg case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
417 1.1 joerg return emu->x86.R_FS;
418 1.1 joerg case SYSMODE_SEGOVR_GS:
419 1.1 joerg case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
420 1.1 joerg return emu->x86.R_GS;
421 1.1 joerg case SYSMODE_SEGOVR_SS:
422 1.1 joerg case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
423 1.1 joerg return emu->x86.R_SS;
424 1.1 joerg }
425 1.1 joerg X86EMU_halt_sys(emu);
426 1.1 joerg }
427 1.1 joerg /****************************************************************************
428 1.1 joerg PARAMETERS:
429 1.1 joerg offset - Offset to load data from
430 1.1 joerg
431 1.1 joerg RETURNS:
432 1.1 joerg Byte value read from the absolute memory location.
433 1.1 joerg
434 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
435 1.1 joerg ****************************************************************************/
436 1.1 joerg static uint8_t
437 1.1 joerg fetch_data_byte(struct X86EMU *emu, uint32_t offset)
438 1.1 joerg {
439 1.1 joerg return fetch_byte(emu, get_data_segment(emu), offset);
440 1.1 joerg }
441 1.1 joerg /****************************************************************************
442 1.1 joerg PARAMETERS:
443 1.1 joerg offset - Offset to load data from
444 1.1 joerg
445 1.1 joerg RETURNS:
446 1.1 joerg Word value read from the absolute memory location.
447 1.1 joerg
448 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
449 1.1 joerg ****************************************************************************/
450 1.1 joerg static uint16_t
451 1.1 joerg fetch_data_word(struct X86EMU *emu, uint32_t offset)
452 1.1 joerg {
453 1.1 joerg return fetch_word(emu, get_data_segment(emu), offset);
454 1.1 joerg }
455 1.1 joerg /****************************************************************************
456 1.1 joerg PARAMETERS:
457 1.1 joerg offset - Offset to load data from
458 1.1 joerg
459 1.1 joerg RETURNS:
460 1.1 joerg Long value read from the absolute memory location.
461 1.1 joerg
462 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
463 1.1 joerg ****************************************************************************/
464 1.1 joerg static uint32_t
465 1.1 joerg fetch_data_long(struct X86EMU *emu, uint32_t offset)
466 1.1 joerg {
467 1.1 joerg return fetch_long(emu, get_data_segment(emu), offset);
468 1.1 joerg }
469 1.1 joerg /****************************************************************************
470 1.1 joerg PARAMETERS:
471 1.1 joerg segment - Segment to load data from
472 1.1 joerg offset - Offset to load data from
473 1.1 joerg
474 1.1 joerg RETURNS:
475 1.1 joerg Byte value read from the absolute memory location.
476 1.1 joerg
477 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
478 1.1 joerg ****************************************************************************/
479 1.1 joerg static uint8_t
480 1.1 joerg fetch_byte(struct X86EMU *emu, uint32_t segment, uint32_t offset)
481 1.1 joerg {
482 1.1 joerg return (*emu->emu_rdb) (emu, ((uint32_t) segment << 4) + offset);
483 1.1 joerg }
484 1.1 joerg /****************************************************************************
485 1.1 joerg PARAMETERS:
486 1.1 joerg segment - Segment to load data from
487 1.1 joerg offset - Offset to load data from
488 1.1 joerg
489 1.1 joerg RETURNS:
490 1.1 joerg Word value read from the absolute memory location.
491 1.1 joerg
492 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
493 1.1 joerg ****************************************************************************/
494 1.1 joerg static uint16_t
495 1.1 joerg fetch_word(struct X86EMU *emu, uint32_t segment, uint32_t offset)
496 1.1 joerg {
497 1.1 joerg return (*emu->emu_rdw) (emu, ((uint32_t) segment << 4) + offset);
498 1.1 joerg }
499 1.1 joerg /****************************************************************************
500 1.1 joerg PARAMETERS:
501 1.1 joerg segment - Segment to load data from
502 1.1 joerg offset - Offset to load data from
503 1.1 joerg
504 1.1 joerg RETURNS:
505 1.1 joerg Long value read from the absolute memory location.
506 1.1 joerg
507 1.1 joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
508 1.1 joerg ****************************************************************************/
509 1.1 joerg static uint32_t
510 1.1 joerg fetch_long(struct X86EMU *emu, uint32_t segment, uint32_t offset)
511 1.1 joerg {
512 1.1 joerg return (*emu->emu_rdl) (emu, ((uint32_t) segment << 4) + offset);
513 1.1 joerg }
514 1.1 joerg /****************************************************************************
515 1.1 joerg PARAMETERS:
516 1.1 joerg offset - Offset to store data at
517 1.1 joerg val - Value to store
518 1.1 joerg
519 1.1 joerg REMARKS:
520 1.1 joerg Writes a word value to an segmented memory location. The segment used is
521 1.1 joerg the current 'default' segment, which may have been overridden.
522 1.1 joerg
523 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
524 1.1 joerg ****************************************************************************/
525 1.1 joerg static void
526 1.1 joerg store_data_byte(struct X86EMU *emu, uint32_t offset, uint8_t val)
527 1.1 joerg {
528 1.1 joerg store_byte(emu, get_data_segment(emu), offset, val);
529 1.1 joerg }
530 1.1 joerg /****************************************************************************
531 1.1 joerg PARAMETERS:
532 1.1 joerg offset - Offset to store data at
533 1.1 joerg val - Value to store
534 1.1 joerg
535 1.1 joerg REMARKS:
536 1.1 joerg Writes a word value to an segmented memory location. The segment used is
537 1.1 joerg the current 'default' segment, which may have been overridden.
538 1.1 joerg
539 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
540 1.1 joerg ****************************************************************************/
541 1.1 joerg static void
542 1.1 joerg store_data_word(struct X86EMU *emu, uint32_t offset, uint16_t val)
543 1.1 joerg {
544 1.1 joerg store_word(emu, get_data_segment(emu), offset, val);
545 1.1 joerg }
546 1.1 joerg /****************************************************************************
547 1.1 joerg PARAMETERS:
548 1.1 joerg offset - Offset to store data at
549 1.1 joerg val - Value to store
550 1.1 joerg
551 1.1 joerg REMARKS:
552 1.1 joerg Writes a long value to an segmented memory location. The segment used is
553 1.1 joerg the current 'default' segment, which may have been overridden.
554 1.1 joerg
555 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
556 1.1 joerg ****************************************************************************/
557 1.1 joerg static void
558 1.1 joerg store_data_long(struct X86EMU *emu, uint32_t offset, uint32_t val)
559 1.1 joerg {
560 1.1 joerg store_long(emu, get_data_segment(emu), offset, val);
561 1.1 joerg }
562 1.1 joerg /****************************************************************************
563 1.1 joerg PARAMETERS:
564 1.1 joerg segment - Segment to store data at
565 1.1 joerg offset - Offset to store data at
566 1.1 joerg val - Value to store
567 1.1 joerg
568 1.1 joerg REMARKS:
569 1.1 joerg Writes a byte value to an absolute memory location.
570 1.1 joerg
571 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
572 1.1 joerg ****************************************************************************/
573 1.1 joerg static void
574 1.1 joerg store_byte(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint8_t val)
575 1.1 joerg {
576 1.1 joerg (*emu->emu_wrb) (emu, ((uint32_t) segment << 4) + offset, val);
577 1.1 joerg }
578 1.1 joerg /****************************************************************************
579 1.1 joerg PARAMETERS:
580 1.1 joerg segment - Segment to store data at
581 1.1 joerg offset - Offset to store data at
582 1.1 joerg val - Value to store
583 1.1 joerg
584 1.1 joerg REMARKS:
585 1.1 joerg Writes a word value to an absolute memory location.
586 1.1 joerg
587 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
588 1.1 joerg ****************************************************************************/
589 1.1 joerg static void
590 1.1 joerg store_word(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint16_t val)
591 1.1 joerg {
592 1.1 joerg (*emu->emu_wrw) (emu, ((uint32_t) segment << 4) + offset, val);
593 1.1 joerg }
594 1.1 joerg /****************************************************************************
595 1.1 joerg PARAMETERS:
596 1.1 joerg segment - Segment to store data at
597 1.1 joerg offset - Offset to store data at
598 1.1 joerg val - Value to store
599 1.1 joerg
600 1.1 joerg REMARKS:
601 1.1 joerg Writes a long value to an absolute memory location.
602 1.1 joerg
603 1.1 joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
604 1.1 joerg ****************************************************************************/
605 1.1 joerg static void
606 1.1 joerg store_long(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint32_t val)
607 1.1 joerg {
608 1.1 joerg (*emu->emu_wrl) (emu, ((uint32_t) segment << 4) + offset, val);
609 1.1 joerg }
610 1.1 joerg /****************************************************************************
611 1.1 joerg PARAMETERS:
612 1.1 joerg reg - Register to decode
613 1.1 joerg
614 1.1 joerg RETURNS:
615 1.1 joerg Pointer to the appropriate register
616 1.1 joerg
617 1.1 joerg REMARKS:
618 1.1 joerg Return a pointer to the register given by the R/RM field of the
619 1.1 joerg modrm byte, for byte operands. Also enables the decoding of instructions.
620 1.1 joerg ****************************************************************************/
621 1.1 joerg static uint8_t *
622 1.1 joerg decode_rm_byte_register(struct X86EMU *emu, int reg)
623 1.1 joerg {
624 1.1 joerg switch (reg) {
625 1.1 joerg case 0:
626 1.1 joerg return &emu->x86.R_AL;
627 1.1 joerg case 1:
628 1.1 joerg return &emu->x86.R_CL;
629 1.1 joerg case 2:
630 1.1 joerg return &emu->x86.R_DL;
631 1.1 joerg case 3:
632 1.1 joerg return &emu->x86.R_BL;
633 1.1 joerg case 4:
634 1.1 joerg return &emu->x86.R_AH;
635 1.1 joerg case 5:
636 1.1 joerg return &emu->x86.R_CH;
637 1.1 joerg case 6:
638 1.1 joerg return &emu->x86.R_DH;
639 1.1 joerg case 7:
640 1.1 joerg return &emu->x86.R_BH;
641 1.1 joerg default:
642 1.1 joerg X86EMU_halt_sys(emu);
643 1.1 joerg }
644 1.1 joerg }
645 1.1 joerg
646 1.1 joerg static uint8_t *
647 1.1 joerg decode_rl_byte_register(struct X86EMU *emu)
648 1.1 joerg {
649 1.1 joerg return decode_rm_byte_register(emu, emu->cur_rl);
650 1.1 joerg }
651 1.1 joerg
652 1.1 joerg static uint8_t *
653 1.1 joerg decode_rh_byte_register(struct X86EMU *emu)
654 1.1 joerg {
655 1.1 joerg return decode_rm_byte_register(emu, emu->cur_rh);
656 1.1 joerg }
657 1.1 joerg /****************************************************************************
658 1.1 joerg PARAMETERS:
659 1.1 joerg reg - Register to decode
660 1.1 joerg
661 1.1 joerg RETURNS:
662 1.1 joerg Pointer to the appropriate register
663 1.1 joerg
664 1.1 joerg REMARKS:
665 1.1 joerg Return a pointer to the register given by the R/RM field of the
666 1.1 joerg modrm byte, for word operands. Also enables the decoding of instructions.
667 1.1 joerg ****************************************************************************/
668 1.1 joerg static uint16_t *
669 1.1 joerg decode_rm_word_register(struct X86EMU *emu, int reg)
670 1.1 joerg {
671 1.1 joerg switch (reg) {
672 1.1 joerg case 0:
673 1.1 joerg return &emu->x86.R_AX;
674 1.1 joerg case 1:
675 1.1 joerg return &emu->x86.R_CX;
676 1.1 joerg case 2:
677 1.1 joerg return &emu->x86.R_DX;
678 1.1 joerg case 3:
679 1.1 joerg return &emu->x86.R_BX;
680 1.1 joerg case 4:
681 1.1 joerg return &emu->x86.R_SP;
682 1.1 joerg case 5:
683 1.1 joerg return &emu->x86.R_BP;
684 1.1 joerg case 6:
685 1.1 joerg return &emu->x86.R_SI;
686 1.1 joerg case 7:
687 1.1 joerg return &emu->x86.R_DI;
688 1.1 joerg default:
689 1.1 joerg X86EMU_halt_sys(emu);
690 1.1 joerg }
691 1.1 joerg }
692 1.1 joerg
693 1.1 joerg static uint16_t *
694 1.1 joerg decode_rl_word_register(struct X86EMU *emu)
695 1.1 joerg {
696 1.1 joerg return decode_rm_word_register(emu, emu->cur_rl);
697 1.1 joerg }
698 1.1 joerg
699 1.1 joerg static uint16_t *
700 1.1 joerg decode_rh_word_register(struct X86EMU *emu)
701 1.1 joerg {
702 1.1 joerg return decode_rm_word_register(emu, emu->cur_rh);
703 1.1 joerg }
704 1.1 joerg /****************************************************************************
705 1.1 joerg PARAMETERS:
706 1.1 joerg reg - Register to decode
707 1.1 joerg
708 1.1 joerg RETURNS:
709 1.1 joerg Pointer to the appropriate register
710 1.1 joerg
711 1.1 joerg REMARKS:
712 1.1 joerg Return a pointer to the register given by the R/RM field of the
713 1.1 joerg modrm byte, for dword operands. Also enables the decoding of instructions.
714 1.1 joerg ****************************************************************************/
715 1.1 joerg static uint32_t *
716 1.1 joerg decode_rm_long_register(struct X86EMU *emu, int reg)
717 1.1 joerg {
718 1.1 joerg switch (reg) {
719 1.1 joerg case 0:
720 1.1 joerg return &emu->x86.R_EAX;
721 1.1 joerg case 1:
722 1.1 joerg return &emu->x86.R_ECX;
723 1.1 joerg case 2:
724 1.1 joerg return &emu->x86.R_EDX;
725 1.1 joerg case 3:
726 1.1 joerg return &emu->x86.R_EBX;
727 1.1 joerg case 4:
728 1.1 joerg return &emu->x86.R_ESP;
729 1.1 joerg case 5:
730 1.1 joerg return &emu->x86.R_EBP;
731 1.1 joerg case 6:
732 1.1 joerg return &emu->x86.R_ESI;
733 1.1 joerg case 7:
734 1.1 joerg return &emu->x86.R_EDI;
735 1.1 joerg default:
736 1.1 joerg X86EMU_halt_sys(emu);
737 1.1 joerg }
738 1.1 joerg }
739 1.1 joerg
740 1.1 joerg static uint32_t *
741 1.1 joerg decode_rl_long_register(struct X86EMU *emu)
742 1.1 joerg {
743 1.1 joerg return decode_rm_long_register(emu, emu->cur_rl);
744 1.1 joerg }
745 1.1 joerg
746 1.1 joerg static uint32_t *
747 1.1 joerg decode_rh_long_register(struct X86EMU *emu)
748 1.1 joerg {
749 1.1 joerg return decode_rm_long_register(emu, emu->cur_rh);
750 1.1 joerg }
751 1.1 joerg
752 1.1 joerg /****************************************************************************
753 1.1 joerg PARAMETERS:
754 1.1 joerg reg - Register to decode
755 1.1 joerg
756 1.1 joerg RETURNS:
757 1.1 joerg Pointer to the appropriate register
758 1.1 joerg
759 1.1 joerg REMARKS:
760 1.1 joerg Return a pointer to the register given by the R/RM field of the
761 1.1 joerg modrm byte, for word operands, modified from above for the weirdo
762 1.1 joerg special case of segreg operands. Also enables the decoding of instructions.
763 1.1 joerg ****************************************************************************/
764 1.1 joerg static uint16_t *
765 1.1 joerg decode_rh_seg_register(struct X86EMU *emu)
766 1.1 joerg {
767 1.1 joerg switch (emu->cur_rh) {
768 1.1 joerg case 0:
769 1.1 joerg return &emu->x86.R_ES;
770 1.1 joerg case 1:
771 1.1 joerg return &emu->x86.R_CS;
772 1.1 joerg case 2:
773 1.1 joerg return &emu->x86.R_SS;
774 1.1 joerg case 3:
775 1.1 joerg return &emu->x86.R_DS;
776 1.1 joerg case 4:
777 1.1 joerg return &emu->x86.R_FS;
778 1.1 joerg case 5:
779 1.1 joerg return &emu->x86.R_GS;
780 1.1 joerg default:
781 1.1 joerg X86EMU_halt_sys(emu);
782 1.1 joerg }
783 1.1 joerg }
784 1.1 joerg /*
785 1.1 joerg *
786 1.1 joerg * return offset from the SIB Byte
787 1.1 joerg */
788 1.1 joerg static uint32_t
789 1.1 joerg decode_sib_address(struct X86EMU *emu, int sib, int mod)
790 1.1 joerg {
791 1.1 joerg uint32_t base = 0, i = 0, scale = 1;
792 1.1 joerg
793 1.1 joerg switch (sib & 0x07) {
794 1.1 joerg case 0:
795 1.1 joerg base = emu->x86.R_EAX;
796 1.1 joerg break;
797 1.1 joerg case 1:
798 1.1 joerg base = emu->x86.R_ECX;
799 1.1 joerg break;
800 1.1 joerg case 2:
801 1.1 joerg base = emu->x86.R_EDX;
802 1.1 joerg break;
803 1.1 joerg case 3:
804 1.1 joerg base = emu->x86.R_EBX;
805 1.1 joerg break;
806 1.1 joerg case 4:
807 1.1 joerg base = emu->x86.R_ESP;
808 1.1 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
809 1.1 joerg break;
810 1.1 joerg case 5:
811 1.1 joerg if (mod == 0) {
812 1.1 joerg base = fetch_long_imm(emu);
813 1.1 joerg } else {
814 1.6 joerg base = emu->x86.R_EBP;
815 1.1 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
816 1.1 joerg }
817 1.1 joerg break;
818 1.1 joerg case 6:
819 1.1 joerg base = emu->x86.R_ESI;
820 1.1 joerg break;
821 1.1 joerg case 7:
822 1.1 joerg base = emu->x86.R_EDI;
823 1.1 joerg break;
824 1.1 joerg }
825 1.1 joerg switch ((sib >> 3) & 0x07) {
826 1.1 joerg case 0:
827 1.1 joerg i = emu->x86.R_EAX;
828 1.1 joerg break;
829 1.1 joerg case 1:
830 1.1 joerg i = emu->x86.R_ECX;
831 1.1 joerg break;
832 1.1 joerg case 2:
833 1.1 joerg i = emu->x86.R_EDX;
834 1.1 joerg break;
835 1.1 joerg case 3:
836 1.1 joerg i = emu->x86.R_EBX;
837 1.1 joerg break;
838 1.1 joerg case 4:
839 1.1 joerg i = 0;
840 1.1 joerg break;
841 1.1 joerg case 5:
842 1.1 joerg i = emu->x86.R_EBP;
843 1.1 joerg break;
844 1.1 joerg case 6:
845 1.1 joerg i = emu->x86.R_ESI;
846 1.1 joerg break;
847 1.1 joerg case 7:
848 1.1 joerg i = emu->x86.R_EDI;
849 1.1 joerg break;
850 1.1 joerg }
851 1.1 joerg scale = 1 << ((sib >> 6) & 0x03);
852 1.1 joerg return base + (i * scale);
853 1.1 joerg }
854 1.1 joerg /****************************************************************************
855 1.1 joerg PARAMETERS:
856 1.1 joerg rm - RM value to decode
857 1.1 joerg
858 1.1 joerg RETURNS:
859 1.1 joerg Offset in memory for the address decoding
860 1.1 joerg
861 1.1 joerg REMARKS:
862 1.1 joerg Return the offset given by mod=00, mod=01 or mod=10 addressing.
863 1.1 joerg Also enables the decoding of instructions.
864 1.1 joerg ****************************************************************************/
865 1.1 joerg static uint32_t
866 1.1 joerg decode_rl_address(struct X86EMU *emu)
867 1.1 joerg {
868 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
869 1.1 joerg uint32_t offset, sib;
870 1.1 joerg /* 32-bit addressing */
871 1.1 joerg switch (emu->cur_rl) {
872 1.1 joerg case 0:
873 1.1 joerg offset = emu->x86.R_EAX;
874 1.1 joerg break;
875 1.1 joerg case 1:
876 1.1 joerg offset = emu->x86.R_ECX;
877 1.1 joerg break;
878 1.1 joerg case 2:
879 1.1 joerg offset = emu->x86.R_EDX;
880 1.1 joerg break;
881 1.1 joerg case 3:
882 1.1 joerg offset = emu->x86.R_EBX;
883 1.1 joerg break;
884 1.1 joerg case 4:
885 1.1 joerg sib = fetch_byte_imm(emu);
886 1.1 joerg offset = decode_sib_address(emu, sib, 0);
887 1.1 joerg break;
888 1.1 joerg case 5:
889 1.6 joerg if (emu->cur_mod == 0) {
890 1.1 joerg offset = fetch_long_imm(emu);
891 1.6 joerg } else {
892 1.6 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
893 1.1 joerg offset = emu->x86.R_EBP;
894 1.6 joerg }
895 1.1 joerg break;
896 1.1 joerg case 6:
897 1.1 joerg offset = emu->x86.R_ESI;
898 1.1 joerg break;
899 1.1 joerg case 7:
900 1.1 joerg offset = emu->x86.R_EDI;
901 1.1 joerg break;
902 1.1 joerg default:
903 1.1 joerg X86EMU_halt_sys(emu);
904 1.1 joerg }
905 1.1 joerg if (emu->cur_mod == 1)
906 1.1 joerg offset += (int8_t)fetch_byte_imm(emu);
907 1.1 joerg else if (emu->cur_mod == 2)
908 1.1 joerg offset += fetch_long_imm(emu);
909 1.1 joerg return offset;
910 1.1 joerg } else {
911 1.1 joerg uint16_t offset;
912 1.1 joerg
913 1.1 joerg /* 16-bit addressing */
914 1.1 joerg switch (emu->cur_rl) {
915 1.1 joerg case 0:
916 1.1 joerg offset = emu->x86.R_BX + emu->x86.R_SI;
917 1.1 joerg break;
918 1.1 joerg case 1:
919 1.1 joerg offset = emu->x86.R_BX + emu->x86.R_DI;
920 1.1 joerg break;
921 1.1 joerg case 2:
922 1.1 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
923 1.1 joerg offset = emu->x86.R_BP + emu->x86.R_SI;
924 1.1 joerg break;
925 1.1 joerg case 3:
926 1.1 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
927 1.1 joerg offset = emu->x86.R_BP + emu->x86.R_DI;
928 1.1 joerg break;
929 1.1 joerg case 4:
930 1.1 joerg offset = emu->x86.R_SI;
931 1.1 joerg break;
932 1.1 joerg case 5:
933 1.1 joerg offset = emu->x86.R_DI;
934 1.1 joerg break;
935 1.1 joerg case 6:
936 1.6 joerg if (emu->cur_mod == 0) {
937 1.1 joerg offset = fetch_word_imm(emu);
938 1.6 joerg } else {
939 1.6 joerg emu->x86.mode |= SYSMODE_SEG_DS_SS;
940 1.1 joerg offset = emu->x86.R_BP;
941 1.6 joerg }
942 1.1 joerg break;
943 1.1 joerg case 7:
944 1.1 joerg offset = emu->x86.R_BX;
945 1.1 joerg break;
946 1.1 joerg default:
947 1.1 joerg X86EMU_halt_sys(emu);
948 1.1 joerg }
949 1.1 joerg if (emu->cur_mod == 1)
950 1.1 joerg offset += (int8_t)fetch_byte_imm(emu);
951 1.1 joerg else if (emu->cur_mod == 2)
952 1.1 joerg offset += fetch_word_imm(emu);
953 1.1 joerg return offset;
954 1.1 joerg }
955 1.1 joerg }
956 1.1 joerg
957 1.1 joerg static uint8_t
958 1.1 joerg decode_and_fetch_byte(struct X86EMU *emu)
959 1.1 joerg {
960 1.1 joerg if (emu->cur_mod != 3) {
961 1.1 joerg emu->cur_offset = decode_rl_address(emu);
962 1.1 joerg return fetch_data_byte(emu, emu->cur_offset);
963 1.1 joerg } else {
964 1.1 joerg return *decode_rl_byte_register(emu);
965 1.1 joerg }
966 1.1 joerg }
967 1.1 joerg
968 1.1 joerg static uint16_t
969 1.1 joerg decode_and_fetch_word_disp(struct X86EMU *emu, int16_t disp)
970 1.1 joerg {
971 1.1 joerg if (emu->cur_mod != 3) {
972 1.1 joerg /* TODO: A20 gate emulation */
973 1.1 joerg emu->cur_offset = decode_rl_address(emu) + disp;
974 1.1 joerg if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
975 1.1 joerg emu->cur_offset &= 0xffff;
976 1.1 joerg return fetch_data_word(emu, emu->cur_offset);
977 1.1 joerg } else {
978 1.1 joerg return *decode_rl_word_register(emu);
979 1.1 joerg }
980 1.1 joerg }
981 1.1 joerg
982 1.1 joerg static uint32_t
983 1.1 joerg decode_and_fetch_long_disp(struct X86EMU *emu, int16_t disp)
984 1.1 joerg {
985 1.1 joerg if (emu->cur_mod != 3) {
986 1.1 joerg /* TODO: A20 gate emulation */
987 1.1 joerg emu->cur_offset = decode_rl_address(emu) + disp;
988 1.1 joerg if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
989 1.1 joerg emu->cur_offset &= 0xffff;
990 1.1 joerg return fetch_data_long(emu, emu->cur_offset);
991 1.1 joerg } else {
992 1.1 joerg return *decode_rl_long_register(emu);
993 1.1 joerg }
994 1.1 joerg }
995 1.1 joerg
996 1.1 joerg uint16_t
997 1.1 joerg decode_and_fetch_word(struct X86EMU *emu)
998 1.1 joerg {
999 1.1 joerg return decode_and_fetch_word_disp(emu, 0);
1000 1.1 joerg }
1001 1.1 joerg
1002 1.1 joerg uint32_t
1003 1.1 joerg decode_and_fetch_long(struct X86EMU *emu)
1004 1.1 joerg {
1005 1.1 joerg return decode_and_fetch_long_disp(emu, 0);
1006 1.1 joerg }
1007 1.1 joerg
1008 1.1 joerg uint8_t
1009 1.1 joerg decode_and_fetch_byte_imm8(struct X86EMU *emu, uint8_t *imm)
1010 1.1 joerg {
1011 1.1 joerg if (emu->cur_mod != 3) {
1012 1.1 joerg emu->cur_offset = decode_rl_address(emu);
1013 1.1 joerg *imm = fetch_byte_imm(emu);
1014 1.1 joerg return fetch_data_byte(emu, emu->cur_offset);
1015 1.1 joerg } else {
1016 1.1 joerg *imm = fetch_byte_imm(emu);
1017 1.1 joerg return *decode_rl_byte_register(emu);
1018 1.1 joerg }
1019 1.1 joerg }
1020 1.1 joerg
1021 1.1 joerg static uint16_t
1022 1.1 joerg decode_and_fetch_word_imm8(struct X86EMU *emu, uint8_t *imm)
1023 1.1 joerg {
1024 1.1 joerg if (emu->cur_mod != 3) {
1025 1.1 joerg emu->cur_offset = decode_rl_address(emu);
1026 1.1 joerg *imm = fetch_byte_imm(emu);
1027 1.1 joerg return fetch_data_word(emu, emu->cur_offset);
1028 1.1 joerg } else {
1029 1.1 joerg *imm = fetch_byte_imm(emu);
1030 1.1 joerg return *decode_rl_word_register(emu);
1031 1.1 joerg }
1032 1.1 joerg }
1033 1.1 joerg
1034 1.1 joerg static uint32_t
1035 1.1 joerg decode_and_fetch_long_imm8(struct X86EMU *emu, uint8_t *imm)
1036 1.1 joerg {
1037 1.1 joerg if (emu->cur_mod != 3) {
1038 1.1 joerg emu->cur_offset = decode_rl_address(emu);
1039 1.1 joerg *imm = fetch_byte_imm(emu);
1040 1.1 joerg return fetch_data_long(emu, emu->cur_offset);
1041 1.1 joerg } else {
1042 1.1 joerg *imm = fetch_byte_imm(emu);
1043 1.1 joerg return *decode_rl_long_register(emu);
1044 1.1 joerg }
1045 1.1 joerg }
1046 1.1 joerg
1047 1.1 joerg static void
1048 1.1 joerg write_back_byte(struct X86EMU *emu, uint8_t val)
1049 1.1 joerg {
1050 1.1 joerg if (emu->cur_mod != 3)
1051 1.1 joerg store_data_byte(emu, emu->cur_offset, val);
1052 1.1 joerg else
1053 1.1 joerg *decode_rl_byte_register(emu) = val;
1054 1.1 joerg }
1055 1.1 joerg
1056 1.1 joerg static void
1057 1.1 joerg write_back_word(struct X86EMU *emu, uint16_t val)
1058 1.1 joerg {
1059 1.1 joerg if (emu->cur_mod != 3)
1060 1.1 joerg store_data_word(emu, emu->cur_offset, val);
1061 1.1 joerg else
1062 1.1 joerg *decode_rl_word_register(emu) = val;
1063 1.1 joerg }
1064 1.1 joerg
1065 1.1 joerg static void
1066 1.1 joerg write_back_long(struct X86EMU *emu, uint32_t val)
1067 1.1 joerg {
1068 1.1 joerg if (emu->cur_mod != 3)
1069 1.1 joerg store_data_long(emu, emu->cur_offset, val);
1070 1.1 joerg else
1071 1.1 joerg *decode_rl_long_register(emu) = val;
1072 1.1 joerg }
1073 1.1 joerg
1074 1.1 joerg static void
1075 1.1 joerg common_inc_word_long(struct X86EMU *emu, union X86EMU_register *reg)
1076 1.1 joerg {
1077 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1078 1.1 joerg reg->I32_reg.e_reg = inc_long(emu, reg->I32_reg.e_reg);
1079 1.1 joerg else
1080 1.1 joerg reg->I16_reg.x_reg = inc_word(emu, reg->I16_reg.x_reg);
1081 1.1 joerg }
1082 1.1 joerg
1083 1.1 joerg static void
1084 1.1 joerg common_dec_word_long(struct X86EMU *emu, union X86EMU_register *reg)
1085 1.1 joerg {
1086 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1087 1.1 joerg reg->I32_reg.e_reg = dec_long(emu, reg->I32_reg.e_reg);
1088 1.1 joerg else
1089 1.1 joerg reg->I16_reg.x_reg = dec_word(emu, reg->I16_reg.x_reg);
1090 1.1 joerg }
1091 1.1 joerg
1092 1.1 joerg static void
1093 1.1 joerg common_binop_byte_rm_r(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
1094 1.1 joerg {
1095 1.1 joerg uint32_t destoffset;
1096 1.1 joerg uint8_t *destreg, srcval;
1097 1.1 joerg uint8_t destval;
1098 1.1 joerg
1099 1.1 joerg fetch_decode_modrm(emu);
1100 1.1 joerg srcval = *decode_rh_byte_register(emu);
1101 1.1 joerg if (emu->cur_mod != 3) {
1102 1.1 joerg destoffset = decode_rl_address(emu);
1103 1.1 joerg destval = fetch_data_byte(emu, destoffset);
1104 1.1 joerg destval = (*binop)(emu, destval, srcval);
1105 1.1 joerg store_data_byte(emu, destoffset, destval);
1106 1.1 joerg } else {
1107 1.1 joerg destreg = decode_rl_byte_register(emu);
1108 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1109 1.1 joerg }
1110 1.1 joerg }
1111 1.1 joerg
1112 1.1 joerg static void
1113 1.1 joerg common_binop_ns_byte_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint8_t, uint8_t))
1114 1.1 joerg {
1115 1.1 joerg uint32_t destoffset;
1116 1.1 joerg uint8_t destval, srcval;
1117 1.1 joerg
1118 1.1 joerg fetch_decode_modrm(emu);
1119 1.1 joerg srcval = *decode_rh_byte_register(emu);
1120 1.1 joerg if (emu->cur_mod != 3) {
1121 1.1 joerg destoffset = decode_rl_address(emu);
1122 1.1 joerg destval = fetch_data_byte(emu, destoffset);
1123 1.1 joerg } else {
1124 1.1 joerg destval = *decode_rl_byte_register(emu);
1125 1.1 joerg }
1126 1.1 joerg (*binop)(emu, destval, srcval);
1127 1.1 joerg }
1128 1.1 joerg
1129 1.1 joerg static void
1130 1.1 joerg common_binop_word_rm_r(struct X86EMU *emu, uint16_t (*binop)(struct X86EMU *, uint16_t, uint16_t))
1131 1.1 joerg {
1132 1.1 joerg uint32_t destoffset;
1133 1.1 joerg uint16_t destval, *destreg, srcval;
1134 1.1 joerg
1135 1.1 joerg fetch_decode_modrm(emu);
1136 1.1 joerg srcval = *decode_rh_word_register(emu);
1137 1.1 joerg if (emu->cur_mod != 3) {
1138 1.1 joerg destoffset = decode_rl_address(emu);
1139 1.1 joerg destval = fetch_data_word(emu, destoffset);
1140 1.1 joerg destval = (*binop)(emu, destval, srcval);
1141 1.1 joerg store_data_word(emu, destoffset, destval);
1142 1.1 joerg } else {
1143 1.1 joerg destreg = decode_rl_word_register(emu);
1144 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1145 1.1 joerg }
1146 1.1 joerg }
1147 1.1 joerg
1148 1.1 joerg static void
1149 1.1 joerg common_binop_byte_r_rm(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
1150 1.1 joerg {
1151 1.1 joerg uint8_t *destreg, srcval;
1152 1.1 joerg uint32_t srcoffset;
1153 1.1 joerg
1154 1.1 joerg fetch_decode_modrm(emu);
1155 1.1 joerg destreg = decode_rh_byte_register(emu);
1156 1.1 joerg if (emu->cur_mod != 3) {
1157 1.1 joerg srcoffset = decode_rl_address(emu);
1158 1.1 joerg srcval = fetch_data_byte(emu, srcoffset);
1159 1.1 joerg } else {
1160 1.1 joerg srcval = *decode_rl_byte_register(emu);
1161 1.1 joerg }
1162 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1163 1.1 joerg }
1164 1.1 joerg
1165 1.1 joerg static void
1166 1.1 joerg common_binop_long_rm_r(struct X86EMU *emu, uint32_t (*binop)(struct X86EMU *, uint32_t, uint32_t))
1167 1.1 joerg {
1168 1.1 joerg uint32_t destoffset;
1169 1.1 joerg uint32_t destval, *destreg, srcval;
1170 1.1 joerg
1171 1.1 joerg fetch_decode_modrm(emu);
1172 1.1 joerg srcval = *decode_rh_long_register(emu);
1173 1.1 joerg if (emu->cur_mod != 3) {
1174 1.1 joerg destoffset = decode_rl_address(emu);
1175 1.1 joerg destval = fetch_data_long(emu, destoffset);
1176 1.1 joerg destval = (*binop)(emu, destval, srcval);
1177 1.1 joerg store_data_long(emu, destoffset, destval);
1178 1.1 joerg } else {
1179 1.1 joerg destreg = decode_rl_long_register(emu);
1180 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1181 1.1 joerg }
1182 1.1 joerg }
1183 1.1 joerg
1184 1.1 joerg static void
1185 1.1 joerg common_binop_word_long_rm_r(struct X86EMU *emu,
1186 1.1 joerg uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
1187 1.1 joerg {
1188 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1189 1.1 joerg common_binop_long_rm_r(emu, binop32);
1190 1.1 joerg else
1191 1.1 joerg common_binop_word_rm_r(emu, binop16);
1192 1.1 joerg }
1193 1.1 joerg
1194 1.1 joerg static void
1195 1.1 joerg common_binop_ns_word_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint16_t, uint16_t))
1196 1.1 joerg {
1197 1.1 joerg uint32_t destoffset;
1198 1.1 joerg uint16_t destval, srcval;
1199 1.1 joerg
1200 1.1 joerg fetch_decode_modrm(emu);
1201 1.1 joerg srcval = *decode_rh_word_register(emu);
1202 1.1 joerg if (emu->cur_mod != 3) {
1203 1.1 joerg destoffset = decode_rl_address(emu);
1204 1.1 joerg destval = fetch_data_word(emu, destoffset);
1205 1.1 joerg } else {
1206 1.1 joerg destval = *decode_rl_word_register(emu);
1207 1.1 joerg }
1208 1.1 joerg (*binop)(emu, destval, srcval);
1209 1.1 joerg }
1210 1.1 joerg
1211 1.1 joerg
1212 1.1 joerg static void
1213 1.1 joerg common_binop_ns_long_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint32_t, uint32_t))
1214 1.1 joerg {
1215 1.1 joerg uint32_t destoffset;
1216 1.1 joerg uint32_t destval, srcval;
1217 1.1 joerg
1218 1.1 joerg fetch_decode_modrm(emu);
1219 1.1 joerg srcval = *decode_rh_long_register(emu);
1220 1.1 joerg if (emu->cur_mod != 3) {
1221 1.1 joerg destoffset = decode_rl_address(emu);
1222 1.1 joerg destval = fetch_data_long(emu, destoffset);
1223 1.1 joerg } else {
1224 1.1 joerg destval = *decode_rl_long_register(emu);
1225 1.1 joerg }
1226 1.1 joerg (*binop)(emu, destval, srcval);
1227 1.1 joerg }
1228 1.1 joerg
1229 1.1 joerg static void
1230 1.1 joerg common_binop_ns_word_long_rm_r(struct X86EMU *emu,
1231 1.1 joerg void (*binop16)(struct X86EMU *, uint16_t, uint16_t), void (*binop32)(struct X86EMU *, uint32_t, uint32_t))
1232 1.1 joerg {
1233 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1234 1.1 joerg common_binop_ns_long_rm_r(emu, binop32);
1235 1.1 joerg else
1236 1.1 joerg common_binop_ns_word_rm_r(emu, binop16);
1237 1.1 joerg }
1238 1.1 joerg
1239 1.1 joerg static void
1240 1.1 joerg common_binop_long_r_rm(struct X86EMU *emu, uint32_t (*binop)(struct X86EMU *, uint32_t, uint32_t))
1241 1.1 joerg {
1242 1.1 joerg uint32_t srcoffset;
1243 1.1 joerg uint32_t *destreg, srcval;
1244 1.1 joerg
1245 1.1 joerg fetch_decode_modrm(emu);
1246 1.1 joerg destreg = decode_rh_long_register(emu);
1247 1.1 joerg if (emu->cur_mod != 3) {
1248 1.1 joerg srcoffset = decode_rl_address(emu);
1249 1.1 joerg srcval = fetch_data_long(emu, srcoffset);
1250 1.1 joerg } else {
1251 1.1 joerg srcval = *decode_rl_long_register(emu);
1252 1.1 joerg }
1253 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1254 1.1 joerg }
1255 1.1 joerg
1256 1.1 joerg static void
1257 1.1 joerg common_binop_word_r_rm(struct X86EMU *emu, uint16_t (*binop)(struct X86EMU *, uint16_t, uint16_t))
1258 1.1 joerg {
1259 1.1 joerg uint32_t srcoffset;
1260 1.1 joerg uint16_t *destreg, srcval;
1261 1.1 joerg
1262 1.1 joerg fetch_decode_modrm(emu);
1263 1.1 joerg destreg = decode_rh_word_register(emu);
1264 1.1 joerg if (emu->cur_mod != 3) {
1265 1.1 joerg srcoffset = decode_rl_address(emu);
1266 1.1 joerg srcval = fetch_data_word(emu, srcoffset);
1267 1.1 joerg } else {
1268 1.1 joerg srcval = *decode_rl_word_register(emu);
1269 1.1 joerg }
1270 1.1 joerg *destreg = (*binop)(emu, *destreg, srcval);
1271 1.1 joerg }
1272 1.1 joerg
1273 1.1 joerg static void
1274 1.1 joerg common_binop_word_long_r_rm(struct X86EMU *emu,
1275 1.1 joerg uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
1276 1.1 joerg {
1277 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1278 1.1 joerg common_binop_long_r_rm(emu, binop32);
1279 1.1 joerg else
1280 1.1 joerg common_binop_word_r_rm(emu, binop16);
1281 1.1 joerg }
1282 1.1 joerg
1283 1.1 joerg static void
1284 1.1 joerg common_binop_byte_imm(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
1285 1.1 joerg {
1286 1.1 joerg uint8_t srcval;
1287 1.1 joerg
1288 1.1 joerg srcval = fetch_byte_imm(emu);
1289 1.1 joerg emu->x86.R_AL = (*binop)(emu, emu->x86.R_AL, srcval);
1290 1.1 joerg }
1291 1.1 joerg
1292 1.1 joerg static void
1293 1.1 joerg common_binop_word_long_imm(struct X86EMU *emu,
1294 1.1 joerg uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
1295 1.1 joerg {
1296 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1297 1.1 joerg uint32_t srcval;
1298 1.1 joerg
1299 1.1 joerg srcval = fetch_long_imm(emu);
1300 1.1 joerg emu->x86.R_EAX = (*binop32)(emu, emu->x86.R_EAX, srcval);
1301 1.1 joerg } else {
1302 1.1 joerg uint16_t srcval;
1303 1.1 joerg
1304 1.1 joerg srcval = fetch_word_imm(emu);
1305 1.1 joerg emu->x86.R_AX = (*binop16)(emu, emu->x86.R_AX, srcval);
1306 1.1 joerg }
1307 1.1 joerg }
1308 1.1 joerg
1309 1.1 joerg static void
1310 1.1 joerg common_push_word_long(struct X86EMU *emu, union X86EMU_register *reg)
1311 1.1 joerg {
1312 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1313 1.1 joerg push_long(emu, reg->I32_reg.e_reg);
1314 1.1 joerg else
1315 1.1 joerg push_word(emu, reg->I16_reg.x_reg);
1316 1.1 joerg }
1317 1.1 joerg
1318 1.1 joerg static void
1319 1.1 joerg common_pop_word_long(struct X86EMU *emu, union X86EMU_register *reg)
1320 1.1 joerg {
1321 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1322 1.1 joerg reg->I32_reg.e_reg = pop_long(emu);
1323 1.1 joerg else
1324 1.1 joerg reg->I16_reg.x_reg = pop_word(emu);
1325 1.1 joerg }
1326 1.1 joerg
1327 1.1 joerg static void
1328 1.1 joerg common_imul_long_IMM(struct X86EMU *emu, bool byte_imm)
1329 1.1 joerg {
1330 1.1 joerg uint32_t srcoffset;
1331 1.1 joerg uint32_t *destreg, srcval;
1332 1.1 joerg int32_t imm;
1333 1.1 joerg uint64_t res;
1334 1.1 joerg
1335 1.1 joerg fetch_decode_modrm(emu);
1336 1.1 joerg destreg = decode_rh_long_register(emu);
1337 1.1 joerg if (emu->cur_mod != 3) {
1338 1.1 joerg srcoffset = decode_rl_address(emu);
1339 1.1 joerg srcval = fetch_data_long(emu, srcoffset);
1340 1.1 joerg } else {
1341 1.1 joerg srcval = *decode_rl_long_register(emu);
1342 1.1 joerg }
1343 1.1 joerg
1344 1.1 joerg if (byte_imm)
1345 1.1 joerg imm = (int8_t)fetch_byte_imm(emu);
1346 1.1 joerg else
1347 1.1 joerg imm = fetch_long_imm(emu);
1348 1.1 joerg res = (int32_t)srcval * imm;
1349 1.1 joerg
1350 1.1 joerg if (res > 0xffffffff) {
1351 1.1 joerg SET_FLAG(F_CF);
1352 1.1 joerg SET_FLAG(F_OF);
1353 1.1 joerg } else {
1354 1.1 joerg CLEAR_FLAG(F_CF);
1355 1.1 joerg CLEAR_FLAG(F_OF);
1356 1.1 joerg }
1357 1.1 joerg *destreg = (uint32_t)res;
1358 1.1 joerg }
1359 1.1 joerg
1360 1.1 joerg static void
1361 1.1 joerg common_imul_word_IMM(struct X86EMU *emu, bool byte_imm)
1362 1.1 joerg {
1363 1.1 joerg uint32_t srcoffset;
1364 1.1 joerg uint16_t *destreg, srcval;
1365 1.1 joerg int16_t imm;
1366 1.1 joerg uint32_t res;
1367 1.1 joerg
1368 1.1 joerg fetch_decode_modrm(emu);
1369 1.1 joerg destreg = decode_rh_word_register(emu);
1370 1.1 joerg if (emu->cur_mod != 3) {
1371 1.1 joerg srcoffset = decode_rl_address(emu);
1372 1.1 joerg srcval = fetch_data_word(emu, srcoffset);
1373 1.1 joerg } else {
1374 1.1 joerg srcval = *decode_rl_word_register(emu);
1375 1.1 joerg }
1376 1.1 joerg
1377 1.1 joerg if (byte_imm)
1378 1.1 joerg imm = (int8_t)fetch_byte_imm(emu);
1379 1.1 joerg else
1380 1.1 joerg imm = fetch_word_imm(emu);
1381 1.1 joerg res = (int16_t)srcval * imm;
1382 1.1 joerg
1383 1.1 joerg if (res > 0xffff) {
1384 1.1 joerg SET_FLAG(F_CF);
1385 1.1 joerg SET_FLAG(F_OF);
1386 1.1 joerg } else {
1387 1.1 joerg CLEAR_FLAG(F_CF);
1388 1.1 joerg CLEAR_FLAG(F_OF);
1389 1.1 joerg }
1390 1.1 joerg *destreg = (uint16_t) res;
1391 1.1 joerg }
1392 1.1 joerg
1393 1.1 joerg static void
1394 1.1 joerg common_imul_imm(struct X86EMU *emu, bool byte_imm)
1395 1.1 joerg {
1396 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1397 1.1 joerg common_imul_long_IMM(emu, byte_imm);
1398 1.1 joerg else
1399 1.1 joerg common_imul_word_IMM(emu, byte_imm);
1400 1.1 joerg }
1401 1.1 joerg
1402 1.1 joerg static void
1403 1.1 joerg common_jmp_near(struct X86EMU *emu, bool cond)
1404 1.1 joerg {
1405 1.1 joerg int8_t offset;
1406 1.1 joerg uint16_t target;
1407 1.1 joerg
1408 1.1 joerg offset = (int8_t) fetch_byte_imm(emu);
1409 1.1 joerg target = (uint16_t) (emu->x86.R_IP + (int16_t) offset);
1410 1.1 joerg if (cond)
1411 1.1 joerg emu->x86.R_IP = target;
1412 1.1 joerg }
1413 1.1 joerg
1414 1.1 joerg static void
1415 1.1 joerg common_load_far_pointer(struct X86EMU *emu, uint16_t *seg)
1416 1.1 joerg {
1417 1.1 joerg uint16_t *dstreg;
1418 1.1 joerg uint32_t srcoffset;
1419 1.1 joerg
1420 1.1 joerg fetch_decode_modrm(emu);
1421 1.1 joerg if (emu->cur_mod == 3)
1422 1.1 joerg X86EMU_halt_sys(emu);
1423 1.1 joerg
1424 1.1 joerg dstreg = decode_rh_word_register(emu);
1425 1.1 joerg srcoffset = decode_rl_address(emu);
1426 1.1 joerg *dstreg = fetch_data_word(emu, srcoffset);
1427 1.1 joerg *seg = fetch_data_word(emu, srcoffset + 2);
1428 1.1 joerg }
1429 1.1 joerg
1430 1.1 joerg /*----------------------------- Implementation ----------------------------*/
1431 1.1 joerg /****************************************************************************
1432 1.1 joerg REMARKS:
1433 1.1 joerg Handles opcode 0x3a
1434 1.1 joerg ****************************************************************************/
1435 1.1 joerg static void
1436 1.1 joerg x86emuOp_cmp_byte_R_RM(struct X86EMU *emu)
1437 1.1 joerg {
1438 1.1 joerg uint8_t *destreg, srcval;
1439 1.1 joerg
1440 1.1 joerg fetch_decode_modrm(emu);
1441 1.1 joerg destreg = decode_rh_byte_register(emu);
1442 1.1 joerg srcval = decode_and_fetch_byte(emu);
1443 1.1 joerg cmp_byte(emu, *destreg, srcval);
1444 1.1 joerg }
1445 1.1 joerg /****************************************************************************
1446 1.1 joerg REMARKS:
1447 1.1 joerg Handles opcode 0x3b
1448 1.1 joerg ****************************************************************************/
1449 1.1 joerg static void
1450 1.1 joerg x86emuOp32_cmp_word_R_RM(struct X86EMU *emu)
1451 1.1 joerg {
1452 1.1 joerg uint32_t srcval, *destreg;
1453 1.1 joerg
1454 1.1 joerg fetch_decode_modrm(emu);
1455 1.1 joerg destreg = decode_rh_long_register(emu);
1456 1.1 joerg srcval = decode_and_fetch_long(emu);
1457 1.1 joerg cmp_long(emu, *destreg, srcval);
1458 1.1 joerg }
1459 1.1 joerg
1460 1.1 joerg static void
1461 1.1 joerg x86emuOp16_cmp_word_R_RM(struct X86EMU *emu)
1462 1.1 joerg {
1463 1.1 joerg uint16_t srcval, *destreg;
1464 1.1 joerg
1465 1.1 joerg fetch_decode_modrm(emu);
1466 1.1 joerg destreg = decode_rh_word_register(emu);
1467 1.1 joerg srcval = decode_and_fetch_word(emu);
1468 1.1 joerg cmp_word(emu, *destreg, srcval);
1469 1.1 joerg }
1470 1.1 joerg
1471 1.1 joerg static void
1472 1.1 joerg x86emuOp_cmp_word_R_RM(struct X86EMU *emu)
1473 1.1 joerg {
1474 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1475 1.1 joerg x86emuOp32_cmp_word_R_RM(emu);
1476 1.1 joerg else
1477 1.1 joerg x86emuOp16_cmp_word_R_RM(emu);
1478 1.1 joerg }
1479 1.1 joerg /****************************************************************************
1480 1.1 joerg REMARKS:
1481 1.1 joerg Handles opcode 0x3c
1482 1.1 joerg ****************************************************************************/
1483 1.1 joerg static void
1484 1.1 joerg x86emuOp_cmp_byte_AL_IMM(struct X86EMU *emu)
1485 1.1 joerg {
1486 1.1 joerg uint8_t srcval;
1487 1.1 joerg
1488 1.1 joerg srcval = fetch_byte_imm(emu);
1489 1.1 joerg cmp_byte(emu, emu->x86.R_AL, srcval);
1490 1.1 joerg }
1491 1.1 joerg /****************************************************************************
1492 1.1 joerg REMARKS:
1493 1.1 joerg Handles opcode 0x3d
1494 1.1 joerg ****************************************************************************/
1495 1.1 joerg static void
1496 1.1 joerg x86emuOp32_cmp_word_AX_IMM(struct X86EMU *emu)
1497 1.1 joerg {
1498 1.1 joerg uint32_t srcval;
1499 1.1 joerg
1500 1.1 joerg srcval = fetch_long_imm(emu);
1501 1.1 joerg cmp_long(emu, emu->x86.R_EAX, srcval);
1502 1.1 joerg }
1503 1.1 joerg
1504 1.1 joerg static void
1505 1.1 joerg x86emuOp16_cmp_word_AX_IMM(struct X86EMU *emu)
1506 1.1 joerg {
1507 1.1 joerg uint16_t srcval;
1508 1.1 joerg
1509 1.1 joerg srcval = fetch_word_imm(emu);
1510 1.1 joerg cmp_word(emu, emu->x86.R_AX, srcval);
1511 1.1 joerg }
1512 1.1 joerg
1513 1.1 joerg static void
1514 1.1 joerg x86emuOp_cmp_word_AX_IMM(struct X86EMU *emu)
1515 1.1 joerg {
1516 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1517 1.1 joerg x86emuOp32_cmp_word_AX_IMM(emu);
1518 1.1 joerg else
1519 1.1 joerg x86emuOp16_cmp_word_AX_IMM(emu);
1520 1.1 joerg }
1521 1.1 joerg /****************************************************************************
1522 1.1 joerg REMARKS:
1523 1.1 joerg Handles opcode 0x60
1524 1.1 joerg ****************************************************************************/
1525 1.1 joerg static void
1526 1.1 joerg x86emuOp_push_all(struct X86EMU *emu)
1527 1.1 joerg {
1528 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1529 1.1 joerg uint32_t old_sp = emu->x86.R_ESP;
1530 1.1 joerg
1531 1.1 joerg push_long(emu, emu->x86.R_EAX);
1532 1.1 joerg push_long(emu, emu->x86.R_ECX);
1533 1.1 joerg push_long(emu, emu->x86.R_EDX);
1534 1.1 joerg push_long(emu, emu->x86.R_EBX);
1535 1.1 joerg push_long(emu, old_sp);
1536 1.1 joerg push_long(emu, emu->x86.R_EBP);
1537 1.1 joerg push_long(emu, emu->x86.R_ESI);
1538 1.1 joerg push_long(emu, emu->x86.R_EDI);
1539 1.1 joerg } else {
1540 1.1 joerg uint16_t old_sp = emu->x86.R_SP;
1541 1.1 joerg
1542 1.1 joerg push_word(emu, emu->x86.R_AX);
1543 1.1 joerg push_word(emu, emu->x86.R_CX);
1544 1.1 joerg push_word(emu, emu->x86.R_DX);
1545 1.1 joerg push_word(emu, emu->x86.R_BX);
1546 1.1 joerg push_word(emu, old_sp);
1547 1.1 joerg push_word(emu, emu->x86.R_BP);
1548 1.1 joerg push_word(emu, emu->x86.R_SI);
1549 1.1 joerg push_word(emu, emu->x86.R_DI);
1550 1.1 joerg }
1551 1.1 joerg }
1552 1.1 joerg /****************************************************************************
1553 1.1 joerg REMARKS:
1554 1.1 joerg Handles opcode 0x61
1555 1.1 joerg ****************************************************************************/
1556 1.1 joerg static void
1557 1.1 joerg x86emuOp_pop_all(struct X86EMU *emu)
1558 1.1 joerg {
1559 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1560 1.1 joerg emu->x86.R_EDI = pop_long(emu);
1561 1.1 joerg emu->x86.R_ESI = pop_long(emu);
1562 1.1 joerg emu->x86.R_EBP = pop_long(emu);
1563 1.1 joerg emu->x86.R_ESP += 4; /* skip ESP */
1564 1.1 joerg emu->x86.R_EBX = pop_long(emu);
1565 1.1 joerg emu->x86.R_EDX = pop_long(emu);
1566 1.1 joerg emu->x86.R_ECX = pop_long(emu);
1567 1.1 joerg emu->x86.R_EAX = pop_long(emu);
1568 1.1 joerg } else {
1569 1.1 joerg emu->x86.R_DI = pop_word(emu);
1570 1.1 joerg emu->x86.R_SI = pop_word(emu);
1571 1.1 joerg emu->x86.R_BP = pop_word(emu);
1572 1.1 joerg emu->x86.R_SP += 2;/* skip SP */
1573 1.1 joerg emu->x86.R_BX = pop_word(emu);
1574 1.1 joerg emu->x86.R_DX = pop_word(emu);
1575 1.1 joerg emu->x86.R_CX = pop_word(emu);
1576 1.1 joerg emu->x86.R_AX = pop_word(emu);
1577 1.1 joerg }
1578 1.1 joerg }
1579 1.1 joerg /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
1580 1.1 joerg /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
1581 1.1 joerg
1582 1.1 joerg /****************************************************************************
1583 1.1 joerg REMARKS:
1584 1.1 joerg Handles opcode 0x68
1585 1.1 joerg ****************************************************************************/
1586 1.1 joerg static void
1587 1.1 joerg x86emuOp_push_word_IMM(struct X86EMU *emu)
1588 1.1 joerg {
1589 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1590 1.1 joerg uint32_t imm;
1591 1.1 joerg
1592 1.1 joerg imm = fetch_long_imm(emu);
1593 1.1 joerg push_long(emu, imm);
1594 1.1 joerg } else {
1595 1.1 joerg uint16_t imm;
1596 1.1 joerg
1597 1.1 joerg imm = fetch_word_imm(emu);
1598 1.1 joerg push_word(emu, imm);
1599 1.1 joerg }
1600 1.1 joerg }
1601 1.1 joerg /****************************************************************************
1602 1.1 joerg REMARKS:
1603 1.1 joerg Handles opcode 0x6a
1604 1.1 joerg ****************************************************************************/
1605 1.1 joerg static void
1606 1.1 joerg x86emuOp_push_byte_IMM(struct X86EMU *emu)
1607 1.1 joerg {
1608 1.1 joerg int16_t imm;
1609 1.1 joerg
1610 1.1 joerg imm = (int8_t) fetch_byte_imm(emu);
1611 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1612 1.1 joerg push_long(emu, (int32_t) imm);
1613 1.1 joerg } else {
1614 1.1 joerg push_word(emu, imm);
1615 1.1 joerg }
1616 1.1 joerg }
1617 1.1 joerg /****************************************************************************
1618 1.1 joerg REMARKS:
1619 1.1 joerg Handles opcode 0x6c
1620 1.1 joerg ****************************************************************************/
1621 1.1 joerg /****************************************************************************
1622 1.1 joerg REMARKS:
1623 1.1 joerg Handles opcode 0x6d
1624 1.1 joerg ****************************************************************************/
1625 1.1 joerg static void
1626 1.1 joerg x86emuOp_ins_word(struct X86EMU *emu)
1627 1.1 joerg {
1628 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1629 1.1 joerg ins(emu, 4);
1630 1.1 joerg } else {
1631 1.1 joerg ins(emu, 2);
1632 1.1 joerg }
1633 1.1 joerg }
1634 1.1 joerg /****************************************************************************
1635 1.1 joerg REMARKS:
1636 1.1 joerg Handles opcode 0x6f
1637 1.1 joerg ****************************************************************************/
1638 1.1 joerg static void
1639 1.1 joerg x86emuOp_outs_word(struct X86EMU *emu)
1640 1.1 joerg {
1641 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
1642 1.1 joerg outs(emu, 4);
1643 1.1 joerg } else {
1644 1.1 joerg outs(emu, 2);
1645 1.1 joerg }
1646 1.1 joerg }
1647 1.1 joerg /****************************************************************************
1648 1.1 joerg REMARKS:
1649 1.1 joerg Handles opcode 0x7c
1650 1.1 joerg ****************************************************************************/
1651 1.1 joerg static void
1652 1.1 joerg x86emuOp_jump_near_L(struct X86EMU *emu)
1653 1.1 joerg {
1654 1.1 joerg bool sf, of;
1655 1.1 joerg
1656 1.1 joerg sf = ACCESS_FLAG(F_SF) != 0;
1657 1.1 joerg of = ACCESS_FLAG(F_OF) != 0;
1658 1.1 joerg
1659 1.1 joerg common_jmp_near(emu, sf != of);
1660 1.1 joerg }
1661 1.1 joerg /****************************************************************************
1662 1.1 joerg REMARKS:
1663 1.1 joerg Handles opcode 0x7d
1664 1.1 joerg ****************************************************************************/
1665 1.1 joerg static void
1666 1.1 joerg x86emuOp_jump_near_NL(struct X86EMU *emu)
1667 1.1 joerg {
1668 1.1 joerg bool sf, of;
1669 1.1 joerg
1670 1.1 joerg sf = ACCESS_FLAG(F_SF) != 0;
1671 1.1 joerg of = ACCESS_FLAG(F_OF) != 0;
1672 1.1 joerg
1673 1.1 joerg common_jmp_near(emu, sf == of);
1674 1.1 joerg }
1675 1.1 joerg /****************************************************************************
1676 1.1 joerg REMARKS:
1677 1.1 joerg Handles opcode 0x7e
1678 1.1 joerg ****************************************************************************/
1679 1.1 joerg static void
1680 1.1 joerg x86emuOp_jump_near_LE(struct X86EMU *emu)
1681 1.1 joerg {
1682 1.1 joerg bool sf, of;
1683 1.1 joerg
1684 1.1 joerg sf = ACCESS_FLAG(F_SF) != 0;
1685 1.1 joerg of = ACCESS_FLAG(F_OF) != 0;
1686 1.1 joerg
1687 1.1 joerg common_jmp_near(emu, sf != of || ACCESS_FLAG(F_ZF));
1688 1.1 joerg }
1689 1.1 joerg /****************************************************************************
1690 1.1 joerg REMARKS:
1691 1.1 joerg Handles opcode 0x7f
1692 1.1 joerg ****************************************************************************/
1693 1.1 joerg static void
1694 1.1 joerg x86emuOp_jump_near_NLE(struct X86EMU *emu)
1695 1.1 joerg {
1696 1.1 joerg bool sf, of;
1697 1.1 joerg
1698 1.1 joerg sf = ACCESS_FLAG(F_SF) != 0;
1699 1.1 joerg of = ACCESS_FLAG(F_OF) != 0;
1700 1.1 joerg
1701 1.1 joerg common_jmp_near(emu, sf == of && !ACCESS_FLAG(F_ZF));
1702 1.1 joerg }
1703 1.1 joerg
1704 1.1 joerg static
1705 1.1 joerg uint8_t(*const opc80_byte_operation[]) (struct X86EMU *, uint8_t d, uint8_t s) =
1706 1.1 joerg {
1707 1.1 joerg add_byte, /* 00 */
1708 1.1 joerg or_byte, /* 01 */
1709 1.1 joerg adc_byte, /* 02 */
1710 1.1 joerg sbb_byte, /* 03 */
1711 1.1 joerg and_byte, /* 04 */
1712 1.1 joerg sub_byte, /* 05 */
1713 1.1 joerg xor_byte, /* 06 */
1714 1.1 joerg cmp_byte, /* 07 */
1715 1.1 joerg };
1716 1.1 joerg /****************************************************************************
1717 1.1 joerg REMARKS:
1718 1.1 joerg Handles opcode 0x80
1719 1.1 joerg ****************************************************************************/
1720 1.1 joerg static void
1721 1.1 joerg x86emuOp_opc80_byte_RM_IMM(struct X86EMU *emu)
1722 1.1 joerg {
1723 1.1 joerg uint8_t imm, destval;
1724 1.1 joerg
1725 1.1 joerg /*
1726 1.1 joerg * Weirdo special case instruction format. Part of the opcode
1727 1.1 joerg * held below in "RH". Doubly nested case would result, except
1728 1.1 joerg * that the decoded instruction
1729 1.1 joerg */
1730 1.1 joerg fetch_decode_modrm(emu);
1731 1.1 joerg destval = decode_and_fetch_byte(emu);
1732 1.1 joerg imm = fetch_byte_imm(emu);
1733 1.1 joerg destval = (*opc80_byte_operation[emu->cur_rh]) (emu, destval, imm);
1734 1.1 joerg if (emu->cur_rh != 7)
1735 1.1 joerg write_back_byte(emu, destval);
1736 1.1 joerg }
1737 1.1 joerg
1738 1.1 joerg static
1739 1.1 joerg uint16_t(* const opc81_word_operation[]) (struct X86EMU *, uint16_t d, uint16_t s) =
1740 1.1 joerg {
1741 1.1 joerg add_word, /* 00 */
1742 1.1 joerg or_word, /* 01 */
1743 1.1 joerg adc_word, /* 02 */
1744 1.1 joerg sbb_word, /* 03 */
1745 1.1 joerg and_word, /* 04 */
1746 1.1 joerg sub_word, /* 05 */
1747 1.1 joerg xor_word, /* 06 */
1748 1.1 joerg cmp_word, /* 07 */
1749 1.1 joerg };
1750 1.1 joerg
1751 1.1 joerg static
1752 1.1 joerg uint32_t(* const opc81_long_operation[]) (struct X86EMU *, uint32_t d, uint32_t s) =
1753 1.1 joerg {
1754 1.1 joerg add_long, /* 00 */
1755 1.1 joerg or_long, /* 01 */
1756 1.1 joerg adc_long, /* 02 */
1757 1.1 joerg sbb_long, /* 03 */
1758 1.1 joerg and_long, /* 04 */
1759 1.1 joerg sub_long, /* 05 */
1760 1.1 joerg xor_long, /* 06 */
1761 1.1 joerg cmp_long, /* 07 */
1762 1.1 joerg };
1763 1.1 joerg /****************************************************************************
1764 1.1 joerg REMARKS:
1765 1.1 joerg Handles opcode 0x81
1766 1.1 joerg ****************************************************************************/
1767 1.1 joerg static void
1768 1.1 joerg x86emuOp32_opc81_word_RM_IMM(struct X86EMU *emu)
1769 1.1 joerg {
1770 1.1 joerg uint32_t destval, imm;
1771 1.1 joerg
1772 1.1 joerg /*
1773 1.1 joerg * Weirdo special case instruction format. Part of the opcode
1774 1.1 joerg * held below in "RH". Doubly nested case would result, except
1775 1.1 joerg * that the decoded instruction
1776 1.1 joerg */
1777 1.1 joerg fetch_decode_modrm(emu);
1778 1.1 joerg destval = decode_and_fetch_long(emu);
1779 1.1 joerg imm = fetch_long_imm(emu);
1780 1.1 joerg destval = (*opc81_long_operation[emu->cur_rh]) (emu, destval, imm);
1781 1.1 joerg if (emu->cur_rh != 7)
1782 1.1 joerg write_back_long(emu, destval);
1783 1.1 joerg }
1784 1.1 joerg
1785 1.1 joerg static void
1786 1.1 joerg x86emuOp16_opc81_word_RM_IMM(struct X86EMU *emu)
1787 1.1 joerg {
1788 1.1 joerg uint16_t destval, imm;
1789 1.1 joerg
1790 1.1 joerg /*
1791 1.1 joerg * Weirdo special case instruction format. Part of the opcode
1792 1.1 joerg * held below in "RH". Doubly nested case would result, except
1793 1.1 joerg * that the decoded instruction
1794 1.1 joerg */
1795 1.1 joerg fetch_decode_modrm(emu);
1796 1.1 joerg destval = decode_and_fetch_word(emu);
1797 1.1 joerg imm = fetch_word_imm(emu);
1798 1.1 joerg destval = (*opc81_word_operation[emu->cur_rh]) (emu, destval, imm);
1799 1.1 joerg if (emu->cur_rh != 7)
1800 1.1 joerg write_back_word(emu, destval);
1801 1.1 joerg }
1802 1.1 joerg
1803 1.1 joerg static void
1804 1.1 joerg x86emuOp_opc81_word_RM_IMM(struct X86EMU *emu)
1805 1.1 joerg {
1806 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1807 1.1 joerg x86emuOp32_opc81_word_RM_IMM(emu);
1808 1.1 joerg else
1809 1.1 joerg x86emuOp16_opc81_word_RM_IMM(emu);
1810 1.1 joerg }
1811 1.1 joerg
1812 1.1 joerg static
1813 1.1 joerg uint8_t(* const opc82_byte_operation[]) (struct X86EMU *, uint8_t s, uint8_t d) =
1814 1.1 joerg {
1815 1.1 joerg add_byte, /* 00 */
1816 1.1 joerg or_byte, /* 01 *//* YYY UNUSED ???? */
1817 1.1 joerg adc_byte, /* 02 */
1818 1.1 joerg sbb_byte, /* 03 */
1819 1.1 joerg and_byte, /* 04 *//* YYY UNUSED ???? */
1820 1.1 joerg sub_byte, /* 05 */
1821 1.1 joerg xor_byte, /* 06 *//* YYY UNUSED ???? */
1822 1.1 joerg cmp_byte, /* 07 */
1823 1.1 joerg };
1824 1.1 joerg /****************************************************************************
1825 1.1 joerg REMARKS:
1826 1.1 joerg Handles opcode 0x82
1827 1.1 joerg ****************************************************************************/
1828 1.1 joerg static void
1829 1.1 joerg x86emuOp_opc82_byte_RM_IMM(struct X86EMU *emu)
1830 1.1 joerg {
1831 1.1 joerg uint8_t imm, destval;
1832 1.1 joerg
1833 1.1 joerg /*
1834 1.1 joerg * Weirdo special case instruction format. Part of the opcode
1835 1.1 joerg * held below in "RH". Doubly nested case would result, except
1836 1.1 joerg * that the decoded instruction Similar to opcode 81, except that
1837 1.1 joerg * the immediate byte is sign extended to a word length.
1838 1.1 joerg */
1839 1.1 joerg fetch_decode_modrm(emu);
1840 1.1 joerg destval = decode_and_fetch_byte(emu);
1841 1.1 joerg imm = fetch_byte_imm(emu);
1842 1.1 joerg destval = (*opc82_byte_operation[emu->cur_rh]) (emu, destval, imm);
1843 1.1 joerg if (emu->cur_rh != 7)
1844 1.1 joerg write_back_byte(emu, destval);
1845 1.1 joerg }
1846 1.1 joerg
1847 1.1 joerg static
1848 1.1 joerg uint16_t(* const opc83_word_operation[]) (struct X86EMU *, uint16_t s, uint16_t d) =
1849 1.1 joerg {
1850 1.1 joerg add_word, /* 00 */
1851 1.1 joerg or_word, /* 01 *//* YYY UNUSED ???? */
1852 1.1 joerg adc_word, /* 02 */
1853 1.1 joerg sbb_word, /* 03 */
1854 1.1 joerg and_word, /* 04 *//* YYY UNUSED ???? */
1855 1.1 joerg sub_word, /* 05 */
1856 1.1 joerg xor_word, /* 06 *//* YYY UNUSED ???? */
1857 1.1 joerg cmp_word, /* 07 */
1858 1.1 joerg };
1859 1.1 joerg
1860 1.1 joerg static
1861 1.1 joerg uint32_t(* const opc83_long_operation[]) (struct X86EMU *, uint32_t s, uint32_t d) =
1862 1.1 joerg {
1863 1.1 joerg add_long, /* 00 */
1864 1.1 joerg or_long, /* 01 *//* YYY UNUSED ???? */
1865 1.1 joerg adc_long, /* 02 */
1866 1.1 joerg sbb_long, /* 03 */
1867 1.1 joerg and_long, /* 04 *//* YYY UNUSED ???? */
1868 1.1 joerg sub_long, /* 05 */
1869 1.1 joerg xor_long, /* 06 *//* YYY UNUSED ???? */
1870 1.1 joerg cmp_long, /* 07 */
1871 1.1 joerg };
1872 1.1 joerg /****************************************************************************
1873 1.1 joerg REMARKS:
1874 1.1 joerg Handles opcode 0x83
1875 1.1 joerg ****************************************************************************/
1876 1.1 joerg static void
1877 1.1 joerg x86emuOp32_opc83_word_RM_IMM(struct X86EMU *emu)
1878 1.1 joerg {
1879 1.1 joerg uint32_t destval, imm;
1880 1.1 joerg
1881 1.1 joerg fetch_decode_modrm(emu);
1882 1.1 joerg destval = decode_and_fetch_long(emu);
1883 1.1 joerg imm = (int8_t) fetch_byte_imm(emu);
1884 1.1 joerg destval = (*opc83_long_operation[emu->cur_rh]) (emu, destval, imm);
1885 1.1 joerg if (emu->cur_rh != 7)
1886 1.1 joerg write_back_long(emu, destval);
1887 1.1 joerg }
1888 1.1 joerg
1889 1.1 joerg static void
1890 1.1 joerg x86emuOp16_opc83_word_RM_IMM(struct X86EMU *emu)
1891 1.1 joerg {
1892 1.1 joerg uint16_t destval, imm;
1893 1.1 joerg
1894 1.1 joerg fetch_decode_modrm(emu);
1895 1.1 joerg destval = decode_and_fetch_word(emu);
1896 1.1 joerg imm = (int8_t) fetch_byte_imm(emu);
1897 1.1 joerg destval = (*opc83_word_operation[emu->cur_rh]) (emu, destval, imm);
1898 1.1 joerg if (emu->cur_rh != 7)
1899 1.1 joerg write_back_word(emu, destval);
1900 1.1 joerg }
1901 1.1 joerg
1902 1.1 joerg static void
1903 1.1 joerg x86emuOp_opc83_word_RM_IMM(struct X86EMU *emu)
1904 1.1 joerg {
1905 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1906 1.1 joerg x86emuOp32_opc83_word_RM_IMM(emu);
1907 1.1 joerg else
1908 1.1 joerg x86emuOp16_opc83_word_RM_IMM(emu);
1909 1.1 joerg }
1910 1.1 joerg /****************************************************************************
1911 1.1 joerg REMARKS:
1912 1.1 joerg Handles opcode 0x86
1913 1.1 joerg ****************************************************************************/
1914 1.1 joerg static void
1915 1.1 joerg x86emuOp_xchg_byte_RM_R(struct X86EMU *emu)
1916 1.1 joerg {
1917 1.1 joerg uint8_t *srcreg, destval, tmp;
1918 1.1 joerg
1919 1.1 joerg fetch_decode_modrm(emu);
1920 1.1 joerg destval = decode_and_fetch_byte(emu);
1921 1.1 joerg srcreg = decode_rh_byte_register(emu);
1922 1.1 joerg tmp = destval;
1923 1.1 joerg destval = *srcreg;
1924 1.1 joerg *srcreg = tmp;
1925 1.1 joerg write_back_byte(emu, destval);
1926 1.1 joerg }
1927 1.1 joerg /****************************************************************************
1928 1.1 joerg REMARKS:
1929 1.1 joerg Handles opcode 0x87
1930 1.1 joerg ****************************************************************************/
1931 1.1 joerg static void
1932 1.1 joerg x86emuOp32_xchg_word_RM_R(struct X86EMU *emu)
1933 1.1 joerg {
1934 1.1 joerg uint32_t *srcreg, destval, tmp;
1935 1.1 joerg
1936 1.1 joerg fetch_decode_modrm(emu);
1937 1.1 joerg destval = decode_and_fetch_long(emu);
1938 1.1 joerg srcreg = decode_rh_long_register(emu);
1939 1.1 joerg tmp = destval;
1940 1.1 joerg destval = *srcreg;
1941 1.1 joerg *srcreg = tmp;
1942 1.1 joerg write_back_long(emu, destval);
1943 1.1 joerg }
1944 1.1 joerg
1945 1.1 joerg static void
1946 1.1 joerg x86emuOp16_xchg_word_RM_R(struct X86EMU *emu)
1947 1.1 joerg {
1948 1.1 joerg uint16_t *srcreg, destval, tmp;
1949 1.1 joerg
1950 1.1 joerg fetch_decode_modrm(emu);
1951 1.1 joerg destval = decode_and_fetch_word(emu);
1952 1.1 joerg srcreg = decode_rh_word_register(emu);
1953 1.1 joerg tmp = destval;
1954 1.1 joerg destval = *srcreg;
1955 1.1 joerg *srcreg = tmp;
1956 1.1 joerg write_back_word(emu, destval);
1957 1.1 joerg }
1958 1.1 joerg
1959 1.1 joerg static void
1960 1.1 joerg x86emuOp_xchg_word_RM_R(struct X86EMU *emu)
1961 1.1 joerg {
1962 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
1963 1.1 joerg x86emuOp32_xchg_word_RM_R(emu);
1964 1.1 joerg else
1965 1.1 joerg x86emuOp16_xchg_word_RM_R(emu);
1966 1.1 joerg }
1967 1.1 joerg /****************************************************************************
1968 1.1 joerg REMARKS:
1969 1.1 joerg Handles opcode 0x88
1970 1.1 joerg ****************************************************************************/
1971 1.1 joerg static void
1972 1.1 joerg x86emuOp_mov_byte_RM_R(struct X86EMU *emu)
1973 1.1 joerg {
1974 1.1 joerg uint8_t *destreg, *srcreg;
1975 1.1 joerg uint32_t destoffset;
1976 1.1 joerg
1977 1.1 joerg fetch_decode_modrm(emu);
1978 1.1 joerg srcreg = decode_rh_byte_register(emu);
1979 1.1 joerg if (emu->cur_mod != 3) {
1980 1.1 joerg destoffset = decode_rl_address(emu);
1981 1.1 joerg store_data_byte(emu, destoffset, *srcreg);
1982 1.1 joerg } else {
1983 1.1 joerg destreg = decode_rl_byte_register(emu);
1984 1.1 joerg *destreg = *srcreg;
1985 1.1 joerg }
1986 1.1 joerg }
1987 1.1 joerg /****************************************************************************
1988 1.1 joerg REMARKS:
1989 1.1 joerg Handles opcode 0x89
1990 1.1 joerg ****************************************************************************/
1991 1.1 joerg static void
1992 1.1 joerg x86emuOp32_mov_word_RM_R(struct X86EMU *emu)
1993 1.1 joerg {
1994 1.1 joerg uint32_t destoffset;
1995 1.1 joerg uint32_t *destreg, srcval;
1996 1.1 joerg
1997 1.1 joerg fetch_decode_modrm(emu);
1998 1.1 joerg srcval = *decode_rh_long_register(emu);
1999 1.1 joerg if (emu->cur_mod != 3) {
2000 1.1 joerg destoffset = decode_rl_address(emu);
2001 1.1 joerg store_data_long(emu, destoffset, srcval);
2002 1.1 joerg } else {
2003 1.1 joerg destreg = decode_rl_long_register(emu);
2004 1.1 joerg *destreg = srcval;
2005 1.1 joerg }
2006 1.1 joerg }
2007 1.1 joerg
2008 1.1 joerg static void
2009 1.1 joerg x86emuOp16_mov_word_RM_R(struct X86EMU *emu)
2010 1.1 joerg {
2011 1.1 joerg uint32_t destoffset;
2012 1.1 joerg uint16_t *destreg, srcval;
2013 1.1 joerg
2014 1.1 joerg fetch_decode_modrm(emu);
2015 1.1 joerg srcval = *decode_rh_word_register(emu);
2016 1.1 joerg if (emu->cur_mod != 3) {
2017 1.1 joerg destoffset = decode_rl_address(emu);
2018 1.1 joerg store_data_word(emu, destoffset, srcval);
2019 1.1 joerg } else {
2020 1.1 joerg destreg = decode_rl_word_register(emu);
2021 1.1 joerg *destreg = srcval;
2022 1.1 joerg }
2023 1.1 joerg }
2024 1.1 joerg
2025 1.1 joerg static void
2026 1.1 joerg x86emuOp_mov_word_RM_R(struct X86EMU *emu)
2027 1.1 joerg {
2028 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2029 1.1 joerg x86emuOp32_mov_word_RM_R(emu);
2030 1.1 joerg else
2031 1.1 joerg x86emuOp16_mov_word_RM_R(emu);
2032 1.1 joerg }
2033 1.1 joerg /****************************************************************************
2034 1.1 joerg REMARKS:
2035 1.1 joerg Handles opcode 0x8a
2036 1.1 joerg ****************************************************************************/
2037 1.1 joerg static void
2038 1.1 joerg x86emuOp_mov_byte_R_RM(struct X86EMU *emu)
2039 1.1 joerg {
2040 1.1 joerg uint8_t *destreg;
2041 1.1 joerg
2042 1.1 joerg fetch_decode_modrm(emu);
2043 1.1 joerg destreg = decode_rh_byte_register(emu);
2044 1.1 joerg *destreg = decode_and_fetch_byte(emu);
2045 1.1 joerg }
2046 1.1 joerg /****************************************************************************
2047 1.1 joerg REMARKS:
2048 1.1 joerg Handles opcode 0x8b
2049 1.1 joerg ****************************************************************************/
2050 1.1 joerg static void
2051 1.1 joerg x86emuOp_mov_word_R_RM(struct X86EMU *emu)
2052 1.1 joerg {
2053 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2054 1.1 joerg uint32_t *destreg;
2055 1.1 joerg
2056 1.1 joerg fetch_decode_modrm(emu);
2057 1.1 joerg destreg = decode_rh_long_register(emu);
2058 1.1 joerg *destreg = decode_and_fetch_long(emu);
2059 1.1 joerg } else {
2060 1.1 joerg uint16_t *destreg;
2061 1.1 joerg
2062 1.1 joerg fetch_decode_modrm(emu);
2063 1.1 joerg destreg = decode_rh_word_register(emu);
2064 1.1 joerg *destreg = decode_and_fetch_word(emu);
2065 1.1 joerg }
2066 1.1 joerg }
2067 1.1 joerg /****************************************************************************
2068 1.1 joerg REMARKS:
2069 1.1 joerg Handles opcode 0x8c
2070 1.1 joerg ****************************************************************************/
2071 1.1 joerg static void
2072 1.1 joerg x86emuOp_mov_word_RM_SR(struct X86EMU *emu)
2073 1.1 joerg {
2074 1.1 joerg uint16_t *destreg, srcval;
2075 1.1 joerg uint32_t destoffset;
2076 1.1 joerg
2077 1.1 joerg fetch_decode_modrm(emu);
2078 1.1 joerg srcval = *decode_rh_seg_register(emu);
2079 1.1 joerg if (emu->cur_mod != 3) {
2080 1.1 joerg destoffset = decode_rl_address(emu);
2081 1.1 joerg store_data_word(emu, destoffset, srcval);
2082 1.1 joerg } else {
2083 1.1 joerg destreg = decode_rl_word_register(emu);
2084 1.1 joerg *destreg = srcval;
2085 1.1 joerg }
2086 1.1 joerg }
2087 1.1 joerg /****************************************************************************
2088 1.1 joerg REMARKS:
2089 1.1 joerg Handles opcode 0x8d
2090 1.1 joerg ****************************************************************************/
2091 1.1 joerg static void
2092 1.1 joerg x86emuOp_lea_word_R_M(struct X86EMU *emu)
2093 1.1 joerg {
2094 1.1 joerg uint32_t destoffset;
2095 1.1 joerg
2096 1.1 joerg fetch_decode_modrm(emu);
2097 1.1 joerg if (emu->cur_mod == 3)
2098 1.1 joerg X86EMU_halt_sys(emu);
2099 1.1 joerg
2100 1.1 joerg destoffset = decode_rl_address(emu);
2101 1.9 joerg if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
2102 1.9 joerg uint32_t *srcreg;
2103 1.9 joerg
2104 1.9 joerg srcreg = decode_rh_long_register(emu);
2105 1.9 joerg *srcreg = (uint32_t) destoffset;
2106 1.9 joerg } else {
2107 1.9 joerg uint16_t *srcreg;
2108 1.9 joerg
2109 1.9 joerg srcreg = decode_rh_word_register(emu);
2110 1.9 joerg *srcreg = (uint16_t) destoffset;
2111 1.9 joerg }
2112 1.1 joerg }
2113 1.1 joerg /****************************************************************************
2114 1.1 joerg REMARKS:
2115 1.1 joerg Handles opcode 0x8e
2116 1.1 joerg ****************************************************************************/
2117 1.1 joerg static void
2118 1.1 joerg x86emuOp_mov_word_SR_RM(struct X86EMU *emu)
2119 1.1 joerg {
2120 1.1 joerg uint16_t *destreg;
2121 1.1 joerg
2122 1.1 joerg fetch_decode_modrm(emu);
2123 1.1 joerg destreg = decode_rh_seg_register(emu);
2124 1.1 joerg *destreg = decode_and_fetch_word(emu);
2125 1.1 joerg /*
2126 1.1 joerg * Clean up, and reset all the R_xSP pointers to the correct
2127 1.1 joerg * locations. This is about 3x too much overhead (doing all the
2128 1.1 joerg * segreg ptrs when only one is needed, but this instruction
2129 1.1 joerg * *cannot* be that common, and this isn't too much work anyway.
2130 1.1 joerg */
2131 1.1 joerg }
2132 1.1 joerg /****************************************************************************
2133 1.1 joerg REMARKS:
2134 1.1 joerg Handles opcode 0x8f
2135 1.1 joerg ****************************************************************************/
2136 1.1 joerg static void
2137 1.1 joerg x86emuOp32_pop_RM(struct X86EMU *emu)
2138 1.1 joerg {
2139 1.1 joerg uint32_t destoffset;
2140 1.1 joerg uint32_t destval, *destreg;
2141 1.1 joerg
2142 1.1 joerg fetch_decode_modrm(emu);
2143 1.1 joerg if (emu->cur_mod != 3) {
2144 1.1 joerg destoffset = decode_rl_address(emu);
2145 1.1 joerg destval = pop_long(emu);
2146 1.1 joerg store_data_long(emu, destoffset, destval);
2147 1.1 joerg } else {
2148 1.1 joerg destreg = decode_rl_long_register(emu);
2149 1.1 joerg *destreg = pop_long(emu);
2150 1.1 joerg }
2151 1.1 joerg }
2152 1.1 joerg
2153 1.1 joerg static void
2154 1.1 joerg x86emuOp16_pop_RM(struct X86EMU *emu)
2155 1.1 joerg {
2156 1.1 joerg uint32_t destoffset;
2157 1.1 joerg uint16_t destval, *destreg;
2158 1.1 joerg
2159 1.1 joerg fetch_decode_modrm(emu);
2160 1.1 joerg if (emu->cur_mod != 3) {
2161 1.1 joerg destoffset = decode_rl_address(emu);
2162 1.1 joerg destval = pop_word(emu);
2163 1.1 joerg store_data_word(emu, destoffset, destval);
2164 1.1 joerg } else {
2165 1.1 joerg destreg = decode_rl_word_register(emu);
2166 1.1 joerg *destreg = pop_word(emu);
2167 1.1 joerg }
2168 1.1 joerg }
2169 1.1 joerg
2170 1.1 joerg static void
2171 1.1 joerg x86emuOp_pop_RM(struct X86EMU *emu)
2172 1.1 joerg {
2173 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2174 1.1 joerg x86emuOp32_pop_RM(emu);
2175 1.1 joerg else
2176 1.1 joerg x86emuOp16_pop_RM(emu);
2177 1.1 joerg }
2178 1.1 joerg /****************************************************************************
2179 1.1 joerg REMARKS:
2180 1.1 joerg Handles opcode 0x91
2181 1.1 joerg ****************************************************************************/
2182 1.1 joerg static void
2183 1.1 joerg x86emuOp_xchg_word_AX_CX(struct X86EMU *emu)
2184 1.1 joerg {
2185 1.1 joerg uint32_t tmp;
2186 1.1 joerg
2187 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2188 1.1 joerg tmp = emu->x86.R_EAX;
2189 1.1 joerg emu->x86.R_EAX = emu->x86.R_ECX;
2190 1.1 joerg emu->x86.R_ECX = tmp;
2191 1.1 joerg } else {
2192 1.1 joerg tmp = emu->x86.R_AX;
2193 1.1 joerg emu->x86.R_AX = emu->x86.R_CX;
2194 1.1 joerg emu->x86.R_CX = (uint16_t) tmp;
2195 1.1 joerg }
2196 1.1 joerg }
2197 1.1 joerg /****************************************************************************
2198 1.1 joerg REMARKS:
2199 1.1 joerg Handles opcode 0x92
2200 1.1 joerg ****************************************************************************/
2201 1.1 joerg static void
2202 1.1 joerg x86emuOp_xchg_word_AX_DX(struct X86EMU *emu)
2203 1.1 joerg {
2204 1.1 joerg uint32_t tmp;
2205 1.1 joerg
2206 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2207 1.1 joerg tmp = emu->x86.R_EAX;
2208 1.1 joerg emu->x86.R_EAX = emu->x86.R_EDX;
2209 1.1 joerg emu->x86.R_EDX = tmp;
2210 1.1 joerg } else {
2211 1.1 joerg tmp = emu->x86.R_AX;
2212 1.1 joerg emu->x86.R_AX = emu->x86.R_DX;
2213 1.1 joerg emu->x86.R_DX = (uint16_t) tmp;
2214 1.1 joerg }
2215 1.1 joerg }
2216 1.1 joerg /****************************************************************************
2217 1.1 joerg REMARKS:
2218 1.1 joerg Handles opcode 0x93
2219 1.1 joerg ****************************************************************************/
2220 1.1 joerg static void
2221 1.1 joerg x86emuOp_xchg_word_AX_BX(struct X86EMU *emu)
2222 1.1 joerg {
2223 1.1 joerg uint32_t tmp;
2224 1.1 joerg
2225 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2226 1.1 joerg tmp = emu->x86.R_EAX;
2227 1.1 joerg emu->x86.R_EAX = emu->x86.R_EBX;
2228 1.1 joerg emu->x86.R_EBX = tmp;
2229 1.1 joerg } else {
2230 1.1 joerg tmp = emu->x86.R_AX;
2231 1.1 joerg emu->x86.R_AX = emu->x86.R_BX;
2232 1.1 joerg emu->x86.R_BX = (uint16_t) tmp;
2233 1.1 joerg }
2234 1.1 joerg }
2235 1.1 joerg /****************************************************************************
2236 1.1 joerg REMARKS:
2237 1.1 joerg Handles opcode 0x94
2238 1.1 joerg ****************************************************************************/
2239 1.1 joerg static void
2240 1.1 joerg x86emuOp_xchg_word_AX_SP(struct X86EMU *emu)
2241 1.1 joerg {
2242 1.1 joerg uint32_t tmp;
2243 1.1 joerg
2244 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2245 1.1 joerg tmp = emu->x86.R_EAX;
2246 1.1 joerg emu->x86.R_EAX = emu->x86.R_ESP;
2247 1.1 joerg emu->x86.R_ESP = tmp;
2248 1.1 joerg } else {
2249 1.1 joerg tmp = emu->x86.R_AX;
2250 1.1 joerg emu->x86.R_AX = emu->x86.R_SP;
2251 1.1 joerg emu->x86.R_SP = (uint16_t) tmp;
2252 1.1 joerg }
2253 1.1 joerg }
2254 1.1 joerg /****************************************************************************
2255 1.1 joerg REMARKS:
2256 1.1 joerg Handles opcode 0x95
2257 1.1 joerg ****************************************************************************/
2258 1.1 joerg static void
2259 1.1 joerg x86emuOp_xchg_word_AX_BP(struct X86EMU *emu)
2260 1.1 joerg {
2261 1.1 joerg uint32_t tmp;
2262 1.1 joerg
2263 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2264 1.1 joerg tmp = emu->x86.R_EAX;
2265 1.1 joerg emu->x86.R_EAX = emu->x86.R_EBP;
2266 1.1 joerg emu->x86.R_EBP = tmp;
2267 1.1 joerg } else {
2268 1.1 joerg tmp = emu->x86.R_AX;
2269 1.1 joerg emu->x86.R_AX = emu->x86.R_BP;
2270 1.1 joerg emu->x86.R_BP = (uint16_t) tmp;
2271 1.1 joerg }
2272 1.1 joerg }
2273 1.1 joerg /****************************************************************************
2274 1.1 joerg REMARKS:
2275 1.1 joerg Handles opcode 0x96
2276 1.1 joerg ****************************************************************************/
2277 1.1 joerg static void
2278 1.1 joerg x86emuOp_xchg_word_AX_SI(struct X86EMU *emu)
2279 1.1 joerg {
2280 1.1 joerg uint32_t tmp;
2281 1.1 joerg
2282 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2283 1.1 joerg tmp = emu->x86.R_EAX;
2284 1.1 joerg emu->x86.R_EAX = emu->x86.R_ESI;
2285 1.1 joerg emu->x86.R_ESI = tmp;
2286 1.1 joerg } else {
2287 1.1 joerg tmp = emu->x86.R_AX;
2288 1.1 joerg emu->x86.R_AX = emu->x86.R_SI;
2289 1.1 joerg emu->x86.R_SI = (uint16_t) tmp;
2290 1.1 joerg }
2291 1.1 joerg }
2292 1.1 joerg /****************************************************************************
2293 1.1 joerg REMARKS:
2294 1.1 joerg Handles opcode 0x97
2295 1.1 joerg ****************************************************************************/
2296 1.1 joerg static void
2297 1.1 joerg x86emuOp_xchg_word_AX_DI(struct X86EMU *emu)
2298 1.1 joerg {
2299 1.1 joerg uint32_t tmp;
2300 1.1 joerg
2301 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2302 1.1 joerg tmp = emu->x86.R_EAX;
2303 1.1 joerg emu->x86.R_EAX = emu->x86.R_EDI;
2304 1.1 joerg emu->x86.R_EDI = tmp;
2305 1.1 joerg } else {
2306 1.1 joerg tmp = emu->x86.R_AX;
2307 1.1 joerg emu->x86.R_AX = emu->x86.R_DI;
2308 1.1 joerg emu->x86.R_DI = (uint16_t) tmp;
2309 1.1 joerg }
2310 1.1 joerg }
2311 1.1 joerg /****************************************************************************
2312 1.1 joerg REMARKS:
2313 1.1 joerg Handles opcode 0x98
2314 1.1 joerg ****************************************************************************/
2315 1.1 joerg static void
2316 1.1 joerg x86emuOp_cbw(struct X86EMU *emu)
2317 1.1 joerg {
2318 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2319 1.1 joerg if (emu->x86.R_AX & 0x8000) {
2320 1.1 joerg emu->x86.R_EAX |= 0xffff0000;
2321 1.1 joerg } else {
2322 1.1 joerg emu->x86.R_EAX &= 0x0000ffff;
2323 1.1 joerg }
2324 1.1 joerg } else {
2325 1.1 joerg if (emu->x86.R_AL & 0x80) {
2326 1.1 joerg emu->x86.R_AH = 0xff;
2327 1.1 joerg } else {
2328 1.1 joerg emu->x86.R_AH = 0x0;
2329 1.1 joerg }
2330 1.1 joerg }
2331 1.1 joerg }
2332 1.1 joerg /****************************************************************************
2333 1.1 joerg REMARKS:
2334 1.1 joerg Handles opcode 0x99
2335 1.1 joerg ****************************************************************************/
2336 1.1 joerg static void
2337 1.1 joerg x86emuOp_cwd(struct X86EMU *emu)
2338 1.1 joerg {
2339 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2340 1.1 joerg if (emu->x86.R_EAX & 0x80000000) {
2341 1.1 joerg emu->x86.R_EDX = 0xffffffff;
2342 1.1 joerg } else {
2343 1.1 joerg emu->x86.R_EDX = 0x0;
2344 1.1 joerg }
2345 1.1 joerg } else {
2346 1.1 joerg if (emu->x86.R_AX & 0x8000) {
2347 1.1 joerg emu->x86.R_DX = 0xffff;
2348 1.1 joerg } else {
2349 1.1 joerg emu->x86.R_DX = 0x0;
2350 1.1 joerg }
2351 1.1 joerg }
2352 1.1 joerg }
2353 1.1 joerg /****************************************************************************
2354 1.1 joerg REMARKS:
2355 1.1 joerg Handles opcode 0x9a
2356 1.1 joerg ****************************************************************************/
2357 1.1 joerg static void
2358 1.1 joerg x86emuOp_call_far_IMM(struct X86EMU *emu)
2359 1.1 joerg {
2360 1.1 joerg uint16_t farseg, faroff;
2361 1.1 joerg
2362 1.1 joerg faroff = fetch_word_imm(emu);
2363 1.1 joerg farseg = fetch_word_imm(emu);
2364 1.1 joerg /* XXX
2365 1.1 joerg *
2366 1.1 joerg * Hooked interrupt vectors calling into our "BIOS" will cause problems
2367 1.1 joerg * unless all intersegment stuff is checked for BIOS access. Check
2368 1.1 joerg * needed here. For moment, let it alone. */
2369 1.1 joerg push_word(emu, emu->x86.R_CS);
2370 1.1 joerg emu->x86.R_CS = farseg;
2371 1.1 joerg push_word(emu, emu->x86.R_IP);
2372 1.1 joerg emu->x86.R_IP = faroff;
2373 1.1 joerg }
2374 1.1 joerg /****************************************************************************
2375 1.1 joerg REMARKS:
2376 1.1 joerg Handles opcode 0x9c
2377 1.1 joerg ****************************************************************************/
2378 1.1 joerg static void
2379 1.1 joerg x86emuOp_pushf_word(struct X86EMU *emu)
2380 1.1 joerg {
2381 1.1 joerg uint32_t flags;
2382 1.1 joerg
2383 1.1 joerg /* clear out *all* bits not representing flags, and turn on real bits */
2384 1.1 joerg flags = (emu->x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
2385 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2386 1.1 joerg push_long(emu, flags);
2387 1.1 joerg } else {
2388 1.1 joerg push_word(emu, (uint16_t) flags);
2389 1.1 joerg }
2390 1.1 joerg }
2391 1.1 joerg /****************************************************************************
2392 1.1 joerg REMARKS:
2393 1.1 joerg Handles opcode 0x9d
2394 1.1 joerg ****************************************************************************/
2395 1.1 joerg static void
2396 1.1 joerg x86emuOp_popf_word(struct X86EMU *emu)
2397 1.1 joerg {
2398 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2399 1.1 joerg emu->x86.R_EFLG = pop_long(emu);
2400 1.1 joerg } else {
2401 1.1 joerg emu->x86.R_FLG = pop_word(emu);
2402 1.1 joerg }
2403 1.1 joerg }
2404 1.1 joerg /****************************************************************************
2405 1.1 joerg REMARKS:
2406 1.1 joerg Handles opcode 0x9e
2407 1.1 joerg ****************************************************************************/
2408 1.1 joerg static void
2409 1.1 joerg x86emuOp_sahf(struct X86EMU *emu)
2410 1.1 joerg {
2411 1.1 joerg /* clear the lower bits of the flag register */
2412 1.1 joerg emu->x86.R_FLG &= 0xffffff00;
2413 1.1 joerg /* or in the AH register into the flags register */
2414 1.1 joerg emu->x86.R_FLG |= emu->x86.R_AH;
2415 1.1 joerg }
2416 1.1 joerg /****************************************************************************
2417 1.1 joerg REMARKS:
2418 1.1 joerg Handles opcode 0x9f
2419 1.1 joerg ****************************************************************************/
2420 1.1 joerg static void
2421 1.1 joerg x86emuOp_lahf(struct X86EMU *emu)
2422 1.1 joerg {
2423 1.1 joerg emu->x86.R_AH = (uint8_t) (emu->x86.R_FLG & 0xff);
2424 1.1 joerg /* undocumented TC++ behavior??? Nope. It's documented, but you have
2425 1.1 joerg * too look real hard to notice it. */
2426 1.1 joerg emu->x86.R_AH |= 0x2;
2427 1.1 joerg }
2428 1.1 joerg /****************************************************************************
2429 1.1 joerg REMARKS:
2430 1.1 joerg Handles opcode 0xa0
2431 1.1 joerg ****************************************************************************/
2432 1.1 joerg static void
2433 1.1 joerg x86emuOp_mov_AL_M_IMM(struct X86EMU *emu)
2434 1.1 joerg {
2435 1.1 joerg uint16_t offset;
2436 1.1 joerg
2437 1.1 joerg offset = fetch_word_imm(emu);
2438 1.1 joerg emu->x86.R_AL = fetch_data_byte(emu, offset);
2439 1.1 joerg }
2440 1.1 joerg /****************************************************************************
2441 1.1 joerg REMARKS:
2442 1.1 joerg Handles opcode 0xa1
2443 1.1 joerg ****************************************************************************/
2444 1.1 joerg static void
2445 1.1 joerg x86emuOp_mov_AX_M_IMM(struct X86EMU *emu)
2446 1.1 joerg {
2447 1.1 joerg uint16_t offset;
2448 1.1 joerg
2449 1.1 joerg offset = fetch_word_imm(emu);
2450 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2451 1.1 joerg emu->x86.R_EAX = fetch_data_long(emu, offset);
2452 1.1 joerg } else {
2453 1.1 joerg emu->x86.R_AX = fetch_data_word(emu, offset);
2454 1.1 joerg }
2455 1.1 joerg }
2456 1.1 joerg /****************************************************************************
2457 1.1 joerg REMARKS:
2458 1.1 joerg Handles opcode 0xa2
2459 1.1 joerg ****************************************************************************/
2460 1.1 joerg static void
2461 1.1 joerg x86emuOp_mov_M_AL_IMM(struct X86EMU *emu)
2462 1.1 joerg {
2463 1.1 joerg uint16_t offset;
2464 1.1 joerg
2465 1.1 joerg offset = fetch_word_imm(emu);
2466 1.1 joerg store_data_byte(emu, offset, emu->x86.R_AL);
2467 1.1 joerg }
2468 1.1 joerg /****************************************************************************
2469 1.1 joerg REMARKS:
2470 1.1 joerg Handles opcode 0xa3
2471 1.1 joerg ****************************************************************************/
2472 1.1 joerg static void
2473 1.1 joerg x86emuOp_mov_M_AX_IMM(struct X86EMU *emu)
2474 1.1 joerg {
2475 1.1 joerg uint16_t offset;
2476 1.1 joerg
2477 1.1 joerg offset = fetch_word_imm(emu);
2478 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2479 1.1 joerg store_data_long(emu, offset, emu->x86.R_EAX);
2480 1.1 joerg } else {
2481 1.1 joerg store_data_word(emu, offset, emu->x86.R_AX);
2482 1.1 joerg }
2483 1.1 joerg }
2484 1.1 joerg /****************************************************************************
2485 1.1 joerg REMARKS:
2486 1.1 joerg Handles opcode 0xa4
2487 1.1 joerg ****************************************************************************/
2488 1.1 joerg static void
2489 1.1 joerg x86emuOp_movs_byte(struct X86EMU *emu)
2490 1.1 joerg {
2491 1.1 joerg uint8_t val;
2492 1.1 joerg uint32_t count;
2493 1.1 joerg int inc;
2494 1.1 joerg
2495 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2496 1.1 joerg inc = -1;
2497 1.1 joerg else
2498 1.1 joerg inc = 1;
2499 1.1 joerg count = 1;
2500 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2501 1.1 joerg /* dont care whether REPE or REPNE */
2502 1.1 joerg /* move them until CX is ZERO. */
2503 1.1 joerg count = emu->x86.R_CX;
2504 1.1 joerg emu->x86.R_CX = 0;
2505 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2506 1.1 joerg }
2507 1.1 joerg while (count--) {
2508 1.1 joerg val = fetch_data_byte(emu, emu->x86.R_SI);
2509 1.1 joerg store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, val);
2510 1.1 joerg emu->x86.R_SI += inc;
2511 1.1 joerg emu->x86.R_DI += inc;
2512 1.1 joerg }
2513 1.1 joerg }
2514 1.1 joerg /****************************************************************************
2515 1.1 joerg REMARKS:
2516 1.1 joerg Handles opcode 0xa5
2517 1.1 joerg ****************************************************************************/
2518 1.1 joerg static void
2519 1.1 joerg x86emuOp_movs_word(struct X86EMU *emu)
2520 1.1 joerg {
2521 1.1 joerg uint32_t val;
2522 1.1 joerg int inc;
2523 1.1 joerg uint32_t count;
2524 1.1 joerg
2525 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2526 1.1 joerg inc = 4;
2527 1.1 joerg else
2528 1.1 joerg inc = 2;
2529 1.1 joerg
2530 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2531 1.1 joerg inc = -inc;
2532 1.1 joerg
2533 1.1 joerg count = 1;
2534 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2535 1.1 joerg /* dont care whether REPE or REPNE */
2536 1.1 joerg /* move them until CX is ZERO. */
2537 1.1 joerg count = emu->x86.R_CX;
2538 1.1 joerg emu->x86.R_CX = 0;
2539 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2540 1.1 joerg }
2541 1.1 joerg while (count--) {
2542 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2543 1.1 joerg val = fetch_data_long(emu, emu->x86.R_SI);
2544 1.1 joerg store_long(emu, emu->x86.R_ES, emu->x86.R_DI, val);
2545 1.1 joerg } else {
2546 1.1 joerg val = fetch_data_word(emu, emu->x86.R_SI);
2547 1.1 joerg store_word(emu, emu->x86.R_ES, emu->x86.R_DI, (uint16_t) val);
2548 1.1 joerg }
2549 1.1 joerg emu->x86.R_SI += inc;
2550 1.1 joerg emu->x86.R_DI += inc;
2551 1.1 joerg }
2552 1.1 joerg }
2553 1.1 joerg /****************************************************************************
2554 1.1 joerg REMARKS:
2555 1.1 joerg Handles opcode 0xa6
2556 1.1 joerg ****************************************************************************/
2557 1.1 joerg static void
2558 1.1 joerg x86emuOp_cmps_byte(struct X86EMU *emu)
2559 1.1 joerg {
2560 1.1 joerg int8_t val1, val2;
2561 1.1 joerg int inc;
2562 1.1 joerg
2563 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2564 1.1 joerg inc = -1;
2565 1.1 joerg else
2566 1.1 joerg inc = 1;
2567 1.1 joerg
2568 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
2569 1.1 joerg /* REPE */
2570 1.1 joerg /* move them until CX is ZERO. */
2571 1.1 joerg while (emu->x86.R_CX != 0) {
2572 1.1 joerg val1 = fetch_data_byte(emu, emu->x86.R_SI);
2573 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2574 1.1 joerg cmp_byte(emu, val1, val2);
2575 1.1 joerg emu->x86.R_CX -= 1;
2576 1.1 joerg emu->x86.R_SI += inc;
2577 1.1 joerg emu->x86.R_DI += inc;
2578 1.1 joerg if (ACCESS_FLAG(F_ZF) == 0)
2579 1.1 joerg break;
2580 1.1 joerg }
2581 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
2582 1.1 joerg } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
2583 1.1 joerg /* REPNE */
2584 1.1 joerg /* move them until CX is ZERO. */
2585 1.1 joerg while (emu->x86.R_CX != 0) {
2586 1.1 joerg val1 = fetch_data_byte(emu, emu->x86.R_SI);
2587 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2588 1.1 joerg cmp_byte(emu, val1, val2);
2589 1.1 joerg emu->x86.R_CX -= 1;
2590 1.1 joerg emu->x86.R_SI += inc;
2591 1.1 joerg emu->x86.R_DI += inc;
2592 1.1 joerg if (ACCESS_FLAG(F_ZF))
2593 1.1 joerg break; /* zero flag set means equal */
2594 1.1 joerg }
2595 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
2596 1.1 joerg } else {
2597 1.1 joerg val1 = fetch_data_byte(emu, emu->x86.R_SI);
2598 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2599 1.1 joerg cmp_byte(emu, val1, val2);
2600 1.1 joerg emu->x86.R_SI += inc;
2601 1.1 joerg emu->x86.R_DI += inc;
2602 1.1 joerg }
2603 1.1 joerg }
2604 1.1 joerg /****************************************************************************
2605 1.1 joerg REMARKS:
2606 1.1 joerg Handles opcode 0xa7
2607 1.1 joerg ****************************************************************************/
2608 1.1 joerg static void
2609 1.1 joerg x86emuOp_cmps_word(struct X86EMU *emu)
2610 1.1 joerg {
2611 1.1 joerg uint32_t val1, val2;
2612 1.1 joerg int inc;
2613 1.1 joerg
2614 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2615 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2616 1.1 joerg inc = -4;
2617 1.1 joerg else
2618 1.1 joerg inc = 4;
2619 1.1 joerg } else {
2620 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2621 1.1 joerg inc = -2;
2622 1.1 joerg else
2623 1.1 joerg inc = 2;
2624 1.1 joerg }
2625 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
2626 1.1 joerg /* REPE */
2627 1.1 joerg /* move them until CX is ZERO. */
2628 1.1 joerg while (emu->x86.R_CX != 0) {
2629 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2630 1.1 joerg val1 = fetch_data_long(emu, emu->x86.R_SI);
2631 1.1 joerg val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2632 1.1 joerg cmp_long(emu, val1, val2);
2633 1.1 joerg } else {
2634 1.1 joerg val1 = fetch_data_word(emu, emu->x86.R_SI);
2635 1.1 joerg val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2636 1.1 joerg cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
2637 1.1 joerg }
2638 1.1 joerg emu->x86.R_CX -= 1;
2639 1.1 joerg emu->x86.R_SI += inc;
2640 1.1 joerg emu->x86.R_DI += inc;
2641 1.1 joerg if (ACCESS_FLAG(F_ZF) == 0)
2642 1.1 joerg break;
2643 1.1 joerg }
2644 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
2645 1.1 joerg } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
2646 1.1 joerg /* REPNE */
2647 1.1 joerg /* move them until CX is ZERO. */
2648 1.1 joerg while (emu->x86.R_CX != 0) {
2649 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2650 1.1 joerg val1 = fetch_data_long(emu, emu->x86.R_SI);
2651 1.1 joerg val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2652 1.1 joerg cmp_long(emu, val1, val2);
2653 1.1 joerg } else {
2654 1.1 joerg val1 = fetch_data_word(emu, emu->x86.R_SI);
2655 1.1 joerg val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2656 1.1 joerg cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
2657 1.1 joerg }
2658 1.1 joerg emu->x86.R_CX -= 1;
2659 1.1 joerg emu->x86.R_SI += inc;
2660 1.1 joerg emu->x86.R_DI += inc;
2661 1.1 joerg if (ACCESS_FLAG(F_ZF))
2662 1.1 joerg break; /* zero flag set means equal */
2663 1.1 joerg }
2664 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
2665 1.1 joerg } else {
2666 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2667 1.1 joerg val1 = fetch_data_long(emu, emu->x86.R_SI);
2668 1.1 joerg val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2669 1.1 joerg cmp_long(emu, val1, val2);
2670 1.1 joerg } else {
2671 1.1 joerg val1 = fetch_data_word(emu, emu->x86.R_SI);
2672 1.1 joerg val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2673 1.1 joerg cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
2674 1.1 joerg }
2675 1.1 joerg emu->x86.R_SI += inc;
2676 1.1 joerg emu->x86.R_DI += inc;
2677 1.1 joerg }
2678 1.1 joerg }
2679 1.1 joerg /****************************************************************************
2680 1.1 joerg REMARKS:
2681 1.1 joerg Handles opcode 0xa9
2682 1.1 joerg ****************************************************************************/
2683 1.1 joerg static void
2684 1.1 joerg x86emuOp_test_AX_IMM(struct X86EMU *emu)
2685 1.1 joerg {
2686 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2687 1.1 joerg test_long(emu, emu->x86.R_EAX, fetch_long_imm(emu));
2688 1.1 joerg } else {
2689 1.1 joerg test_word(emu, emu->x86.R_AX, fetch_word_imm(emu));
2690 1.1 joerg }
2691 1.1 joerg }
2692 1.1 joerg /****************************************************************************
2693 1.1 joerg REMARKS:
2694 1.1 joerg Handles opcode 0xaa
2695 1.1 joerg ****************************************************************************/
2696 1.1 joerg static void
2697 1.1 joerg x86emuOp_stos_byte(struct X86EMU *emu)
2698 1.1 joerg {
2699 1.1 joerg int inc;
2700 1.1 joerg
2701 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2702 1.1 joerg inc = -1;
2703 1.1 joerg else
2704 1.1 joerg inc = 1;
2705 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2706 1.1 joerg /* dont care whether REPE or REPNE */
2707 1.1 joerg /* move them until CX is ZERO. */
2708 1.1 joerg while (emu->x86.R_CX != 0) {
2709 1.1 joerg store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
2710 1.1 joerg emu->x86.R_CX -= 1;
2711 1.1 joerg emu->x86.R_DI += inc;
2712 1.1 joerg }
2713 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2714 1.1 joerg } else {
2715 1.1 joerg store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
2716 1.1 joerg emu->x86.R_DI += inc;
2717 1.1 joerg }
2718 1.1 joerg }
2719 1.1 joerg /****************************************************************************
2720 1.1 joerg REMARKS:
2721 1.1 joerg Handles opcode 0xab
2722 1.1 joerg ****************************************************************************/
2723 1.1 joerg static void
2724 1.1 joerg x86emuOp_stos_word(struct X86EMU *emu)
2725 1.1 joerg {
2726 1.1 joerg int inc;
2727 1.1 joerg uint32_t count;
2728 1.1 joerg
2729 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2730 1.1 joerg inc = 4;
2731 1.1 joerg else
2732 1.1 joerg inc = 2;
2733 1.1 joerg
2734 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2735 1.1 joerg inc = -inc;
2736 1.1 joerg
2737 1.1 joerg count = 1;
2738 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2739 1.1 joerg /* dont care whether REPE or REPNE */
2740 1.1 joerg /* move them until CX is ZERO. */
2741 1.1 joerg count = emu->x86.R_CX;
2742 1.1 joerg emu->x86.R_CX = 0;
2743 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2744 1.1 joerg }
2745 1.1 joerg while (count--) {
2746 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2747 1.1 joerg store_long(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_EAX);
2748 1.1 joerg } else {
2749 1.1 joerg store_word(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AX);
2750 1.1 joerg }
2751 1.1 joerg emu->x86.R_DI += inc;
2752 1.1 joerg }
2753 1.1 joerg }
2754 1.1 joerg /****************************************************************************
2755 1.1 joerg REMARKS:
2756 1.1 joerg Handles opcode 0xac
2757 1.1 joerg ****************************************************************************/
2758 1.1 joerg static void
2759 1.1 joerg x86emuOp_lods_byte(struct X86EMU *emu)
2760 1.1 joerg {
2761 1.1 joerg int inc;
2762 1.1 joerg
2763 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2764 1.1 joerg inc = -1;
2765 1.1 joerg else
2766 1.1 joerg inc = 1;
2767 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2768 1.1 joerg /* dont care whether REPE or REPNE */
2769 1.1 joerg /* move them until CX is ZERO. */
2770 1.1 joerg while (emu->x86.R_CX != 0) {
2771 1.1 joerg emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
2772 1.1 joerg emu->x86.R_CX -= 1;
2773 1.1 joerg emu->x86.R_SI += inc;
2774 1.1 joerg }
2775 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2776 1.1 joerg } else {
2777 1.1 joerg emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
2778 1.1 joerg emu->x86.R_SI += inc;
2779 1.1 joerg }
2780 1.1 joerg }
2781 1.1 joerg /****************************************************************************
2782 1.1 joerg REMARKS:
2783 1.1 joerg Handles opcode 0xad
2784 1.1 joerg ****************************************************************************/
2785 1.1 joerg static void
2786 1.1 joerg x86emuOp_lods_word(struct X86EMU *emu)
2787 1.1 joerg {
2788 1.1 joerg int inc;
2789 1.1 joerg uint32_t count;
2790 1.1 joerg
2791 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2792 1.1 joerg inc = 4;
2793 1.1 joerg else
2794 1.1 joerg inc = 2;
2795 1.1 joerg
2796 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2797 1.1 joerg inc = -inc;
2798 1.1 joerg
2799 1.1 joerg count = 1;
2800 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2801 1.1 joerg /* dont care whether REPE or REPNE */
2802 1.1 joerg /* move them until CX is ZERO. */
2803 1.1 joerg count = emu->x86.R_CX;
2804 1.1 joerg emu->x86.R_CX = 0;
2805 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2806 1.1 joerg }
2807 1.1 joerg while (count--) {
2808 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2809 1.1 joerg emu->x86.R_EAX = fetch_data_long(emu, emu->x86.R_SI);
2810 1.1 joerg } else {
2811 1.1 joerg emu->x86.R_AX = fetch_data_word(emu, emu->x86.R_SI);
2812 1.1 joerg }
2813 1.1 joerg emu->x86.R_SI += inc;
2814 1.1 joerg }
2815 1.1 joerg }
2816 1.1 joerg /****************************************************************************
2817 1.1 joerg REMARKS:
2818 1.1 joerg Handles opcode 0xae
2819 1.1 joerg ****************************************************************************/
2820 1.1 joerg static void
2821 1.1 joerg x86emuOp_scas_byte(struct X86EMU *emu)
2822 1.1 joerg {
2823 1.1 joerg int8_t val2;
2824 1.1 joerg int inc;
2825 1.1 joerg
2826 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2827 1.1 joerg inc = -1;
2828 1.1 joerg else
2829 1.1 joerg inc = 1;
2830 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
2831 1.1 joerg /* REPE */
2832 1.1 joerg /* move them until CX is ZERO. */
2833 1.1 joerg while (emu->x86.R_CX != 0) {
2834 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2835 1.1 joerg cmp_byte(emu, emu->x86.R_AL, val2);
2836 1.1 joerg emu->x86.R_CX -= 1;
2837 1.1 joerg emu->x86.R_DI += inc;
2838 1.1 joerg if (ACCESS_FLAG(F_ZF) == 0)
2839 1.1 joerg break;
2840 1.1 joerg }
2841 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
2842 1.1 joerg } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
2843 1.1 joerg /* REPNE */
2844 1.1 joerg /* move them until CX is ZERO. */
2845 1.1 joerg while (emu->x86.R_CX != 0) {
2846 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2847 1.1 joerg cmp_byte(emu, emu->x86.R_AL, val2);
2848 1.1 joerg emu->x86.R_CX -= 1;
2849 1.1 joerg emu->x86.R_DI += inc;
2850 1.1 joerg if (ACCESS_FLAG(F_ZF))
2851 1.1 joerg break; /* zero flag set means equal */
2852 1.1 joerg }
2853 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
2854 1.1 joerg } else {
2855 1.1 joerg val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
2856 1.1 joerg cmp_byte(emu, emu->x86.R_AL, val2);
2857 1.1 joerg emu->x86.R_DI += inc;
2858 1.1 joerg }
2859 1.1 joerg }
2860 1.1 joerg /****************************************************************************
2861 1.1 joerg REMARKS:
2862 1.1 joerg Handles opcode 0xaf
2863 1.1 joerg ****************************************************************************/
2864 1.1 joerg static void
2865 1.1 joerg x86emuOp_scas_word(struct X86EMU *emu)
2866 1.1 joerg {
2867 1.1 joerg int inc;
2868 1.1 joerg uint32_t val;
2869 1.1 joerg
2870 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2871 1.1 joerg inc = 4;
2872 1.1 joerg else
2873 1.1 joerg inc = 2;
2874 1.1 joerg
2875 1.1 joerg if (ACCESS_FLAG(F_DF)) /* down */
2876 1.1 joerg inc = -inc;
2877 1.1 joerg
2878 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
2879 1.1 joerg /* REPE */
2880 1.1 joerg /* move them until CX is ZERO. */
2881 1.1 joerg while (emu->x86.R_CX != 0) {
2882 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2883 1.1 joerg val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2884 1.1 joerg cmp_long(emu, emu->x86.R_EAX, val);
2885 1.1 joerg } else {
2886 1.1 joerg val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2887 1.1 joerg cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
2888 1.1 joerg }
2889 1.1 joerg emu->x86.R_CX -= 1;
2890 1.1 joerg emu->x86.R_DI += inc;
2891 1.1 joerg if (ACCESS_FLAG(F_ZF) == 0)
2892 1.1 joerg break;
2893 1.1 joerg }
2894 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
2895 1.1 joerg } else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
2896 1.1 joerg /* REPNE */
2897 1.1 joerg /* move them until CX is ZERO. */
2898 1.1 joerg while (emu->x86.R_CX != 0) {
2899 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2900 1.1 joerg val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2901 1.1 joerg cmp_long(emu, emu->x86.R_EAX, val);
2902 1.1 joerg } else {
2903 1.1 joerg val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2904 1.1 joerg cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
2905 1.1 joerg }
2906 1.1 joerg emu->x86.R_CX -= 1;
2907 1.1 joerg emu->x86.R_DI += inc;
2908 1.1 joerg if (ACCESS_FLAG(F_ZF))
2909 1.1 joerg break; /* zero flag set means equal */
2910 1.1 joerg }
2911 1.1 joerg emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
2912 1.1 joerg } else {
2913 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
2914 1.1 joerg val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
2915 1.1 joerg cmp_long(emu, emu->x86.R_EAX, val);
2916 1.1 joerg } else {
2917 1.1 joerg val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
2918 1.1 joerg cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
2919 1.1 joerg }
2920 1.1 joerg emu->x86.R_DI += inc;
2921 1.1 joerg }
2922 1.1 joerg }
2923 1.1 joerg /****************************************************************************
2924 1.1 joerg REMARKS:
2925 1.1 joerg Handles opcode 0xb8
2926 1.1 joerg ****************************************************************************/
2927 1.1 joerg static void
2928 1.1 joerg x86emuOp_mov_word_AX_IMM(struct X86EMU *emu)
2929 1.1 joerg {
2930 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2931 1.1 joerg emu->x86.R_EAX = fetch_long_imm(emu);
2932 1.1 joerg else
2933 1.1 joerg emu->x86.R_AX = fetch_word_imm(emu);
2934 1.1 joerg }
2935 1.1 joerg /****************************************************************************
2936 1.1 joerg REMARKS:
2937 1.1 joerg Handles opcode 0xb9
2938 1.1 joerg ****************************************************************************/
2939 1.1 joerg static void
2940 1.1 joerg x86emuOp_mov_word_CX_IMM(struct X86EMU *emu)
2941 1.1 joerg {
2942 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2943 1.1 joerg emu->x86.R_ECX = fetch_long_imm(emu);
2944 1.1 joerg else
2945 1.1 joerg emu->x86.R_CX = fetch_word_imm(emu);
2946 1.1 joerg }
2947 1.1 joerg /****************************************************************************
2948 1.1 joerg REMARKS:
2949 1.1 joerg Handles opcode 0xba
2950 1.1 joerg ****************************************************************************/
2951 1.1 joerg static void
2952 1.1 joerg x86emuOp_mov_word_DX_IMM(struct X86EMU *emu)
2953 1.1 joerg {
2954 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2955 1.1 joerg emu->x86.R_EDX = fetch_long_imm(emu);
2956 1.1 joerg else
2957 1.1 joerg emu->x86.R_DX = fetch_word_imm(emu);
2958 1.1 joerg }
2959 1.1 joerg /****************************************************************************
2960 1.1 joerg REMARKS:
2961 1.1 joerg Handles opcode 0xbb
2962 1.1 joerg ****************************************************************************/
2963 1.1 joerg static void
2964 1.1 joerg x86emuOp_mov_word_BX_IMM(struct X86EMU *emu)
2965 1.1 joerg {
2966 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2967 1.1 joerg emu->x86.R_EBX = fetch_long_imm(emu);
2968 1.1 joerg else
2969 1.1 joerg emu->x86.R_BX = fetch_word_imm(emu);
2970 1.1 joerg }
2971 1.1 joerg /****************************************************************************
2972 1.1 joerg REMARKS:
2973 1.1 joerg Handles opcode 0xbc
2974 1.1 joerg ****************************************************************************/
2975 1.1 joerg static void
2976 1.1 joerg x86emuOp_mov_word_SP_IMM(struct X86EMU *emu)
2977 1.1 joerg {
2978 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2979 1.1 joerg emu->x86.R_ESP = fetch_long_imm(emu);
2980 1.1 joerg else
2981 1.1 joerg emu->x86.R_SP = fetch_word_imm(emu);
2982 1.1 joerg }
2983 1.1 joerg /****************************************************************************
2984 1.1 joerg REMARKS:
2985 1.1 joerg Handles opcode 0xbd
2986 1.1 joerg ****************************************************************************/
2987 1.1 joerg static void
2988 1.1 joerg x86emuOp_mov_word_BP_IMM(struct X86EMU *emu)
2989 1.1 joerg {
2990 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
2991 1.1 joerg emu->x86.R_EBP = fetch_long_imm(emu);
2992 1.1 joerg else
2993 1.1 joerg emu->x86.R_BP = fetch_word_imm(emu);
2994 1.1 joerg }
2995 1.1 joerg /****************************************************************************
2996 1.1 joerg REMARKS:
2997 1.1 joerg Handles opcode 0xbe
2998 1.1 joerg ****************************************************************************/
2999 1.1 joerg static void
3000 1.1 joerg x86emuOp_mov_word_SI_IMM(struct X86EMU *emu)
3001 1.1 joerg {
3002 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
3003 1.1 joerg emu->x86.R_ESI = fetch_long_imm(emu);
3004 1.1 joerg else
3005 1.1 joerg emu->x86.R_SI = fetch_word_imm(emu);
3006 1.1 joerg }
3007 1.1 joerg /****************************************************************************
3008 1.1 joerg REMARKS:
3009 1.1 joerg Handles opcode 0xbf
3010 1.1 joerg ****************************************************************************/
3011 1.1 joerg static void
3012 1.1 joerg x86emuOp_mov_word_DI_IMM(struct X86EMU *emu)
3013 1.1 joerg {
3014 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
3015 1.1 joerg emu->x86.R_EDI = fetch_long_imm(emu);
3016 1.1 joerg else
3017 1.1 joerg emu->x86.R_DI = fetch_word_imm(emu);
3018 1.1 joerg }
3019 1.1 joerg /* used by opcodes c0, d0, and d2. */
3020 1.1 joerg static
3021 1.1 joerg uint8_t(* const opcD0_byte_operation[]) (struct X86EMU *, uint8_t d, uint8_t s) =
3022 1.1 joerg {
3023 1.1 joerg rol_byte,
3024 1.1 joerg ror_byte,
3025 1.1 joerg rcl_byte,
3026 1.1 joerg rcr_byte,
3027 1.1 joerg shl_byte,
3028 1.1 joerg shr_byte,
3029 1.1 joerg shl_byte, /* sal_byte === shl_byte by definition */
3030 1.1 joerg sar_byte,
3031 1.1 joerg };
3032 1.1 joerg /****************************************************************************
3033 1.1 joerg REMARKS:
3034 1.1 joerg Handles opcode 0xc0
3035 1.1 joerg ****************************************************************************/
3036 1.1 joerg static void
3037 1.1 joerg x86emuOp_opcC0_byte_RM_MEM(struct X86EMU *emu)
3038 1.1 joerg {
3039 1.1 joerg uint8_t destval, amt;
3040 1.1 joerg
3041 1.1 joerg /*
3042 1.1 joerg * Yet another weirdo special case instruction format. Part of
3043 1.1 joerg * the opcode held below in "RH". Doubly nested case would
3044 1.1 joerg * result, except that the decoded instruction
3045 1.1 joerg */
3046 1.1 joerg fetch_decode_modrm(emu);
3047 1.1 joerg /* know operation, decode the mod byte to find the addressing mode. */
3048 1.1 joerg destval = decode_and_fetch_byte_imm8(emu, &amt);
3049 1.1 joerg destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, amt);
3050 1.1 joerg write_back_byte(emu, destval);
3051 1.1 joerg }
3052 1.1 joerg /* used by opcodes c1, d1, and d3. */
3053 1.1 joerg static
3054 1.1 joerg uint16_t(* const opcD1_word_operation[]) (struct X86EMU *, uint16_t s, uint8_t d) =
3055 1.1 joerg {
3056 1.1 joerg rol_word,
3057 1.1 joerg ror_word,
3058 1.1 joerg rcl_word,
3059 1.1 joerg rcr_word,
3060 1.1 joerg shl_word,
3061 1.1 joerg shr_word,
3062 1.1 joerg shl_word, /* sal_byte === shl_byte by definition */
3063 1.1 joerg sar_word,
3064 1.1 joerg };
3065 1.1 joerg /* used by opcodes c1, d1, and d3. */
3066 1.1 joerg static
3067 1.1 joerg uint32_t(* const opcD1_long_operation[]) (struct X86EMU *, uint32_t s, uint8_t d) =
3068 1.1 joerg {
3069 1.1 joerg rol_long,
3070 1.1 joerg ror_long,
3071 1.1 joerg rcl_long,
3072 1.1 joerg rcr_long,
3073 1.1 joerg shl_long,
3074 1.1 joerg shr_long,
3075 1.1 joerg shl_long, /* sal_byte === shl_byte by definition */
3076 1.1 joerg sar_long,
3077 1.1 joerg };
3078 1.1 joerg /****************************************************************************
3079 1.1 joerg REMARKS:
3080 1.1 joerg Handles opcode 0xc1
3081 1.1 joerg ****************************************************************************/
3082 1.1 joerg static void
3083 1.1 joerg x86emuOp_opcC1_word_RM_MEM(struct X86EMU *emu)
3084 1.1 joerg {
3085 1.1 joerg uint8_t amt;
3086 1.1 joerg
3087 1.1 joerg /*
3088 1.1 joerg * Yet another weirdo special case instruction format. Part of
3089 1.1 joerg * the opcode held below in "RH". Doubly nested case would
3090 1.1 joerg * result, except that the decoded instruction
3091 1.1 joerg */
3092 1.1 joerg fetch_decode_modrm(emu);
3093 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3094 1.1 joerg uint32_t destval;
3095 1.1 joerg
3096 1.1 joerg destval = decode_and_fetch_long_imm8(emu, &amt);
3097 1.1 joerg destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, amt);
3098 1.1 joerg write_back_long(emu, destval);
3099 1.1 joerg } else {
3100 1.1 joerg uint16_t destval;
3101 1.1 joerg
3102 1.1 joerg destval = decode_and_fetch_word_imm8(emu, &amt);
3103 1.1 joerg destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, amt);
3104 1.1 joerg write_back_word(emu, destval);
3105 1.1 joerg }
3106 1.1 joerg }
3107 1.1 joerg /****************************************************************************
3108 1.1 joerg REMARKS:
3109 1.1 joerg Handles opcode 0xc2
3110 1.1 joerg ****************************************************************************/
3111 1.1 joerg static void
3112 1.1 joerg x86emuOp_ret_near_IMM(struct X86EMU *emu)
3113 1.1 joerg {
3114 1.1 joerg uint16_t imm;
3115 1.1 joerg
3116 1.1 joerg imm = fetch_word_imm(emu);
3117 1.1 joerg emu->x86.R_IP = pop_word(emu);
3118 1.1 joerg emu->x86.R_SP += imm;
3119 1.1 joerg }
3120 1.1 joerg /****************************************************************************
3121 1.1 joerg REMARKS:
3122 1.1 joerg Handles opcode 0xc6
3123 1.1 joerg ****************************************************************************/
3124 1.1 joerg static void
3125 1.1 joerg x86emuOp_mov_byte_RM_IMM(struct X86EMU *emu)
3126 1.1 joerg {
3127 1.1 joerg uint8_t *destreg;
3128 1.1 joerg uint32_t destoffset;
3129 1.1 joerg uint8_t imm;
3130 1.1 joerg
3131 1.1 joerg fetch_decode_modrm(emu);
3132 1.1 joerg if (emu->cur_rh != 0)
3133 1.1 joerg X86EMU_halt_sys(emu);
3134 1.1 joerg if (emu->cur_mod != 3) {
3135 1.1 joerg destoffset = decode_rl_address(emu);
3136 1.1 joerg imm = fetch_byte_imm(emu);
3137 1.1 joerg store_data_byte(emu, destoffset, imm);
3138 1.1 joerg } else {
3139 1.1 joerg destreg = decode_rl_byte_register(emu);
3140 1.1 joerg imm = fetch_byte_imm(emu);
3141 1.1 joerg *destreg = imm;
3142 1.1 joerg }
3143 1.1 joerg }
3144 1.1 joerg /****************************************************************************
3145 1.1 joerg REMARKS:
3146 1.1 joerg Handles opcode 0xc7
3147 1.1 joerg ****************************************************************************/
3148 1.1 joerg static void
3149 1.1 joerg x86emuOp32_mov_word_RM_IMM(struct X86EMU *emu)
3150 1.1 joerg {
3151 1.1 joerg uint32_t destoffset;
3152 1.1 joerg uint32_t imm, *destreg;
3153 1.1 joerg
3154 1.1 joerg fetch_decode_modrm(emu);
3155 1.1 joerg if (emu->cur_rh != 0)
3156 1.1 joerg X86EMU_halt_sys(emu);
3157 1.1 joerg
3158 1.1 joerg if (emu->cur_mod != 3) {
3159 1.1 joerg destoffset = decode_rl_address(emu);
3160 1.1 joerg imm = fetch_long_imm(emu);
3161 1.1 joerg store_data_long(emu, destoffset, imm);
3162 1.1 joerg } else {
3163 1.1 joerg destreg = decode_rl_long_register(emu);
3164 1.1 joerg imm = fetch_long_imm(emu);
3165 1.1 joerg *destreg = imm;
3166 1.1 joerg }
3167 1.1 joerg }
3168 1.1 joerg
3169 1.1 joerg static void
3170 1.1 joerg x86emuOp16_mov_word_RM_IMM(struct X86EMU *emu)
3171 1.1 joerg {
3172 1.1 joerg uint32_t destoffset;
3173 1.1 joerg uint16_t imm, *destreg;
3174 1.1 joerg
3175 1.1 joerg fetch_decode_modrm(emu);
3176 1.1 joerg if (emu->cur_rh != 0)
3177 1.1 joerg X86EMU_halt_sys(emu);
3178 1.1 joerg
3179 1.1 joerg if (emu->cur_mod != 3) {
3180 1.1 joerg destoffset = decode_rl_address(emu);
3181 1.1 joerg imm = fetch_word_imm(emu);
3182 1.1 joerg store_data_word(emu, destoffset, imm);
3183 1.1 joerg } else {
3184 1.1 joerg destreg = decode_rl_word_register(emu);
3185 1.1 joerg imm = fetch_word_imm(emu);
3186 1.1 joerg *destreg = imm;
3187 1.1 joerg }
3188 1.1 joerg }
3189 1.1 joerg
3190 1.1 joerg static void
3191 1.1 joerg x86emuOp_mov_word_RM_IMM(struct X86EMU *emu)
3192 1.1 joerg {
3193 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
3194 1.1 joerg x86emuOp32_mov_word_RM_IMM(emu);
3195 1.1 joerg else
3196 1.1 joerg x86emuOp16_mov_word_RM_IMM(emu);
3197 1.1 joerg }
3198 1.1 joerg /****************************************************************************
3199 1.1 joerg REMARKS:
3200 1.1 joerg Handles opcode 0xc8
3201 1.1 joerg ****************************************************************************/
3202 1.1 joerg static void
3203 1.1 joerg x86emuOp_enter(struct X86EMU *emu)
3204 1.1 joerg {
3205 1.1 joerg uint16_t local, frame_pointer;
3206 1.1 joerg uint8_t nesting;
3207 1.1 joerg int i;
3208 1.1 joerg
3209 1.1 joerg local = fetch_word_imm(emu);
3210 1.1 joerg nesting = fetch_byte_imm(emu);
3211 1.1 joerg push_word(emu, emu->x86.R_BP);
3212 1.1 joerg frame_pointer = emu->x86.R_SP;
3213 1.1 joerg if (nesting > 0) {
3214 1.1 joerg for (i = 1; i < nesting; i++) {
3215 1.1 joerg emu->x86.R_BP -= 2;
3216 1.1 joerg push_word(emu, fetch_word(emu, emu->x86.R_SS, emu->x86.R_BP));
3217 1.1 joerg }
3218 1.1 joerg push_word(emu, frame_pointer);
3219 1.1 joerg }
3220 1.1 joerg emu->x86.R_BP = frame_pointer;
3221 1.1 joerg emu->x86.R_SP = (uint16_t) (emu->x86.R_SP - local);
3222 1.1 joerg }
3223 1.1 joerg /****************************************************************************
3224 1.1 joerg REMARKS:
3225 1.1 joerg Handles opcode 0xc9
3226 1.1 joerg ****************************************************************************/
3227 1.1 joerg static void
3228 1.1 joerg x86emuOp_leave(struct X86EMU *emu)
3229 1.1 joerg {
3230 1.1 joerg emu->x86.R_SP = emu->x86.R_BP;
3231 1.1 joerg emu->x86.R_BP = pop_word(emu);
3232 1.1 joerg }
3233 1.1 joerg /****************************************************************************
3234 1.1 joerg REMARKS:
3235 1.1 joerg Handles opcode 0xca
3236 1.1 joerg ****************************************************************************/
3237 1.1 joerg static void
3238 1.1 joerg x86emuOp_ret_far_IMM(struct X86EMU *emu)
3239 1.1 joerg {
3240 1.1 joerg uint16_t imm;
3241 1.1 joerg
3242 1.1 joerg imm = fetch_word_imm(emu);
3243 1.1 joerg emu->x86.R_IP = pop_word(emu);
3244 1.1 joerg emu->x86.R_CS = pop_word(emu);
3245 1.1 joerg emu->x86.R_SP += imm;
3246 1.1 joerg }
3247 1.1 joerg /****************************************************************************
3248 1.1 joerg REMARKS:
3249 1.1 joerg Handles opcode 0xcb
3250 1.1 joerg ****************************************************************************/
3251 1.1 joerg static void
3252 1.1 joerg x86emuOp_ret_far(struct X86EMU *emu)
3253 1.1 joerg {
3254 1.1 joerg emu->x86.R_IP = pop_word(emu);
3255 1.1 joerg emu->x86.R_CS = pop_word(emu);
3256 1.1 joerg }
3257 1.1 joerg /****************************************************************************
3258 1.1 joerg REMARKS:
3259 1.1 joerg Handles opcode 0xcc
3260 1.1 joerg ****************************************************************************/
3261 1.1 joerg static void
3262 1.1 joerg x86emuOp_int3(struct X86EMU *emu)
3263 1.1 joerg {
3264 1.3 joerg x86emu_intr_dispatch(emu, 3);
3265 1.1 joerg }
3266 1.1 joerg /****************************************************************************
3267 1.1 joerg REMARKS:
3268 1.1 joerg Handles opcode 0xcd
3269 1.1 joerg ****************************************************************************/
3270 1.1 joerg static void
3271 1.1 joerg x86emuOp_int_IMM(struct X86EMU *emu)
3272 1.1 joerg {
3273 1.1 joerg uint8_t intnum;
3274 1.1 joerg
3275 1.1 joerg intnum = fetch_byte_imm(emu);
3276 1.3 joerg x86emu_intr_dispatch(emu, intnum);
3277 1.1 joerg }
3278 1.1 joerg /****************************************************************************
3279 1.1 joerg REMARKS:
3280 1.1 joerg Handles opcode 0xce
3281 1.1 joerg ****************************************************************************/
3282 1.1 joerg static void
3283 1.1 joerg x86emuOp_into(struct X86EMU *emu)
3284 1.1 joerg {
3285 1.3 joerg if (ACCESS_FLAG(F_OF))
3286 1.3 joerg x86emu_intr_dispatch(emu, 4);
3287 1.1 joerg }
3288 1.1 joerg /****************************************************************************
3289 1.1 joerg REMARKS:
3290 1.1 joerg Handles opcode 0xcf
3291 1.1 joerg ****************************************************************************/
3292 1.1 joerg static void
3293 1.1 joerg x86emuOp_iret(struct X86EMU *emu)
3294 1.1 joerg {
3295 1.1 joerg emu->x86.R_IP = pop_word(emu);
3296 1.1 joerg emu->x86.R_CS = pop_word(emu);
3297 1.1 joerg emu->x86.R_FLG = pop_word(emu);
3298 1.1 joerg }
3299 1.1 joerg /****************************************************************************
3300 1.1 joerg REMARKS:
3301 1.1 joerg Handles opcode 0xd0
3302 1.1 joerg ****************************************************************************/
3303 1.1 joerg static void
3304 1.1 joerg x86emuOp_opcD0_byte_RM_1(struct X86EMU *emu)
3305 1.1 joerg {
3306 1.1 joerg uint8_t destval;
3307 1.1 joerg
3308 1.1 joerg fetch_decode_modrm(emu);
3309 1.1 joerg destval = decode_and_fetch_byte(emu);
3310 1.1 joerg destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, 1);
3311 1.1 joerg write_back_byte(emu, destval);
3312 1.1 joerg }
3313 1.1 joerg /****************************************************************************
3314 1.1 joerg REMARKS:
3315 1.1 joerg Handles opcode 0xd1
3316 1.1 joerg ****************************************************************************/
3317 1.1 joerg static void
3318 1.1 joerg x86emuOp_opcD1_word_RM_1(struct X86EMU *emu)
3319 1.1 joerg {
3320 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3321 1.1 joerg uint32_t destval;
3322 1.1 joerg
3323 1.1 joerg fetch_decode_modrm(emu);
3324 1.1 joerg destval = decode_and_fetch_long(emu);
3325 1.1 joerg destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, 1);
3326 1.1 joerg write_back_long(emu, destval);
3327 1.1 joerg } else {
3328 1.1 joerg uint16_t destval;
3329 1.1 joerg
3330 1.1 joerg fetch_decode_modrm(emu);
3331 1.1 joerg destval = decode_and_fetch_word(emu);
3332 1.1 joerg destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, 1);
3333 1.1 joerg write_back_word(emu, destval);
3334 1.1 joerg }
3335 1.1 joerg }
3336 1.1 joerg /****************************************************************************
3337 1.1 joerg REMARKS:
3338 1.1 joerg Handles opcode 0xd2
3339 1.1 joerg ****************************************************************************/
3340 1.1 joerg static void
3341 1.1 joerg x86emuOp_opcD2_byte_RM_CL(struct X86EMU *emu)
3342 1.1 joerg {
3343 1.1 joerg uint8_t destval;
3344 1.1 joerg
3345 1.1 joerg fetch_decode_modrm(emu);
3346 1.1 joerg destval = decode_and_fetch_byte(emu);
3347 1.1 joerg destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
3348 1.1 joerg write_back_byte(emu, destval);
3349 1.1 joerg }
3350 1.1 joerg /****************************************************************************
3351 1.1 joerg REMARKS:
3352 1.1 joerg Handles opcode 0xd3
3353 1.1 joerg ****************************************************************************/
3354 1.1 joerg static void
3355 1.1 joerg x86emuOp_opcD3_word_RM_CL(struct X86EMU *emu)
3356 1.1 joerg {
3357 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3358 1.1 joerg uint32_t destval;
3359 1.1 joerg
3360 1.1 joerg fetch_decode_modrm(emu);
3361 1.1 joerg destval = decode_and_fetch_long(emu);
3362 1.1 joerg destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
3363 1.1 joerg write_back_long(emu, destval);
3364 1.1 joerg } else {
3365 1.1 joerg uint16_t destval;
3366 1.1 joerg
3367 1.1 joerg fetch_decode_modrm(emu);
3368 1.1 joerg destval = decode_and_fetch_word(emu);
3369 1.1 joerg destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
3370 1.1 joerg write_back_word(emu, destval);
3371 1.1 joerg }
3372 1.1 joerg }
3373 1.1 joerg /****************************************************************************
3374 1.1 joerg REMARKS:
3375 1.1 joerg Handles opcode 0xd4
3376 1.1 joerg ****************************************************************************/
3377 1.1 joerg static void
3378 1.1 joerg x86emuOp_aam(struct X86EMU *emu)
3379 1.1 joerg {
3380 1.1 joerg uint8_t a;
3381 1.1 joerg
3382 1.1 joerg a = fetch_byte_imm(emu); /* this is a stupid encoding. */
3383 1.1 joerg if (a != 10) {
3384 1.1 joerg /* fix: add base decoding aam_word(uint8_t val, int base a) */
3385 1.1 joerg X86EMU_halt_sys(emu);
3386 1.1 joerg }
3387 1.1 joerg /* note the type change here --- returning AL and AH in AX. */
3388 1.1 joerg emu->x86.R_AX = aam_word(emu, emu->x86.R_AL);
3389 1.1 joerg }
3390 1.1 joerg /****************************************************************************
3391 1.1 joerg REMARKS:
3392 1.1 joerg Handles opcode 0xd5
3393 1.1 joerg ****************************************************************************/
3394 1.1 joerg static void
3395 1.1 joerg x86emuOp_aad(struct X86EMU *emu)
3396 1.1 joerg {
3397 1.1 joerg uint8_t a;
3398 1.1 joerg
3399 1.1 joerg a = fetch_byte_imm(emu);
3400 1.1 joerg if (a != 10) {
3401 1.1 joerg /* fix: add base decoding aad_word(uint16_t val, int base a) */
3402 1.1 joerg X86EMU_halt_sys(emu);
3403 1.1 joerg }
3404 1.1 joerg emu->x86.R_AX = aad_word(emu, emu->x86.R_AX);
3405 1.1 joerg }
3406 1.1 joerg /* opcode 0xd6 ILLEGAL OPCODE */
3407 1.1 joerg
3408 1.1 joerg /****************************************************************************
3409 1.1 joerg REMARKS:
3410 1.1 joerg Handles opcode 0xd7
3411 1.1 joerg ****************************************************************************/
3412 1.1 joerg static void
3413 1.1 joerg x86emuOp_xlat(struct X86EMU *emu)
3414 1.1 joerg {
3415 1.1 joerg uint16_t addr;
3416 1.1 joerg
3417 1.1 joerg addr = (uint16_t) (emu->x86.R_BX + (uint8_t) emu->x86.R_AL);
3418 1.1 joerg emu->x86.R_AL = fetch_data_byte(emu, addr);
3419 1.1 joerg }
3420 1.1 joerg
3421 1.1 joerg /* opcode=0xd8 */
3422 1.1 joerg static void
3423 1.1 joerg x86emuOp_esc_coprocess_d8(struct X86EMU *emu)
3424 1.1 joerg {
3425 1.1 joerg }
3426 1.1 joerg /* opcode=0xd9 */
3427 1.1 joerg static void
3428 1.1 joerg x86emuOp_esc_coprocess_d9(struct X86EMU *emu)
3429 1.1 joerg {
3430 1.1 joerg fetch_decode_modrm(emu);
3431 1.1 joerg if (emu->cur_mod != 3)
3432 1.1 joerg decode_rl_address(emu);
3433 1.1 joerg }
3434 1.1 joerg /* opcode=0xda */
3435 1.1 joerg static void
3436 1.1 joerg x86emuOp_esc_coprocess_da(struct X86EMU *emu)
3437 1.1 joerg {
3438 1.1 joerg fetch_decode_modrm(emu);
3439 1.1 joerg if (emu->cur_mod != 3)
3440 1.1 joerg decode_rl_address(emu);
3441 1.1 joerg }
3442 1.1 joerg /* opcode=0xdb */
3443 1.1 joerg static void
3444 1.1 joerg x86emuOp_esc_coprocess_db(struct X86EMU *emu)
3445 1.1 joerg {
3446 1.1 joerg fetch_decode_modrm(emu);
3447 1.1 joerg if (emu->cur_mod != 3)
3448 1.1 joerg decode_rl_address(emu);
3449 1.1 joerg }
3450 1.1 joerg /* opcode=0xdc */
3451 1.1 joerg static void
3452 1.1 joerg x86emuOp_esc_coprocess_dc(struct X86EMU *emu)
3453 1.1 joerg {
3454 1.1 joerg fetch_decode_modrm(emu);
3455 1.1 joerg if (emu->cur_mod != 3)
3456 1.1 joerg decode_rl_address(emu);
3457 1.1 joerg }
3458 1.1 joerg /* opcode=0xdd */
3459 1.1 joerg static void
3460 1.1 joerg x86emuOp_esc_coprocess_dd(struct X86EMU *emu)
3461 1.1 joerg {
3462 1.1 joerg fetch_decode_modrm(emu);
3463 1.1 joerg if (emu->cur_mod != 3)
3464 1.1 joerg decode_rl_address(emu);
3465 1.1 joerg }
3466 1.1 joerg /* opcode=0xde */
3467 1.1 joerg static void
3468 1.1 joerg x86emuOp_esc_coprocess_de(struct X86EMU *emu)
3469 1.1 joerg {
3470 1.1 joerg fetch_decode_modrm(emu);
3471 1.1 joerg if (emu->cur_mod != 3)
3472 1.1 joerg decode_rl_address(emu);
3473 1.1 joerg }
3474 1.1 joerg /* opcode=0xdf */
3475 1.1 joerg static void
3476 1.1 joerg x86emuOp_esc_coprocess_df(struct X86EMU *emu)
3477 1.1 joerg {
3478 1.1 joerg fetch_decode_modrm(emu);
3479 1.1 joerg if (emu->cur_mod != 3)
3480 1.1 joerg decode_rl_address(emu);
3481 1.1 joerg }
3482 1.1 joerg
3483 1.1 joerg /****************************************************************************
3484 1.1 joerg REMARKS:
3485 1.1 joerg Handles opcode 0xe0
3486 1.1 joerg ****************************************************************************/
3487 1.1 joerg static void
3488 1.1 joerg x86emuOp_loopne(struct X86EMU *emu)
3489 1.1 joerg {
3490 1.1 joerg int16_t ip;
3491 1.1 joerg
3492 1.1 joerg ip = (int8_t) fetch_byte_imm(emu);
3493 1.1 joerg ip += (int16_t) emu->x86.R_IP;
3494 1.1 joerg emu->x86.R_CX -= 1;
3495 1.1 joerg if (emu->x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
3496 1.1 joerg emu->x86.R_IP = ip;
3497 1.1 joerg }
3498 1.1 joerg /****************************************************************************
3499 1.1 joerg REMARKS:
3500 1.1 joerg Handles opcode 0xe1
3501 1.1 joerg ****************************************************************************/
3502 1.1 joerg static void
3503 1.1 joerg x86emuOp_loope(struct X86EMU *emu)
3504 1.1 joerg {
3505 1.1 joerg int16_t ip;
3506 1.1 joerg
3507 1.1 joerg ip = (int8_t) fetch_byte_imm(emu);
3508 1.1 joerg ip += (int16_t) emu->x86.R_IP;
3509 1.1 joerg emu->x86.R_CX -= 1;
3510 1.1 joerg if (emu->x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
3511 1.1 joerg emu->x86.R_IP = ip;
3512 1.1 joerg }
3513 1.1 joerg /****************************************************************************
3514 1.1 joerg REMARKS:
3515 1.1 joerg Handles opcode 0xe2
3516 1.1 joerg ****************************************************************************/
3517 1.1 joerg static void
3518 1.1 joerg x86emuOp_loop(struct X86EMU *emu)
3519 1.1 joerg {
3520 1.1 joerg int16_t ip;
3521 1.1 joerg
3522 1.1 joerg ip = (int8_t) fetch_byte_imm(emu);
3523 1.1 joerg ip += (int16_t) emu->x86.R_IP;
3524 1.1 joerg emu->x86.R_CX -= 1;
3525 1.1 joerg if (emu->x86.R_CX != 0)
3526 1.1 joerg emu->x86.R_IP = ip;
3527 1.1 joerg }
3528 1.1 joerg /****************************************************************************
3529 1.1 joerg REMARKS:
3530 1.1 joerg Handles opcode 0xe3
3531 1.1 joerg ****************************************************************************/
3532 1.1 joerg static void
3533 1.1 joerg x86emuOp_jcxz(struct X86EMU *emu)
3534 1.1 joerg {
3535 1.1 joerg uint16_t target;
3536 1.1 joerg int8_t offset;
3537 1.1 joerg
3538 1.1 joerg /* jump to byte offset if overflow flag is set */
3539 1.1 joerg offset = (int8_t) fetch_byte_imm(emu);
3540 1.1 joerg target = (uint16_t) (emu->x86.R_IP + offset);
3541 1.1 joerg if (emu->x86.R_CX == 0)
3542 1.1 joerg emu->x86.R_IP = target;
3543 1.1 joerg }
3544 1.1 joerg /****************************************************************************
3545 1.1 joerg REMARKS:
3546 1.1 joerg Handles opcode 0xe4
3547 1.1 joerg ****************************************************************************/
3548 1.1 joerg static void
3549 1.1 joerg x86emuOp_in_byte_AL_IMM(struct X86EMU *emu)
3550 1.1 joerg {
3551 1.1 joerg uint8_t port;
3552 1.1 joerg
3553 1.1 joerg port = (uint8_t) fetch_byte_imm(emu);
3554 1.1 joerg emu->x86.R_AL = (*emu->emu_inb) (emu, port);
3555 1.1 joerg }
3556 1.1 joerg /****************************************************************************
3557 1.1 joerg REMARKS:
3558 1.1 joerg Handles opcode 0xe5
3559 1.1 joerg ****************************************************************************/
3560 1.1 joerg static void
3561 1.1 joerg x86emuOp_in_word_AX_IMM(struct X86EMU *emu)
3562 1.1 joerg {
3563 1.1 joerg uint8_t port;
3564 1.1 joerg
3565 1.1 joerg port = (uint8_t) fetch_byte_imm(emu);
3566 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3567 1.1 joerg emu->x86.R_EAX = (*emu->emu_inl) (emu, port);
3568 1.1 joerg } else {
3569 1.1 joerg emu->x86.R_AX = (*emu->emu_inw) (emu, port);
3570 1.1 joerg }
3571 1.1 joerg }
3572 1.1 joerg /****************************************************************************
3573 1.1 joerg REMARKS:
3574 1.1 joerg Handles opcode 0xe6
3575 1.1 joerg ****************************************************************************/
3576 1.1 joerg static void
3577 1.1 joerg x86emuOp_out_byte_IMM_AL(struct X86EMU *emu)
3578 1.1 joerg {
3579 1.1 joerg uint8_t port;
3580 1.1 joerg
3581 1.1 joerg port = (uint8_t) fetch_byte_imm(emu);
3582 1.1 joerg (*emu->emu_outb) (emu, port, emu->x86.R_AL);
3583 1.1 joerg }
3584 1.1 joerg /****************************************************************************
3585 1.1 joerg REMARKS:
3586 1.1 joerg Handles opcode 0xe7
3587 1.1 joerg ****************************************************************************/
3588 1.1 joerg static void
3589 1.1 joerg x86emuOp_out_word_IMM_AX(struct X86EMU *emu)
3590 1.1 joerg {
3591 1.1 joerg uint8_t port;
3592 1.1 joerg
3593 1.1 joerg port = (uint8_t) fetch_byte_imm(emu);
3594 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3595 1.1 joerg (*emu->emu_outl) (emu, port, emu->x86.R_EAX);
3596 1.1 joerg } else {
3597 1.1 joerg (*emu->emu_outw) (emu, port, emu->x86.R_AX);
3598 1.1 joerg }
3599 1.1 joerg }
3600 1.1 joerg /****************************************************************************
3601 1.1 joerg REMARKS:
3602 1.1 joerg Handles opcode 0xe8
3603 1.1 joerg ****************************************************************************/
3604 1.1 joerg static void
3605 1.1 joerg x86emuOp_call_near_IMM(struct X86EMU *emu)
3606 1.1 joerg {
3607 1.10 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3608 1.10 joerg int32_t ip;
3609 1.10 joerg ip = (int32_t) fetch_long_imm(emu);
3610 1.10 joerg ip += (int32_t) emu->x86.R_EIP;
3611 1.10 joerg push_long(emu, emu->x86.R_EIP);
3612 1.10 joerg emu->x86.R_EIP = ip;
3613 1.10 joerg } else {
3614 1.10 joerg int16_t ip;
3615 1.10 joerg ip = (int16_t) fetch_word_imm(emu);
3616 1.10 joerg ip += (int16_t) emu->x86.R_IP; /* CHECK SIGN */
3617 1.10 joerg push_word(emu, emu->x86.R_IP);
3618 1.10 joerg emu->x86.R_IP = ip;
3619 1.10 joerg }
3620 1.1 joerg }
3621 1.1 joerg /****************************************************************************
3622 1.1 joerg REMARKS:
3623 1.1 joerg Handles opcode 0xe9
3624 1.1 joerg ****************************************************************************/
3625 1.1 joerg static void
3626 1.1 joerg x86emuOp_jump_near_IMM(struct X86EMU *emu)
3627 1.1 joerg {
3628 1.1 joerg int ip;
3629 1.1 joerg
3630 1.1 joerg ip = (int16_t) fetch_word_imm(emu);
3631 1.1 joerg ip += (int16_t) emu->x86.R_IP;
3632 1.1 joerg emu->x86.R_IP = (uint16_t) ip;
3633 1.1 joerg }
3634 1.1 joerg /****************************************************************************
3635 1.1 joerg REMARKS:
3636 1.1 joerg Handles opcode 0xea
3637 1.1 joerg ****************************************************************************/
3638 1.1 joerg static void
3639 1.1 joerg x86emuOp_jump_far_IMM(struct X86EMU *emu)
3640 1.1 joerg {
3641 1.1 joerg uint16_t cs, ip;
3642 1.1 joerg
3643 1.1 joerg ip = fetch_word_imm(emu);
3644 1.1 joerg cs = fetch_word_imm(emu);
3645 1.1 joerg emu->x86.R_IP = ip;
3646 1.1 joerg emu->x86.R_CS = cs;
3647 1.1 joerg }
3648 1.1 joerg /****************************************************************************
3649 1.1 joerg REMARKS:
3650 1.1 joerg Handles opcode 0xeb
3651 1.1 joerg ****************************************************************************/
3652 1.1 joerg static void
3653 1.1 joerg x86emuOp_jump_byte_IMM(struct X86EMU *emu)
3654 1.1 joerg {
3655 1.1 joerg uint16_t target;
3656 1.1 joerg int8_t offset;
3657 1.1 joerg
3658 1.1 joerg offset = (int8_t) fetch_byte_imm(emu);
3659 1.1 joerg target = (uint16_t) (emu->x86.R_IP + offset);
3660 1.1 joerg emu->x86.R_IP = target;
3661 1.1 joerg }
3662 1.1 joerg /****************************************************************************
3663 1.1 joerg REMARKS:
3664 1.1 joerg Handles opcode 0xec
3665 1.1 joerg ****************************************************************************/
3666 1.1 joerg static void
3667 1.1 joerg x86emuOp_in_byte_AL_DX(struct X86EMU *emu)
3668 1.1 joerg {
3669 1.1 joerg emu->x86.R_AL = (*emu->emu_inb) (emu, emu->x86.R_DX);
3670 1.1 joerg }
3671 1.1 joerg /****************************************************************************
3672 1.1 joerg REMARKS:
3673 1.1 joerg Handles opcode 0xed
3674 1.1 joerg ****************************************************************************/
3675 1.1 joerg static void
3676 1.1 joerg x86emuOp_in_word_AX_DX(struct X86EMU *emu)
3677 1.1 joerg {
3678 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3679 1.1 joerg emu->x86.R_EAX = (*emu->emu_inl) (emu, emu->x86.R_DX);
3680 1.1 joerg } else {
3681 1.1 joerg emu->x86.R_AX = (*emu->emu_inw) (emu, emu->x86.R_DX);
3682 1.1 joerg }
3683 1.1 joerg }
3684 1.1 joerg /****************************************************************************
3685 1.1 joerg REMARKS:
3686 1.1 joerg Handles opcode 0xee
3687 1.1 joerg ****************************************************************************/
3688 1.1 joerg static void
3689 1.1 joerg x86emuOp_out_byte_DX_AL(struct X86EMU *emu)
3690 1.1 joerg {
3691 1.1 joerg (*emu->emu_outb) (emu, emu->x86.R_DX, emu->x86.R_AL);
3692 1.1 joerg }
3693 1.1 joerg /****************************************************************************
3694 1.1 joerg REMARKS:
3695 1.1 joerg Handles opcode 0xef
3696 1.1 joerg ****************************************************************************/
3697 1.1 joerg static void
3698 1.1 joerg x86emuOp_out_word_DX_AX(struct X86EMU *emu)
3699 1.1 joerg {
3700 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
3701 1.1 joerg (*emu->emu_outl) (emu, emu->x86.R_DX, emu->x86.R_EAX);
3702 1.1 joerg } else {
3703 1.1 joerg (*emu->emu_outw) (emu, emu->x86.R_DX, emu->x86.R_AX);
3704 1.1 joerg }
3705 1.1 joerg }
3706 1.1 joerg /****************************************************************************
3707 1.1 joerg REMARKS:
3708 1.1 joerg Handles opcode 0xf0
3709 1.1 joerg ****************************************************************************/
3710 1.1 joerg static void
3711 1.1 joerg x86emuOp_lock(struct X86EMU *emu)
3712 1.1 joerg {
3713 1.1 joerg }
3714 1.1 joerg /*opcode 0xf1 ILLEGAL OPERATION */
3715 1.1 joerg
3716 1.1 joerg /****************************************************************************
3717 1.1 joerg REMARKS:
3718 1.1 joerg Handles opcode 0xf5
3719 1.1 joerg ****************************************************************************/
3720 1.1 joerg static void
3721 1.1 joerg x86emuOp_cmc(struct X86EMU *emu)
3722 1.1 joerg {
3723 1.1 joerg if (ACCESS_FLAG(F_CF))
3724 1.1 joerg CLEAR_FLAG(F_CF);
3725 1.1 joerg else
3726 1.1 joerg SET_FLAG(F_CF);
3727 1.1 joerg }
3728 1.1 joerg /****************************************************************************
3729 1.1 joerg REMARKS:
3730 1.1 joerg Handles opcode 0xf6
3731 1.1 joerg ****************************************************************************/
3732 1.1 joerg static void
3733 1.1 joerg x86emuOp_opcF6_byte_RM(struct X86EMU *emu)
3734 1.1 joerg {
3735 1.1 joerg uint8_t destval, srcval;
3736 1.1 joerg
3737 1.1 joerg /* long, drawn out code follows. Double switch for a total of 32
3738 1.1 joerg * cases. */
3739 1.1 joerg fetch_decode_modrm(emu);
3740 1.1 joerg if (emu->cur_rh == 1)
3741 1.1 joerg X86EMU_halt_sys(emu);
3742 1.1 joerg
3743 1.1 joerg if (emu->cur_rh == 0) {
3744 1.1 joerg destval = decode_and_fetch_byte_imm8(emu, &srcval);
3745 1.1 joerg test_byte(emu, destval, srcval);
3746 1.1 joerg return;
3747 1.1 joerg }
3748 1.1 joerg destval = decode_and_fetch_byte(emu);
3749 1.1 joerg switch (emu->cur_rh) {
3750 1.1 joerg case 2:
3751 1.1 joerg destval = ~destval;
3752 1.1 joerg write_back_byte(emu, destval);
3753 1.1 joerg break;
3754 1.1 joerg case 3:
3755 1.1 joerg destval = neg_byte(emu, destval);
3756 1.1 joerg write_back_byte(emu, destval);
3757 1.1 joerg break;
3758 1.1 joerg case 4:
3759 1.1 joerg mul_byte(emu, destval);
3760 1.1 joerg break;
3761 1.1 joerg case 5:
3762 1.1 joerg imul_byte(emu, destval);
3763 1.1 joerg break;
3764 1.1 joerg case 6:
3765 1.1 joerg div_byte(emu, destval);
3766 1.1 joerg break;
3767 1.1 joerg case 7:
3768 1.1 joerg idiv_byte(emu, destval);
3769 1.1 joerg break;
3770 1.1 joerg }
3771 1.1 joerg }
3772 1.1 joerg /****************************************************************************
3773 1.1 joerg REMARKS:
3774 1.1 joerg Handles opcode 0xf7
3775 1.1 joerg ****************************************************************************/
3776 1.1 joerg static void
3777 1.1 joerg x86emuOp32_opcF7_word_RM(struct X86EMU *emu)
3778 1.1 joerg {
3779 1.1 joerg uint32_t destval, srcval;
3780 1.1 joerg
3781 1.1 joerg /* long, drawn out code follows. Double switch for a total of 32
3782 1.1 joerg * cases. */
3783 1.1 joerg fetch_decode_modrm(emu);
3784 1.1 joerg if (emu->cur_rh == 1)
3785 1.1 joerg X86EMU_halt_sys(emu);
3786 1.1 joerg
3787 1.1 joerg if (emu->cur_rh == 0) {
3788 1.1 joerg if (emu->cur_mod != 3) {
3789 1.1 joerg uint32_t destoffset;
3790 1.1 joerg
3791 1.1 joerg destoffset = decode_rl_address(emu);
3792 1.1 joerg srcval = fetch_long_imm(emu);
3793 1.1 joerg destval = fetch_data_long(emu, destoffset);
3794 1.1 joerg } else {
3795 1.1 joerg srcval = fetch_long_imm(emu);
3796 1.1 joerg destval = *decode_rl_long_register(emu);
3797 1.1 joerg }
3798 1.1 joerg test_long(emu, destval, srcval);
3799 1.1 joerg return;
3800 1.1 joerg }
3801 1.1 joerg destval = decode_and_fetch_long(emu);
3802 1.1 joerg switch (emu->cur_rh) {
3803 1.1 joerg case 2:
3804 1.1 joerg destval = ~destval;
3805 1.1 joerg write_back_long(emu, destval);
3806 1.1 joerg break;
3807 1.1 joerg case 3:
3808 1.1 joerg destval = neg_long(emu, destval);
3809 1.1 joerg write_back_long(emu, destval);
3810 1.1 joerg break;
3811 1.1 joerg case 4:
3812 1.1 joerg mul_long(emu, destval);
3813 1.1 joerg break;
3814 1.1 joerg case 5:
3815 1.1 joerg imul_long(emu, destval);
3816 1.1 joerg break;
3817 1.1 joerg case 6:
3818 1.1 joerg div_long(emu, destval);
3819 1.1 joerg break;
3820 1.1 joerg case 7:
3821 1.1 joerg idiv_long(emu, destval);
3822 1.1 joerg break;
3823 1.1 joerg }
3824 1.1 joerg }
3825 1.1 joerg static void
3826 1.1 joerg x86emuOp16_opcF7_word_RM(struct X86EMU *emu)
3827 1.1 joerg {
3828 1.1 joerg uint16_t destval, srcval;
3829 1.1 joerg
3830 1.1 joerg /* long, drawn out code follows. Double switch for a total of 32
3831 1.1 joerg * cases. */
3832 1.1 joerg fetch_decode_modrm(emu);
3833 1.1 joerg if (emu->cur_rh == 1)
3834 1.1 joerg X86EMU_halt_sys(emu);
3835 1.1 joerg
3836 1.1 joerg if (emu->cur_rh == 0) {
3837 1.1 joerg if (emu->cur_mod != 3) {
3838 1.1 joerg uint32_t destoffset;
3839 1.1 joerg
3840 1.1 joerg destoffset = decode_rl_address(emu);
3841 1.1 joerg srcval = fetch_word_imm(emu);
3842 1.1 joerg destval = fetch_data_word(emu, destoffset);
3843 1.1 joerg } else {
3844 1.1 joerg srcval = fetch_word_imm(emu);
3845 1.1 joerg destval = *decode_rl_word_register(emu);
3846 1.1 joerg }
3847 1.1 joerg test_word(emu, destval, srcval);
3848 1.1 joerg return;
3849 1.1 joerg }
3850 1.1 joerg destval = decode_and_fetch_word(emu);
3851 1.1 joerg switch (emu->cur_rh) {
3852 1.1 joerg case 2:
3853 1.1 joerg destval = ~destval;
3854 1.1 joerg write_back_word(emu, destval);
3855 1.1 joerg break;
3856 1.1 joerg case 3:
3857 1.1 joerg destval = neg_word(emu, destval);
3858 1.1 joerg write_back_word(emu, destval);
3859 1.1 joerg break;
3860 1.1 joerg case 4:
3861 1.1 joerg mul_word(emu, destval);
3862 1.1 joerg break;
3863 1.1 joerg case 5:
3864 1.1 joerg imul_word(emu, destval);
3865 1.1 joerg break;
3866 1.1 joerg case 6:
3867 1.1 joerg div_word(emu, destval);
3868 1.1 joerg break;
3869 1.1 joerg case 7:
3870 1.1 joerg idiv_word(emu, destval);
3871 1.1 joerg break;
3872 1.1 joerg }
3873 1.1 joerg }
3874 1.1 joerg static void
3875 1.1 joerg x86emuOp_opcF7_word_RM(struct X86EMU *emu)
3876 1.1 joerg {
3877 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
3878 1.1 joerg x86emuOp32_opcF7_word_RM(emu);
3879 1.1 joerg else
3880 1.1 joerg x86emuOp16_opcF7_word_RM(emu);
3881 1.1 joerg }
3882 1.1 joerg /****************************************************************************
3883 1.1 joerg REMARKS:
3884 1.1 joerg Handles opcode 0xfe
3885 1.1 joerg ****************************************************************************/
3886 1.1 joerg static void
3887 1.1 joerg x86emuOp_opcFE_byte_RM(struct X86EMU *emu)
3888 1.1 joerg {
3889 1.1 joerg uint8_t destval;
3890 1.1 joerg uint32_t destoffset;
3891 1.1 joerg uint8_t *destreg;
3892 1.1 joerg
3893 1.1 joerg /* Yet another special case instruction. */
3894 1.1 joerg fetch_decode_modrm(emu);
3895 1.1 joerg if (emu->cur_mod != 3) {
3896 1.1 joerg destoffset = decode_rl_address(emu);
3897 1.1 joerg switch (emu->cur_rh) {
3898 1.1 joerg case 0: /* inc word ptr ... */
3899 1.1 joerg destval = fetch_data_byte(emu, destoffset);
3900 1.1 joerg destval = inc_byte(emu, destval);
3901 1.1 joerg store_data_byte(emu, destoffset, destval);
3902 1.1 joerg break;
3903 1.1 joerg case 1: /* dec word ptr ... */
3904 1.1 joerg destval = fetch_data_byte(emu, destoffset);
3905 1.1 joerg destval = dec_byte(emu, destval);
3906 1.1 joerg store_data_byte(emu, destoffset, destval);
3907 1.1 joerg break;
3908 1.1 joerg }
3909 1.1 joerg } else {
3910 1.1 joerg destreg = decode_rl_byte_register(emu);
3911 1.1 joerg switch (emu->cur_rh) {
3912 1.1 joerg case 0:
3913 1.1 joerg *destreg = inc_byte(emu, *destreg);
3914 1.1 joerg break;
3915 1.1 joerg case 1:
3916 1.1 joerg *destreg = dec_byte(emu, *destreg);
3917 1.1 joerg break;
3918 1.1 joerg }
3919 1.1 joerg }
3920 1.1 joerg }
3921 1.1 joerg /****************************************************************************
3922 1.1 joerg REMARKS:
3923 1.1 joerg Handles opcode 0xff
3924 1.1 joerg ****************************************************************************/
3925 1.1 joerg static void
3926 1.1 joerg x86emuOp32_opcFF_word_RM(struct X86EMU *emu)
3927 1.1 joerg {
3928 1.1 joerg uint32_t destoffset = 0;
3929 1.1 joerg uint32_t destval, *destreg;
3930 1.1 joerg
3931 1.1 joerg if (emu->cur_mod != 3) {
3932 1.1 joerg destoffset = decode_rl_address(emu);
3933 1.1 joerg destval = fetch_data_long(emu, destoffset);
3934 1.1 joerg switch (emu->cur_rh) {
3935 1.1 joerg case 0: /* inc word ptr ... */
3936 1.1 joerg destval = inc_long(emu, destval);
3937 1.1 joerg store_data_long(emu, destoffset, destval);
3938 1.1 joerg break;
3939 1.1 joerg case 1: /* dec word ptr ... */
3940 1.1 joerg destval = dec_long(emu, destval);
3941 1.1 joerg store_data_long(emu, destoffset, destval);
3942 1.1 joerg break;
3943 1.1 joerg case 6: /* push word ptr ... */
3944 1.1 joerg push_long(emu, destval);
3945 1.1 joerg break;
3946 1.1 joerg }
3947 1.1 joerg } else {
3948 1.1 joerg destreg = decode_rl_long_register(emu);
3949 1.1 joerg switch (emu->cur_rh) {
3950 1.1 joerg case 0:
3951 1.1 joerg *destreg = inc_long(emu, *destreg);
3952 1.1 joerg break;
3953 1.1 joerg case 1:
3954 1.1 joerg *destreg = dec_long(emu, *destreg);
3955 1.1 joerg break;
3956 1.1 joerg case 6:
3957 1.1 joerg push_long(emu, *destreg);
3958 1.1 joerg break;
3959 1.1 joerg }
3960 1.1 joerg }
3961 1.1 joerg }
3962 1.1 joerg
3963 1.1 joerg static void
3964 1.1 joerg x86emuOp16_opcFF_word_RM(struct X86EMU *emu)
3965 1.1 joerg {
3966 1.1 joerg uint32_t destoffset = 0;
3967 1.1 joerg uint16_t *destreg;
3968 1.1 joerg uint16_t destval;
3969 1.1 joerg
3970 1.1 joerg if (emu->cur_mod != 3) {
3971 1.1 joerg destoffset = decode_rl_address(emu);
3972 1.1 joerg destval = fetch_data_word(emu, destoffset);
3973 1.1 joerg switch (emu->cur_rh) {
3974 1.1 joerg case 0:
3975 1.1 joerg destval = inc_word(emu, destval);
3976 1.1 joerg store_data_word(emu, destoffset, destval);
3977 1.1 joerg break;
3978 1.1 joerg case 1: /* dec word ptr ... */
3979 1.1 joerg destval = dec_word(emu, destval);
3980 1.1 joerg store_data_word(emu, destoffset, destval);
3981 1.1 joerg break;
3982 1.1 joerg case 6: /* push word ptr ... */
3983 1.1 joerg push_word(emu, destval);
3984 1.1 joerg break;
3985 1.1 joerg }
3986 1.1 joerg } else {
3987 1.1 joerg destreg = decode_rl_word_register(emu);
3988 1.1 joerg switch (emu->cur_rh) {
3989 1.1 joerg case 0:
3990 1.1 joerg *destreg = inc_word(emu, *destreg);
3991 1.1 joerg break;
3992 1.1 joerg case 1:
3993 1.1 joerg *destreg = dec_word(emu, *destreg);
3994 1.1 joerg break;
3995 1.1 joerg case 6:
3996 1.1 joerg push_word(emu, *destreg);
3997 1.1 joerg break;
3998 1.1 joerg }
3999 1.1 joerg }
4000 1.1 joerg }
4001 1.1 joerg
4002 1.1 joerg static void
4003 1.1 joerg x86emuOp_opcFF_word_RM(struct X86EMU *emu)
4004 1.1 joerg {
4005 1.1 joerg uint32_t destoffset = 0;
4006 1.1 joerg uint16_t destval, destval2;
4007 1.1 joerg
4008 1.1 joerg /* Yet another special case instruction. */
4009 1.1 joerg fetch_decode_modrm(emu);
4010 1.1 joerg if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) || emu->cur_rh == 7)
4011 1.1 joerg X86EMU_halt_sys(emu);
4012 1.1 joerg if (emu->cur_rh == 0 || emu->cur_rh == 1 || emu->cur_rh == 6) {
4013 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
4014 1.1 joerg x86emuOp32_opcFF_word_RM(emu);
4015 1.1 joerg else
4016 1.1 joerg x86emuOp16_opcFF_word_RM(emu);
4017 1.1 joerg return;
4018 1.1 joerg }
4019 1.1 joerg
4020 1.1 joerg if (emu->cur_mod != 3) {
4021 1.1 joerg destoffset = decode_rl_address(emu);
4022 1.1 joerg destval = fetch_data_word(emu, destoffset);
4023 1.1 joerg switch (emu->cur_rh) {
4024 1.1 joerg case 3: /* call far ptr ... */
4025 1.1 joerg destval2 = fetch_data_word(emu, destoffset + 2);
4026 1.1 joerg push_word(emu, emu->x86.R_CS);
4027 1.1 joerg emu->x86.R_CS = destval2;
4028 1.1 joerg push_word(emu, emu->x86.R_IP);
4029 1.1 joerg emu->x86.R_IP = destval;
4030 1.1 joerg break;
4031 1.1 joerg case 5: /* jmp far ptr ... */
4032 1.1 joerg destval2 = fetch_data_word(emu, destoffset + 2);
4033 1.1 joerg emu->x86.R_IP = destval;
4034 1.1 joerg emu->x86.R_CS = destval2;
4035 1.1 joerg break;
4036 1.1 joerg }
4037 1.1 joerg } else {
4038 1.1 joerg destval = *decode_rl_word_register(emu);
4039 1.1 joerg }
4040 1.1 joerg
4041 1.1 joerg switch (emu->cur_rh) {
4042 1.1 joerg case 2: /* call word ptr */
4043 1.1 joerg push_word(emu, emu->x86.R_IP);
4044 1.1 joerg emu->x86.R_IP = destval;
4045 1.1 joerg break;
4046 1.1 joerg case 4: /* jmp */
4047 1.1 joerg emu->x86.R_IP = destval;
4048 1.1 joerg break;
4049 1.1 joerg }
4050 1.1 joerg }
4051 1.1 joerg /***************************************************************************
4052 1.1 joerg * Single byte operation code table:
4053 1.1 joerg **************************************************************************/
4054 1.1 joerg static void
4055 1.1 joerg X86EMU_exec_one_byte(struct X86EMU * emu)
4056 1.1 joerg {
4057 1.1 joerg uint8_t op1;
4058 1.1 joerg
4059 1.1 joerg op1 = fetch_byte_imm(emu);
4060 1.1 joerg
4061 1.1 joerg switch (op1) {
4062 1.1 joerg case 0x00:
4063 1.1 joerg common_binop_byte_rm_r(emu, add_byte);
4064 1.1 joerg break;
4065 1.1 joerg case 0x01:
4066 1.1 joerg common_binop_word_long_rm_r(emu, add_word, add_long);
4067 1.1 joerg break;
4068 1.1 joerg case 0x02:
4069 1.1 joerg common_binop_byte_r_rm(emu, add_byte);
4070 1.1 joerg break;
4071 1.1 joerg case 0x03:
4072 1.1 joerg common_binop_word_long_r_rm(emu, add_word, add_long);
4073 1.1 joerg break;
4074 1.1 joerg case 0x04:
4075 1.1 joerg common_binop_byte_imm(emu, add_byte);
4076 1.1 joerg break;
4077 1.1 joerg case 0x05:
4078 1.1 joerg common_binop_word_long_imm(emu, add_word, add_long);
4079 1.1 joerg break;
4080 1.1 joerg case 0x06:
4081 1.1 joerg push_word(emu, emu->x86.R_ES);
4082 1.1 joerg break;
4083 1.1 joerg case 0x07:
4084 1.1 joerg emu->x86.R_ES = pop_word(emu);
4085 1.1 joerg break;
4086 1.1 joerg
4087 1.1 joerg case 0x08:
4088 1.1 joerg common_binop_byte_rm_r(emu, or_byte);
4089 1.1 joerg break;
4090 1.1 joerg case 0x09:
4091 1.1 joerg common_binop_word_long_rm_r(emu, or_word, or_long);
4092 1.1 joerg break;
4093 1.1 joerg case 0x0a:
4094 1.1 joerg common_binop_byte_r_rm(emu, or_byte);
4095 1.1 joerg break;
4096 1.1 joerg case 0x0b:
4097 1.1 joerg common_binop_word_long_r_rm(emu, or_word, or_long);
4098 1.1 joerg break;
4099 1.1 joerg case 0x0c:
4100 1.1 joerg common_binop_byte_imm(emu, or_byte);
4101 1.1 joerg break;
4102 1.1 joerg case 0x0d:
4103 1.1 joerg common_binop_word_long_imm(emu, or_word, or_long);
4104 1.1 joerg break;
4105 1.1 joerg case 0x0e:
4106 1.1 joerg push_word(emu, emu->x86.R_CS);
4107 1.1 joerg break;
4108 1.1 joerg case 0x0f:
4109 1.1 joerg X86EMU_exec_two_byte(emu);
4110 1.1 joerg break;
4111 1.1 joerg
4112 1.1 joerg case 0x10:
4113 1.1 joerg common_binop_byte_rm_r(emu, adc_byte);
4114 1.1 joerg break;
4115 1.1 joerg case 0x11:
4116 1.1 joerg common_binop_word_long_rm_r(emu, adc_word, adc_long);
4117 1.1 joerg break;
4118 1.1 joerg case 0x12:
4119 1.1 joerg common_binop_byte_r_rm(emu, adc_byte);
4120 1.1 joerg break;
4121 1.1 joerg case 0x13:
4122 1.1 joerg common_binop_word_long_r_rm(emu, adc_word, adc_long);
4123 1.1 joerg break;
4124 1.1 joerg case 0x14:
4125 1.1 joerg common_binop_byte_imm(emu, adc_byte);
4126 1.1 joerg break;
4127 1.1 joerg case 0x15:
4128 1.1 joerg common_binop_word_long_imm(emu, adc_word, adc_long);
4129 1.1 joerg break;
4130 1.1 joerg case 0x16:
4131 1.1 joerg push_word(emu, emu->x86.R_SS);
4132 1.1 joerg break;
4133 1.1 joerg case 0x17:
4134 1.1 joerg emu->x86.R_SS = pop_word(emu);
4135 1.1 joerg break;
4136 1.1 joerg
4137 1.1 joerg case 0x18:
4138 1.1 joerg common_binop_byte_rm_r(emu, sbb_byte);
4139 1.1 joerg break;
4140 1.1 joerg case 0x19:
4141 1.1 joerg common_binop_word_long_rm_r(emu, sbb_word, sbb_long);
4142 1.1 joerg break;
4143 1.1 joerg case 0x1a:
4144 1.1 joerg common_binop_byte_r_rm(emu, sbb_byte);
4145 1.1 joerg break;
4146 1.1 joerg case 0x1b:
4147 1.1 joerg common_binop_word_long_r_rm(emu, sbb_word, sbb_long);
4148 1.1 joerg break;
4149 1.1 joerg case 0x1c:
4150 1.1 joerg common_binop_byte_imm(emu, sbb_byte);
4151 1.1 joerg break;
4152 1.1 joerg case 0x1d:
4153 1.1 joerg common_binop_word_long_imm(emu, sbb_word, sbb_long);
4154 1.1 joerg break;
4155 1.1 joerg case 0x1e:
4156 1.1 joerg push_word(emu, emu->x86.R_DS);
4157 1.1 joerg break;
4158 1.1 joerg case 0x1f:
4159 1.1 joerg emu->x86.R_DS = pop_word(emu);
4160 1.1 joerg break;
4161 1.1 joerg
4162 1.1 joerg case 0x20:
4163 1.1 joerg common_binop_byte_rm_r(emu, and_byte);
4164 1.1 joerg break;
4165 1.1 joerg case 0x21:
4166 1.1 joerg common_binop_word_long_rm_r(emu, and_word, and_long);
4167 1.1 joerg break;
4168 1.1 joerg case 0x22:
4169 1.1 joerg common_binop_byte_r_rm(emu, and_byte);
4170 1.1 joerg break;
4171 1.1 joerg case 0x23:
4172 1.1 joerg common_binop_word_long_r_rm(emu, and_word, and_long);
4173 1.1 joerg break;
4174 1.1 joerg case 0x24:
4175 1.1 joerg common_binop_byte_imm(emu, and_byte);
4176 1.1 joerg break;
4177 1.1 joerg case 0x25:
4178 1.1 joerg common_binop_word_long_imm(emu, and_word, and_long);
4179 1.1 joerg break;
4180 1.1 joerg case 0x26:
4181 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_ES;
4182 1.1 joerg break;
4183 1.1 joerg case 0x27:
4184 1.1 joerg emu->x86.R_AL = daa_byte(emu, emu->x86.R_AL);
4185 1.1 joerg break;
4186 1.1 joerg
4187 1.1 joerg case 0x28:
4188 1.1 joerg common_binop_byte_rm_r(emu, sub_byte);
4189 1.1 joerg break;
4190 1.1 joerg case 0x29:
4191 1.1 joerg common_binop_word_long_rm_r(emu, sub_word, sub_long);
4192 1.1 joerg break;
4193 1.1 joerg case 0x2a:
4194 1.1 joerg common_binop_byte_r_rm(emu, sub_byte);
4195 1.1 joerg break;
4196 1.1 joerg case 0x2b:
4197 1.1 joerg common_binop_word_long_r_rm(emu, sub_word, sub_long);
4198 1.1 joerg break;
4199 1.1 joerg case 0x2c:
4200 1.1 joerg common_binop_byte_imm(emu, sub_byte);
4201 1.1 joerg break;
4202 1.1 joerg case 0x2d:
4203 1.1 joerg common_binop_word_long_imm(emu, sub_word, sub_long);
4204 1.1 joerg break;
4205 1.1 joerg case 0x2e:
4206 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_CS;
4207 1.1 joerg break;
4208 1.1 joerg case 0x2f:
4209 1.1 joerg emu->x86.R_AL = das_byte(emu, emu->x86.R_AL);
4210 1.1 joerg break;
4211 1.1 joerg
4212 1.1 joerg case 0x30:
4213 1.1 joerg common_binop_byte_rm_r(emu, xor_byte);
4214 1.1 joerg break;
4215 1.1 joerg case 0x31:
4216 1.1 joerg common_binop_word_long_rm_r(emu, xor_word, xor_long);
4217 1.1 joerg break;
4218 1.1 joerg case 0x32:
4219 1.1 joerg common_binop_byte_r_rm(emu, xor_byte);
4220 1.1 joerg break;
4221 1.1 joerg case 0x33:
4222 1.1 joerg common_binop_word_long_r_rm(emu, xor_word, xor_long);
4223 1.1 joerg break;
4224 1.1 joerg case 0x34:
4225 1.1 joerg common_binop_byte_imm(emu, xor_byte);
4226 1.1 joerg break;
4227 1.1 joerg case 0x35:
4228 1.1 joerg common_binop_word_long_imm(emu, xor_word, xor_long);
4229 1.1 joerg break;
4230 1.1 joerg case 0x36:
4231 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_SS;
4232 1.1 joerg break;
4233 1.1 joerg case 0x37:
4234 1.1 joerg emu->x86.R_AX = aaa_word(emu, emu->x86.R_AX);
4235 1.1 joerg break;
4236 1.1 joerg
4237 1.1 joerg case 0x38:
4238 1.1 joerg common_binop_ns_byte_rm_r(emu, cmp_byte_no_return);
4239 1.1 joerg break;
4240 1.1 joerg case 0x39:
4241 1.1 joerg common_binop_ns_word_long_rm_r(emu, cmp_word_no_return,
4242 1.1 joerg cmp_long_no_return);
4243 1.1 joerg break;
4244 1.1 joerg case 0x3a:
4245 1.1 joerg x86emuOp_cmp_byte_R_RM(emu);
4246 1.1 joerg break;
4247 1.1 joerg case 0x3b:
4248 1.1 joerg x86emuOp_cmp_word_R_RM(emu);
4249 1.1 joerg break;
4250 1.1 joerg case 0x3c:
4251 1.1 joerg x86emuOp_cmp_byte_AL_IMM(emu);
4252 1.1 joerg break;
4253 1.1 joerg case 0x3d:
4254 1.1 joerg x86emuOp_cmp_word_AX_IMM(emu);
4255 1.1 joerg break;
4256 1.1 joerg case 0x3e:
4257 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_DS;
4258 1.1 joerg break;
4259 1.1 joerg case 0x3f:
4260 1.1 joerg emu->x86.R_AX = aas_word(emu, emu->x86.R_AX);
4261 1.1 joerg break;
4262 1.1 joerg
4263 1.1 joerg case 0x40:
4264 1.1 joerg common_inc_word_long(emu, &emu->x86.register_a);
4265 1.1 joerg break;
4266 1.1 joerg case 0x41:
4267 1.1 joerg common_inc_word_long(emu, &emu->x86.register_c);
4268 1.1 joerg break;
4269 1.1 joerg case 0x42:
4270 1.1 joerg common_inc_word_long(emu, &emu->x86.register_d);
4271 1.1 joerg break;
4272 1.1 joerg case 0x43:
4273 1.1 joerg common_inc_word_long(emu, &emu->x86.register_b);
4274 1.1 joerg break;
4275 1.1 joerg case 0x44:
4276 1.1 joerg common_inc_word_long(emu, &emu->x86.register_sp);
4277 1.1 joerg break;
4278 1.1 joerg case 0x45:
4279 1.1 joerg common_inc_word_long(emu, &emu->x86.register_bp);
4280 1.1 joerg break;
4281 1.1 joerg case 0x46:
4282 1.1 joerg common_inc_word_long(emu, &emu->x86.register_si);
4283 1.1 joerg break;
4284 1.1 joerg case 0x47:
4285 1.1 joerg common_inc_word_long(emu, &emu->x86.register_di);
4286 1.1 joerg break;
4287 1.1 joerg
4288 1.1 joerg case 0x48:
4289 1.1 joerg common_dec_word_long(emu, &emu->x86.register_a);
4290 1.1 joerg break;
4291 1.1 joerg case 0x49:
4292 1.1 joerg common_dec_word_long(emu, &emu->x86.register_c);
4293 1.1 joerg break;
4294 1.1 joerg case 0x4a:
4295 1.1 joerg common_dec_word_long(emu, &emu->x86.register_d);
4296 1.1 joerg break;
4297 1.1 joerg case 0x4b:
4298 1.1 joerg common_dec_word_long(emu, &emu->x86.register_b);
4299 1.1 joerg break;
4300 1.1 joerg case 0x4c:
4301 1.1 joerg common_dec_word_long(emu, &emu->x86.register_sp);
4302 1.1 joerg break;
4303 1.1 joerg case 0x4d:
4304 1.1 joerg common_dec_word_long(emu, &emu->x86.register_bp);
4305 1.1 joerg break;
4306 1.1 joerg case 0x4e:
4307 1.1 joerg common_dec_word_long(emu, &emu->x86.register_si);
4308 1.1 joerg break;
4309 1.1 joerg case 0x4f:
4310 1.1 joerg common_dec_word_long(emu, &emu->x86.register_di);
4311 1.1 joerg break;
4312 1.1 joerg
4313 1.1 joerg case 0x50:
4314 1.1 joerg common_push_word_long(emu, &emu->x86.register_a);
4315 1.1 joerg break;
4316 1.1 joerg case 0x51:
4317 1.1 joerg common_push_word_long(emu, &emu->x86.register_c);
4318 1.1 joerg break;
4319 1.1 joerg case 0x52:
4320 1.1 joerg common_push_word_long(emu, &emu->x86.register_d);
4321 1.1 joerg break;
4322 1.1 joerg case 0x53:
4323 1.1 joerg common_push_word_long(emu, &emu->x86.register_b);
4324 1.1 joerg break;
4325 1.1 joerg case 0x54:
4326 1.1 joerg common_push_word_long(emu, &emu->x86.register_sp);
4327 1.1 joerg break;
4328 1.1 joerg case 0x55:
4329 1.1 joerg common_push_word_long(emu, &emu->x86.register_bp);
4330 1.1 joerg break;
4331 1.1 joerg case 0x56:
4332 1.1 joerg common_push_word_long(emu, &emu->x86.register_si);
4333 1.1 joerg break;
4334 1.1 joerg case 0x57:
4335 1.1 joerg common_push_word_long(emu, &emu->x86.register_di);
4336 1.1 joerg break;
4337 1.1 joerg
4338 1.1 joerg case 0x58:
4339 1.1 joerg common_pop_word_long(emu, &emu->x86.register_a);
4340 1.1 joerg break;
4341 1.1 joerg case 0x59:
4342 1.1 joerg common_pop_word_long(emu, &emu->x86.register_c);
4343 1.1 joerg break;
4344 1.1 joerg case 0x5a:
4345 1.1 joerg common_pop_word_long(emu, &emu->x86.register_d);
4346 1.1 joerg break;
4347 1.1 joerg case 0x5b:
4348 1.1 joerg common_pop_word_long(emu, &emu->x86.register_b);
4349 1.1 joerg break;
4350 1.1 joerg case 0x5c:
4351 1.1 joerg common_pop_word_long(emu, &emu->x86.register_sp);
4352 1.1 joerg break;
4353 1.1 joerg case 0x5d:
4354 1.1 joerg common_pop_word_long(emu, &emu->x86.register_bp);
4355 1.1 joerg break;
4356 1.1 joerg case 0x5e:
4357 1.1 joerg common_pop_word_long(emu, &emu->x86.register_si);
4358 1.1 joerg break;
4359 1.1 joerg case 0x5f:
4360 1.1 joerg common_pop_word_long(emu, &emu->x86.register_di);
4361 1.1 joerg break;
4362 1.1 joerg
4363 1.1 joerg case 0x60:
4364 1.1 joerg x86emuOp_push_all(emu);
4365 1.1 joerg break;
4366 1.1 joerg case 0x61:
4367 1.1 joerg x86emuOp_pop_all(emu);
4368 1.1 joerg break;
4369 1.1 joerg /* 0x62 bound */
4370 1.1 joerg /* 0x63 arpl */
4371 1.1 joerg case 0x64:
4372 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_FS;
4373 1.1 joerg break;
4374 1.1 joerg case 0x65:
4375 1.1 joerg emu->x86.mode |= SYSMODE_SEGOVR_GS;
4376 1.1 joerg break;
4377 1.1 joerg case 0x66:
4378 1.1 joerg emu->x86.mode |= SYSMODE_PREFIX_DATA;
4379 1.1 joerg break;
4380 1.1 joerg case 0x67:
4381 1.1 joerg emu->x86.mode |= SYSMODE_PREFIX_ADDR;
4382 1.1 joerg break;
4383 1.1 joerg
4384 1.1 joerg case 0x68:
4385 1.1 joerg x86emuOp_push_word_IMM(emu);
4386 1.1 joerg break;
4387 1.1 joerg case 0x69:
4388 1.1 joerg common_imul_imm(emu, false);
4389 1.1 joerg break;
4390 1.1 joerg case 0x6a:
4391 1.1 joerg x86emuOp_push_byte_IMM(emu);
4392 1.1 joerg break;
4393 1.1 joerg case 0x6b:
4394 1.1 joerg common_imul_imm(emu, true);
4395 1.1 joerg break;
4396 1.1 joerg case 0x6c:
4397 1.1 joerg ins(emu, 1);
4398 1.1 joerg break;
4399 1.1 joerg case 0x6d:
4400 1.1 joerg x86emuOp_ins_word(emu);
4401 1.1 joerg break;
4402 1.1 joerg case 0x6e:
4403 1.1 joerg outs(emu, 1);
4404 1.1 joerg break;
4405 1.1 joerg case 0x6f:
4406 1.1 joerg x86emuOp_outs_word(emu);
4407 1.1 joerg break;
4408 1.1 joerg
4409 1.1 joerg case 0x70:
4410 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_OF));
4411 1.1 joerg break;
4412 1.1 joerg case 0x71:
4413 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_OF));
4414 1.1 joerg break;
4415 1.1 joerg case 0x72:
4416 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_CF));
4417 1.1 joerg break;
4418 1.1 joerg case 0x73:
4419 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_CF));
4420 1.1 joerg break;
4421 1.1 joerg case 0x74:
4422 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_ZF));
4423 1.1 joerg break;
4424 1.1 joerg case 0x75:
4425 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_ZF));
4426 1.1 joerg break;
4427 1.1 joerg case 0x76:
4428 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
4429 1.1 joerg break;
4430 1.1 joerg case 0x77:
4431 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_CF) && !ACCESS_FLAG(F_ZF));
4432 1.1 joerg break;
4433 1.1 joerg
4434 1.1 joerg case 0x78:
4435 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_SF));
4436 1.1 joerg break;
4437 1.1 joerg case 0x79:
4438 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_SF));
4439 1.1 joerg break;
4440 1.1 joerg case 0x7a:
4441 1.1 joerg common_jmp_near(emu, ACCESS_FLAG(F_PF));
4442 1.1 joerg break;
4443 1.1 joerg case 0x7b:
4444 1.1 joerg common_jmp_near(emu, !ACCESS_FLAG(F_PF));
4445 1.1 joerg break;
4446 1.1 joerg case 0x7c:
4447 1.1 joerg x86emuOp_jump_near_L(emu);
4448 1.1 joerg break;
4449 1.1 joerg case 0x7d:
4450 1.1 joerg x86emuOp_jump_near_NL(emu);
4451 1.1 joerg break;
4452 1.1 joerg case 0x7e:
4453 1.1 joerg x86emuOp_jump_near_LE(emu);
4454 1.1 joerg break;
4455 1.1 joerg case 0x7f:
4456 1.1 joerg x86emuOp_jump_near_NLE(emu);
4457 1.1 joerg break;
4458 1.1 joerg
4459 1.1 joerg case 0x80:
4460 1.1 joerg x86emuOp_opc80_byte_RM_IMM(emu);
4461 1.1 joerg break;
4462 1.1 joerg case 0x81:
4463 1.1 joerg x86emuOp_opc81_word_RM_IMM(emu);
4464 1.1 joerg break;
4465 1.1 joerg case 0x82:
4466 1.1 joerg x86emuOp_opc82_byte_RM_IMM(emu);
4467 1.1 joerg break;
4468 1.1 joerg case 0x83:
4469 1.1 joerg x86emuOp_opc83_word_RM_IMM(emu);
4470 1.1 joerg break;
4471 1.1 joerg case 0x84:
4472 1.1 joerg common_binop_ns_byte_rm_r(emu, test_byte);
4473 1.1 joerg break;
4474 1.1 joerg case 0x85:
4475 1.1 joerg common_binop_ns_word_long_rm_r(emu, test_word, test_long);
4476 1.1 joerg break;
4477 1.1 joerg case 0x86:
4478 1.1 joerg x86emuOp_xchg_byte_RM_R(emu);
4479 1.1 joerg break;
4480 1.1 joerg case 0x87:
4481 1.1 joerg x86emuOp_xchg_word_RM_R(emu);
4482 1.1 joerg break;
4483 1.1 joerg
4484 1.1 joerg case 0x88:
4485 1.1 joerg x86emuOp_mov_byte_RM_R(emu);
4486 1.1 joerg break;
4487 1.1 joerg case 0x89:
4488 1.1 joerg x86emuOp_mov_word_RM_R(emu);
4489 1.1 joerg break;
4490 1.1 joerg case 0x8a:
4491 1.1 joerg x86emuOp_mov_byte_R_RM(emu);
4492 1.1 joerg break;
4493 1.1 joerg case 0x8b:
4494 1.1 joerg x86emuOp_mov_word_R_RM(emu);
4495 1.1 joerg break;
4496 1.1 joerg case 0x8c:
4497 1.1 joerg x86emuOp_mov_word_RM_SR(emu);
4498 1.1 joerg break;
4499 1.1 joerg case 0x8d:
4500 1.1 joerg x86emuOp_lea_word_R_M(emu);
4501 1.1 joerg break;
4502 1.1 joerg case 0x8e:
4503 1.1 joerg x86emuOp_mov_word_SR_RM(emu);
4504 1.1 joerg break;
4505 1.1 joerg case 0x8f:
4506 1.1 joerg x86emuOp_pop_RM(emu);
4507 1.1 joerg break;
4508 1.1 joerg
4509 1.1 joerg case 0x90:
4510 1.1 joerg /* nop */
4511 1.1 joerg break;
4512 1.1 joerg case 0x91:
4513 1.1 joerg x86emuOp_xchg_word_AX_CX(emu);
4514 1.1 joerg break;
4515 1.1 joerg case 0x92:
4516 1.1 joerg x86emuOp_xchg_word_AX_DX(emu);
4517 1.1 joerg break;
4518 1.1 joerg case 0x93:
4519 1.1 joerg x86emuOp_xchg_word_AX_BX(emu);
4520 1.1 joerg break;
4521 1.1 joerg case 0x94:
4522 1.1 joerg x86emuOp_xchg_word_AX_SP(emu);
4523 1.1 joerg break;
4524 1.1 joerg case 0x95:
4525 1.1 joerg x86emuOp_xchg_word_AX_BP(emu);
4526 1.1 joerg break;
4527 1.1 joerg case 0x96:
4528 1.1 joerg x86emuOp_xchg_word_AX_SI(emu);
4529 1.1 joerg break;
4530 1.1 joerg case 0x97:
4531 1.1 joerg x86emuOp_xchg_word_AX_DI(emu);
4532 1.1 joerg break;
4533 1.1 joerg
4534 1.1 joerg case 0x98:
4535 1.1 joerg x86emuOp_cbw(emu);
4536 1.1 joerg break;
4537 1.1 joerg case 0x99:
4538 1.1 joerg x86emuOp_cwd(emu);
4539 1.1 joerg break;
4540 1.1 joerg case 0x9a:
4541 1.1 joerg x86emuOp_call_far_IMM(emu);
4542 1.1 joerg break;
4543 1.1 joerg case 0x9b:
4544 1.1 joerg /* wait */
4545 1.1 joerg break;
4546 1.1 joerg case 0x9c:
4547 1.1 joerg x86emuOp_pushf_word(emu);
4548 1.1 joerg break;
4549 1.1 joerg case 0x9d:
4550 1.1 joerg x86emuOp_popf_word(emu);
4551 1.1 joerg break;
4552 1.1 joerg case 0x9e:
4553 1.1 joerg x86emuOp_sahf(emu);
4554 1.1 joerg break;
4555 1.1 joerg case 0x9f:
4556 1.1 joerg x86emuOp_lahf(emu);
4557 1.1 joerg break;
4558 1.1 joerg
4559 1.1 joerg case 0xa0:
4560 1.1 joerg x86emuOp_mov_AL_M_IMM(emu);
4561 1.1 joerg break;
4562 1.1 joerg case 0xa1:
4563 1.1 joerg x86emuOp_mov_AX_M_IMM(emu);
4564 1.1 joerg break;
4565 1.1 joerg case 0xa2:
4566 1.1 joerg x86emuOp_mov_M_AL_IMM(emu);
4567 1.1 joerg break;
4568 1.1 joerg case 0xa3:
4569 1.1 joerg x86emuOp_mov_M_AX_IMM(emu);
4570 1.1 joerg break;
4571 1.1 joerg case 0xa4:
4572 1.1 joerg x86emuOp_movs_byte(emu);
4573 1.1 joerg break;
4574 1.1 joerg case 0xa5:
4575 1.1 joerg x86emuOp_movs_word(emu);
4576 1.1 joerg break;
4577 1.1 joerg case 0xa6:
4578 1.1 joerg x86emuOp_cmps_byte(emu);
4579 1.1 joerg break;
4580 1.1 joerg case 0xa7:
4581 1.1 joerg x86emuOp_cmps_word(emu);
4582 1.1 joerg break;
4583 1.1 joerg
4584 1.1 joerg case 0xa8:
4585 1.1 joerg test_byte(emu, emu->x86.R_AL, fetch_byte_imm(emu));
4586 1.1 joerg break;
4587 1.1 joerg case 0xa9:
4588 1.1 joerg x86emuOp_test_AX_IMM(emu);
4589 1.1 joerg break;
4590 1.1 joerg case 0xaa:
4591 1.1 joerg x86emuOp_stos_byte(emu);
4592 1.1 joerg break;
4593 1.1 joerg case 0xab:
4594 1.1 joerg x86emuOp_stos_word(emu);
4595 1.1 joerg break;
4596 1.1 joerg case 0xac:
4597 1.1 joerg x86emuOp_lods_byte(emu);
4598 1.1 joerg break;
4599 1.1 joerg case 0xad:
4600 1.1 joerg x86emuOp_lods_word(emu);
4601 1.1 joerg break;
4602 1.1 joerg case 0xae:
4603 1.1 joerg x86emuOp_scas_byte(emu);
4604 1.1 joerg break;
4605 1.1 joerg case 0xaf:
4606 1.1 joerg x86emuOp_scas_word(emu);
4607 1.1 joerg break;
4608 1.1 joerg
4609 1.1 joerg case 0xb0:
4610 1.1 joerg emu->x86.R_AL = fetch_byte_imm(emu);
4611 1.1 joerg break;
4612 1.1 joerg case 0xb1:
4613 1.1 joerg emu->x86.R_CL = fetch_byte_imm(emu);
4614 1.1 joerg break;
4615 1.1 joerg case 0xb2:
4616 1.1 joerg emu->x86.R_DL = fetch_byte_imm(emu);
4617 1.1 joerg break;
4618 1.1 joerg case 0xb3:
4619 1.1 joerg emu->x86.R_BL = fetch_byte_imm(emu);
4620 1.1 joerg break;
4621 1.1 joerg case 0xb4:
4622 1.1 joerg emu->x86.R_AH = fetch_byte_imm(emu);
4623 1.1 joerg break;
4624 1.1 joerg case 0xb5:
4625 1.1 joerg emu->x86.R_CH = fetch_byte_imm(emu);
4626 1.1 joerg break;
4627 1.1 joerg case 0xb6:
4628 1.1 joerg emu->x86.R_DH = fetch_byte_imm(emu);
4629 1.1 joerg break;
4630 1.1 joerg case 0xb7:
4631 1.1 joerg emu->x86.R_BH = fetch_byte_imm(emu);
4632 1.1 joerg break;
4633 1.1 joerg
4634 1.1 joerg case 0xb8:
4635 1.1 joerg x86emuOp_mov_word_AX_IMM(emu);
4636 1.1 joerg break;
4637 1.1 joerg case 0xb9:
4638 1.1 joerg x86emuOp_mov_word_CX_IMM(emu);
4639 1.1 joerg break;
4640 1.1 joerg case 0xba:
4641 1.1 joerg x86emuOp_mov_word_DX_IMM(emu);
4642 1.1 joerg break;
4643 1.1 joerg case 0xbb:
4644 1.1 joerg x86emuOp_mov_word_BX_IMM(emu);
4645 1.1 joerg break;
4646 1.1 joerg case 0xbc:
4647 1.1 joerg x86emuOp_mov_word_SP_IMM(emu);
4648 1.1 joerg break;
4649 1.1 joerg case 0xbd:
4650 1.1 joerg x86emuOp_mov_word_BP_IMM(emu);
4651 1.1 joerg break;
4652 1.1 joerg case 0xbe:
4653 1.1 joerg x86emuOp_mov_word_SI_IMM(emu);
4654 1.1 joerg break;
4655 1.1 joerg case 0xbf:
4656 1.1 joerg x86emuOp_mov_word_DI_IMM(emu);
4657 1.1 joerg break;
4658 1.1 joerg
4659 1.1 joerg case 0xc0:
4660 1.1 joerg x86emuOp_opcC0_byte_RM_MEM(emu);
4661 1.1 joerg break;
4662 1.1 joerg case 0xc1:
4663 1.1 joerg x86emuOp_opcC1_word_RM_MEM(emu);
4664 1.1 joerg break;
4665 1.1 joerg case 0xc2:
4666 1.1 joerg x86emuOp_ret_near_IMM(emu);
4667 1.1 joerg break;
4668 1.1 joerg case 0xc3:
4669 1.1 joerg emu->x86.R_IP = pop_word(emu);
4670 1.1 joerg break;
4671 1.1 joerg case 0xc4:
4672 1.1 joerg common_load_far_pointer(emu, &emu->x86.R_ES);
4673 1.1 joerg break;
4674 1.1 joerg case 0xc5:
4675 1.1 joerg common_load_far_pointer(emu, &emu->x86.R_DS);
4676 1.1 joerg break;
4677 1.1 joerg case 0xc6:
4678 1.1 joerg x86emuOp_mov_byte_RM_IMM(emu);
4679 1.1 joerg break;
4680 1.1 joerg case 0xc7:
4681 1.1 joerg x86emuOp_mov_word_RM_IMM(emu);
4682 1.1 joerg break;
4683 1.1 joerg case 0xc8:
4684 1.1 joerg x86emuOp_enter(emu);
4685 1.1 joerg break;
4686 1.1 joerg case 0xc9:
4687 1.1 joerg x86emuOp_leave(emu);
4688 1.1 joerg break;
4689 1.1 joerg case 0xca:
4690 1.1 joerg x86emuOp_ret_far_IMM(emu);
4691 1.1 joerg break;
4692 1.1 joerg case 0xcb:
4693 1.1 joerg x86emuOp_ret_far(emu);
4694 1.1 joerg break;
4695 1.1 joerg case 0xcc:
4696 1.1 joerg x86emuOp_int3(emu);
4697 1.1 joerg break;
4698 1.1 joerg case 0xcd:
4699 1.1 joerg x86emuOp_int_IMM(emu);
4700 1.1 joerg break;
4701 1.1 joerg case 0xce:
4702 1.1 joerg x86emuOp_into(emu);
4703 1.1 joerg break;
4704 1.1 joerg case 0xcf:
4705 1.1 joerg x86emuOp_iret(emu);
4706 1.1 joerg break;
4707 1.1 joerg
4708 1.1 joerg case 0xd0:
4709 1.1 joerg x86emuOp_opcD0_byte_RM_1(emu);
4710 1.1 joerg break;
4711 1.1 joerg case 0xd1:
4712 1.1 joerg x86emuOp_opcD1_word_RM_1(emu);
4713 1.1 joerg break;
4714 1.1 joerg case 0xd2:
4715 1.1 joerg x86emuOp_opcD2_byte_RM_CL(emu);
4716 1.1 joerg break;
4717 1.1 joerg case 0xd3:
4718 1.1 joerg x86emuOp_opcD3_word_RM_CL(emu);
4719 1.1 joerg break;
4720 1.1 joerg case 0xd4:
4721 1.1 joerg x86emuOp_aam(emu);
4722 1.1 joerg break;
4723 1.1 joerg case 0xd5:
4724 1.1 joerg x86emuOp_aad(emu);
4725 1.1 joerg break;
4726 1.1 joerg /* 0xd6 Undocumented SETALC instruction */
4727 1.1 joerg case 0xd7:
4728 1.1 joerg x86emuOp_xlat(emu);
4729 1.1 joerg break;
4730 1.1 joerg case 0xd8:
4731 1.1 joerg x86emuOp_esc_coprocess_d8(emu);
4732 1.1 joerg break;
4733 1.1 joerg case 0xd9:
4734 1.1 joerg x86emuOp_esc_coprocess_d9(emu);
4735 1.1 joerg break;
4736 1.1 joerg case 0xda:
4737 1.1 joerg x86emuOp_esc_coprocess_da(emu);
4738 1.1 joerg break;
4739 1.1 joerg case 0xdb:
4740 1.1 joerg x86emuOp_esc_coprocess_db(emu);
4741 1.1 joerg break;
4742 1.1 joerg case 0xdc:
4743 1.1 joerg x86emuOp_esc_coprocess_dc(emu);
4744 1.1 joerg break;
4745 1.1 joerg case 0xdd:
4746 1.1 joerg x86emuOp_esc_coprocess_dd(emu);
4747 1.1 joerg break;
4748 1.1 joerg case 0xde:
4749 1.1 joerg x86emuOp_esc_coprocess_de(emu);
4750 1.1 joerg break;
4751 1.1 joerg case 0xdf:
4752 1.1 joerg x86emuOp_esc_coprocess_df(emu);
4753 1.1 joerg break;
4754 1.1 joerg
4755 1.1 joerg case 0xe0:
4756 1.1 joerg x86emuOp_loopne(emu);
4757 1.1 joerg break;
4758 1.1 joerg case 0xe1:
4759 1.1 joerg x86emuOp_loope(emu);
4760 1.1 joerg break;
4761 1.1 joerg case 0xe2:
4762 1.1 joerg x86emuOp_loop(emu);
4763 1.1 joerg break;
4764 1.1 joerg case 0xe3:
4765 1.1 joerg x86emuOp_jcxz(emu);
4766 1.1 joerg break;
4767 1.1 joerg case 0xe4:
4768 1.1 joerg x86emuOp_in_byte_AL_IMM(emu);
4769 1.1 joerg break;
4770 1.1 joerg case 0xe5:
4771 1.1 joerg x86emuOp_in_word_AX_IMM(emu);
4772 1.1 joerg break;
4773 1.1 joerg case 0xe6:
4774 1.1 joerg x86emuOp_out_byte_IMM_AL(emu);
4775 1.1 joerg break;
4776 1.1 joerg case 0xe7:
4777 1.1 joerg x86emuOp_out_word_IMM_AX(emu);
4778 1.1 joerg break;
4779 1.1 joerg
4780 1.1 joerg case 0xe8:
4781 1.1 joerg x86emuOp_call_near_IMM(emu);
4782 1.1 joerg break;
4783 1.1 joerg case 0xe9:
4784 1.1 joerg x86emuOp_jump_near_IMM(emu);
4785 1.1 joerg break;
4786 1.1 joerg case 0xea:
4787 1.1 joerg x86emuOp_jump_far_IMM(emu);
4788 1.1 joerg break;
4789 1.1 joerg case 0xeb:
4790 1.1 joerg x86emuOp_jump_byte_IMM(emu);
4791 1.1 joerg break;
4792 1.1 joerg case 0xec:
4793 1.1 joerg x86emuOp_in_byte_AL_DX(emu);
4794 1.1 joerg break;
4795 1.1 joerg case 0xed:
4796 1.1 joerg x86emuOp_in_word_AX_DX(emu);
4797 1.1 joerg break;
4798 1.1 joerg case 0xee:
4799 1.1 joerg x86emuOp_out_byte_DX_AL(emu);
4800 1.1 joerg break;
4801 1.1 joerg case 0xef:
4802 1.1 joerg x86emuOp_out_word_DX_AX(emu);
4803 1.1 joerg break;
4804 1.1 joerg
4805 1.1 joerg case 0xf0:
4806 1.1 joerg x86emuOp_lock(emu);
4807 1.1 joerg break;
4808 1.1 joerg case 0xf2:
4809 1.1 joerg emu->x86.mode |= SYSMODE_PREFIX_REPNE;
4810 1.1 joerg break;
4811 1.1 joerg case 0xf3:
4812 1.1 joerg emu->x86.mode |= SYSMODE_PREFIX_REPE;
4813 1.1 joerg break;
4814 1.1 joerg case 0xf4:
4815 1.1 joerg X86EMU_halt_sys(emu);
4816 1.1 joerg break;
4817 1.1 joerg case 0xf5:
4818 1.1 joerg x86emuOp_cmc(emu);
4819 1.1 joerg break;
4820 1.1 joerg case 0xf6:
4821 1.1 joerg x86emuOp_opcF6_byte_RM(emu);
4822 1.1 joerg break;
4823 1.1 joerg case 0xf7:
4824 1.1 joerg x86emuOp_opcF7_word_RM(emu);
4825 1.1 joerg break;
4826 1.1 joerg
4827 1.1 joerg case 0xf8:
4828 1.1 joerg CLEAR_FLAG(F_CF);
4829 1.1 joerg break;
4830 1.1 joerg case 0xf9:
4831 1.1 joerg SET_FLAG(F_CF);
4832 1.1 joerg break;
4833 1.1 joerg case 0xfa:
4834 1.1 joerg CLEAR_FLAG(F_IF);
4835 1.1 joerg break;
4836 1.1 joerg case 0xfb:
4837 1.1 joerg SET_FLAG(F_IF);
4838 1.1 joerg break;
4839 1.1 joerg case 0xfc:
4840 1.1 joerg CLEAR_FLAG(F_DF);
4841 1.1 joerg break;
4842 1.1 joerg case 0xfd:
4843 1.1 joerg SET_FLAG(F_DF);
4844 1.1 joerg break;
4845 1.1 joerg case 0xfe:
4846 1.1 joerg x86emuOp_opcFE_byte_RM(emu);
4847 1.1 joerg break;
4848 1.1 joerg case 0xff:
4849 1.1 joerg x86emuOp_opcFF_word_RM(emu);
4850 1.1 joerg break;
4851 1.1 joerg default:
4852 1.1 joerg X86EMU_halt_sys(emu);
4853 1.1 joerg break;
4854 1.1 joerg }
4855 1.1 joerg if (op1 != 0x26 && op1 != 0x2e && op1 != 0x36 && op1 != 0x3e &&
4856 1.1 joerg (op1 | 3) != 0x67)
4857 1.1 joerg emu->x86.mode &= ~SYSMODE_CLRMASK;
4858 1.1 joerg }
4859 1.1 joerg
4860 1.1 joerg static void
4861 1.1 joerg common_jmp_long(struct X86EMU *emu, bool cond)
4862 1.1 joerg {
4863 1.1 joerg int16_t target;
4864 1.1 joerg
4865 1.1 joerg target = (int16_t) fetch_word_imm(emu);
4866 1.1 joerg target += (int16_t) emu->x86.R_IP;
4867 1.1 joerg if (cond)
4868 1.1 joerg emu->x86.R_IP = (uint16_t) target;
4869 1.1 joerg }
4870 1.1 joerg
4871 1.1 joerg static void
4872 1.1 joerg common_set_byte(struct X86EMU *emu, bool cond)
4873 1.1 joerg {
4874 1.1 joerg uint32_t destoffset;
4875 1.1 joerg uint8_t *destreg, destval;
4876 1.1 joerg
4877 1.1 joerg fetch_decode_modrm(emu);
4878 1.1 joerg destval = cond ? 0x01 : 0x00;
4879 1.1 joerg if (emu->cur_mod != 3) {
4880 1.1 joerg destoffset = decode_rl_address(emu);
4881 1.1 joerg store_data_byte(emu, destoffset, destval);
4882 1.1 joerg } else {
4883 1.1 joerg destreg = decode_rl_byte_register(emu);
4884 1.1 joerg *destreg = destval;
4885 1.1 joerg }
4886 1.1 joerg }
4887 1.1 joerg
4888 1.1 joerg static void
4889 1.1 joerg common_bitstring32(struct X86EMU *emu, int op)
4890 1.1 joerg {
4891 1.1 joerg int bit;
4892 1.1 joerg uint32_t srcval, *shiftreg, mask;
4893 1.1 joerg
4894 1.1 joerg fetch_decode_modrm(emu);
4895 1.1 joerg shiftreg = decode_rh_long_register(emu);
4896 1.1 joerg srcval = decode_and_fetch_long_disp(emu, (int16_t) *shiftreg >> 5);
4897 1.1 joerg bit = *shiftreg & 0x1F;
4898 1.1 joerg mask = 0x1 << bit;
4899 1.1 joerg CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
4900 1.1 joerg
4901 1.1 joerg switch (op) {
4902 1.1 joerg case 0:
4903 1.1 joerg break;
4904 1.1 joerg case 1:
4905 1.1 joerg write_back_long(emu, srcval | mask);
4906 1.1 joerg break;
4907 1.1 joerg case 2:
4908 1.1 joerg write_back_long(emu, srcval & ~mask);
4909 1.1 joerg break;
4910 1.1 joerg case 3:
4911 1.1 joerg write_back_long(emu, srcval ^ mask);
4912 1.1 joerg break;
4913 1.1 joerg }
4914 1.1 joerg }
4915 1.1 joerg
4916 1.1 joerg static void
4917 1.1 joerg common_bitstring16(struct X86EMU *emu, int op)
4918 1.1 joerg {
4919 1.1 joerg int bit;
4920 1.1 joerg uint16_t srcval, *shiftreg, mask;
4921 1.1 joerg
4922 1.1 joerg fetch_decode_modrm(emu);
4923 1.1 joerg shiftreg = decode_rh_word_register(emu);
4924 1.1 joerg srcval = decode_and_fetch_word_disp(emu, (int16_t) *shiftreg >> 4);
4925 1.1 joerg bit = *shiftreg & 0xF;
4926 1.1 joerg mask = 0x1 << bit;
4927 1.1 joerg CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
4928 1.1 joerg
4929 1.1 joerg switch (op) {
4930 1.1 joerg case 0:
4931 1.1 joerg break;
4932 1.1 joerg case 1:
4933 1.1 joerg write_back_word(emu, srcval | mask);
4934 1.1 joerg break;
4935 1.1 joerg case 2:
4936 1.1 joerg write_back_word(emu, srcval & ~mask);
4937 1.1 joerg break;
4938 1.1 joerg case 3:
4939 1.1 joerg write_back_word(emu, srcval ^ mask);
4940 1.1 joerg break;
4941 1.1 joerg }
4942 1.1 joerg }
4943 1.1 joerg
4944 1.1 joerg static void
4945 1.1 joerg common_bitstring(struct X86EMU *emu, int op)
4946 1.1 joerg {
4947 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
4948 1.1 joerg common_bitstring32(emu, op);
4949 1.1 joerg else
4950 1.1 joerg common_bitstring16(emu, op);
4951 1.1 joerg }
4952 1.1 joerg
4953 1.1 joerg static void
4954 1.1 joerg common_bitsearch32(struct X86EMU *emu, int diff)
4955 1.1 joerg {
4956 1.1 joerg uint32_t srcval, *dstreg;
4957 1.1 joerg
4958 1.1 joerg fetch_decode_modrm(emu);
4959 1.1 joerg dstreg = decode_rh_long_register(emu);
4960 1.1 joerg srcval = decode_and_fetch_long(emu);
4961 1.1 joerg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
4962 1.1 joerg for (*dstreg = 0; *dstreg < 32; *dstreg += diff) {
4963 1.1 joerg if ((srcval >> *dstreg) & 1)
4964 1.1 joerg break;
4965 1.1 joerg }
4966 1.1 joerg }
4967 1.1 joerg
4968 1.1 joerg static void
4969 1.1 joerg common_bitsearch16(struct X86EMU *emu, int diff)
4970 1.1 joerg {
4971 1.1 joerg uint16_t srcval, *dstreg;
4972 1.1 joerg
4973 1.1 joerg fetch_decode_modrm(emu);
4974 1.1 joerg dstreg = decode_rh_word_register(emu);
4975 1.1 joerg srcval = decode_and_fetch_word(emu);
4976 1.1 joerg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
4977 1.1 joerg for (*dstreg = 0; *dstreg < 16; *dstreg += diff) {
4978 1.1 joerg if ((srcval >> *dstreg) & 1)
4979 1.1 joerg break;
4980 1.1 joerg }
4981 1.1 joerg }
4982 1.1 joerg
4983 1.1 joerg static void
4984 1.1 joerg common_bitsearch(struct X86EMU *emu, int diff)
4985 1.1 joerg {
4986 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
4987 1.1 joerg common_bitsearch32(emu, diff);
4988 1.1 joerg else
4989 1.1 joerg common_bitsearch16(emu, diff);
4990 1.1 joerg }
4991 1.1 joerg
4992 1.1 joerg static void
4993 1.1 joerg common_shift32(struct X86EMU *emu, bool shift_left, bool use_cl)
4994 1.1 joerg {
4995 1.1 joerg uint8_t shift;
4996 1.1 joerg uint32_t destval, *shiftreg;
4997 1.1 joerg
4998 1.1 joerg fetch_decode_modrm(emu);
4999 1.1 joerg shiftreg = decode_rh_long_register(emu);
5000 1.1 joerg if (use_cl) {
5001 1.1 joerg destval = decode_and_fetch_long(emu);
5002 1.1 joerg shift = emu->x86.R_CL;
5003 1.1 joerg } else {
5004 1.1 joerg destval = decode_and_fetch_long_imm8(emu, &shift);
5005 1.1 joerg }
5006 1.1 joerg if (shift_left)
5007 1.1 joerg destval = shld_long(emu, destval, *shiftreg, shift);
5008 1.1 joerg else
5009 1.1 joerg destval = shrd_long(emu, destval, *shiftreg, shift);
5010 1.1 joerg write_back_long(emu, destval);
5011 1.1 joerg }
5012 1.1 joerg
5013 1.1 joerg static void
5014 1.1 joerg common_shift16(struct X86EMU *emu, bool shift_left, bool use_cl)
5015 1.1 joerg {
5016 1.1 joerg uint8_t shift;
5017 1.1 joerg uint16_t destval, *shiftreg;
5018 1.1 joerg
5019 1.1 joerg fetch_decode_modrm(emu);
5020 1.1 joerg shiftreg = decode_rh_word_register(emu);
5021 1.1 joerg if (use_cl) {
5022 1.1 joerg destval = decode_and_fetch_word(emu);
5023 1.1 joerg shift = emu->x86.R_CL;
5024 1.1 joerg } else {
5025 1.1 joerg destval = decode_and_fetch_word_imm8(emu, &shift);
5026 1.1 joerg }
5027 1.1 joerg if (shift_left)
5028 1.1 joerg destval = shld_word(emu, destval, *shiftreg, shift);
5029 1.1 joerg else
5030 1.1 joerg destval = shrd_word(emu, destval, *shiftreg, shift);
5031 1.1 joerg write_back_word(emu, destval);
5032 1.1 joerg }
5033 1.1 joerg
5034 1.1 joerg static void
5035 1.1 joerg common_shift(struct X86EMU *emu, bool shift_left, bool use_cl)
5036 1.1 joerg {
5037 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
5038 1.1 joerg common_shift32(emu, shift_left, use_cl);
5039 1.1 joerg else
5040 1.1 joerg common_shift16(emu, shift_left, use_cl);
5041 1.1 joerg }
5042 1.1 joerg
5043 1.1 joerg /*----------------------------- Implementation ----------------------------*/
5044 1.1 joerg #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
5045 1.1 joerg
5046 1.1 joerg /****************************************************************************
5047 1.1 joerg REMARKS:
5048 1.1 joerg Handles opcode 0x0f,0x31
5049 1.1 joerg ****************************************************************************/
5050 1.1 joerg static void
5051 1.1 joerg x86emuOp2_rdtsc(struct X86EMU *emu)
5052 1.1 joerg {
5053 1.1 joerg emu->x86.R_EAX = emu->cur_cycles & 0xffffffff;
5054 1.1 joerg emu->x86.R_EDX = emu->cur_cycles >> 32;
5055 1.1 joerg }
5056 1.1 joerg /****************************************************************************
5057 1.1 joerg REMARKS:
5058 1.1 joerg Handles opcode 0x0f,0xa0
5059 1.1 joerg ****************************************************************************/
5060 1.1 joerg static void
5061 1.1 joerg x86emuOp2_push_FS(struct X86EMU *emu)
5062 1.1 joerg {
5063 1.1 joerg push_word(emu, emu->x86.R_FS);
5064 1.1 joerg }
5065 1.1 joerg /****************************************************************************
5066 1.1 joerg REMARKS:
5067 1.1 joerg Handles opcode 0x0f,0xa1
5068 1.1 joerg ****************************************************************************/
5069 1.1 joerg static void
5070 1.1 joerg x86emuOp2_pop_FS(struct X86EMU *emu)
5071 1.1 joerg {
5072 1.1 joerg emu->x86.R_FS = pop_word(emu);
5073 1.1 joerg }
5074 1.1 joerg /****************************************************************************
5075 1.1 joerg REMARKS:
5076 1.4 jmcneill Handles opcode 0x0f,0xa1
5077 1.4 jmcneill ****************************************************************************/
5078 1.4 jmcneill #if defined(__i386__) || defined(__amd64__)
5079 1.4 jmcneill static void
5080 1.4 jmcneill hw_cpuid(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
5081 1.4 jmcneill {
5082 1.4 jmcneill __asm__ __volatile__("cpuid"
5083 1.4 jmcneill : "=a" (*a), "=b" (*b),
5084 1.4 jmcneill "=c" (*c), "=d" (*d)
5085 1.4 jmcneill : "a" (*a), "c" (*c)
5086 1.4 jmcneill : "cc");
5087 1.4 jmcneill }
5088 1.4 jmcneill #endif
5089 1.4 jmcneill static void
5090 1.4 jmcneill x86emuOp2_cpuid(struct X86EMU *emu)
5091 1.4 jmcneill {
5092 1.4 jmcneill #if defined(__i386__) || defined(__amd64__)
5093 1.4 jmcneill hw_cpuid(&emu->x86.R_EAX, &emu->x86.R_EBX, &emu->x86.R_ECX,
5094 1.4 jmcneill &emu->x86.R_EDX);
5095 1.4 jmcneill #endif
5096 1.4 jmcneill switch (emu->x86.R_EAX) {
5097 1.4 jmcneill case 0:
5098 1.4 jmcneill emu->x86.R_EAX = 1;
5099 1.4 jmcneill #if !defined(__i386__) && !defined(__amd64__)
5100 1.4 jmcneill /* "GenuineIntel" */
5101 1.4 jmcneill emu->x86.R_EBX = 0x756e6547;
5102 1.4 jmcneill emu->x86.R_EDX = 0x49656e69;
5103 1.4 jmcneill emu->x86.R_ECX = 0x6c65746e;
5104 1.4 jmcneill #endif
5105 1.4 jmcneill break;
5106 1.4 jmcneill case 1:
5107 1.4 jmcneill #if !defined(__i386__) && !defined(__amd64__)
5108 1.4 jmcneill emu->x86.R_EAX = 0x00000480;
5109 1.4 jmcneill emu->x86.R_EBX = emu->x86.R_ECX = 0;
5110 1.4 jmcneill emu->x86.R_EDX = 0x00000002;
5111 1.4 jmcneill #else
5112 1.4 jmcneill emu->x86.R_EDX &= 0x00000012;
5113 1.4 jmcneill #endif
5114 1.4 jmcneill break;
5115 1.4 jmcneill default:
5116 1.4 jmcneill emu->x86.R_EAX = emu->x86.R_EBX = emu->x86.R_ECX =
5117 1.4 jmcneill emu->x86.R_EDX = 0;
5118 1.4 jmcneill break;
5119 1.4 jmcneill }
5120 1.4 jmcneill }
5121 1.4 jmcneill /****************************************************************************
5122 1.4 jmcneill REMARKS:
5123 1.1 joerg Handles opcode 0x0f,0xa3
5124 1.1 joerg ****************************************************************************/
5125 1.1 joerg static void
5126 1.1 joerg x86emuOp2_bt_R(struct X86EMU *emu)
5127 1.1 joerg {
5128 1.1 joerg common_bitstring(emu, 0);
5129 1.1 joerg }
5130 1.1 joerg /****************************************************************************
5131 1.1 joerg REMARKS:
5132 1.1 joerg Handles opcode 0x0f,0xa4
5133 1.1 joerg ****************************************************************************/
5134 1.1 joerg static void
5135 1.1 joerg x86emuOp2_shld_IMM(struct X86EMU *emu)
5136 1.1 joerg {
5137 1.1 joerg common_shift(emu, true, false);
5138 1.1 joerg }
5139 1.1 joerg /****************************************************************************
5140 1.1 joerg REMARKS:
5141 1.1 joerg Handles opcode 0x0f,0xa5
5142 1.1 joerg ****************************************************************************/
5143 1.1 joerg static void
5144 1.1 joerg x86emuOp2_shld_CL(struct X86EMU *emu)
5145 1.1 joerg {
5146 1.1 joerg common_shift(emu, true, true);
5147 1.1 joerg }
5148 1.1 joerg /****************************************************************************
5149 1.1 joerg REMARKS:
5150 1.1 joerg Handles opcode 0x0f,0xa8
5151 1.1 joerg ****************************************************************************/
5152 1.1 joerg static void
5153 1.1 joerg x86emuOp2_push_GS(struct X86EMU *emu)
5154 1.1 joerg {
5155 1.1 joerg push_word(emu, emu->x86.R_GS);
5156 1.1 joerg }
5157 1.1 joerg /****************************************************************************
5158 1.1 joerg REMARKS:
5159 1.1 joerg Handles opcode 0x0f,0xa9
5160 1.1 joerg ****************************************************************************/
5161 1.1 joerg static void
5162 1.1 joerg x86emuOp2_pop_GS(struct X86EMU *emu)
5163 1.1 joerg {
5164 1.1 joerg emu->x86.R_GS = pop_word(emu);
5165 1.1 joerg }
5166 1.1 joerg /****************************************************************************
5167 1.1 joerg REMARKS:
5168 1.1 joerg Handles opcode 0x0f,0xab
5169 1.1 joerg ****************************************************************************/
5170 1.1 joerg static void
5171 1.1 joerg x86emuOp2_bts_R(struct X86EMU *emu)
5172 1.1 joerg {
5173 1.1 joerg common_bitstring(emu, 1);
5174 1.1 joerg }
5175 1.1 joerg /****************************************************************************
5176 1.1 joerg REMARKS:
5177 1.1 joerg Handles opcode 0x0f,0xac
5178 1.1 joerg ****************************************************************************/
5179 1.1 joerg static void
5180 1.1 joerg x86emuOp2_shrd_IMM(struct X86EMU *emu)
5181 1.1 joerg {
5182 1.1 joerg common_shift(emu, false, false);
5183 1.1 joerg }
5184 1.1 joerg /****************************************************************************
5185 1.1 joerg REMARKS:
5186 1.1 joerg Handles opcode 0x0f,0xad
5187 1.1 joerg ****************************************************************************/
5188 1.1 joerg static void
5189 1.1 joerg x86emuOp2_shrd_CL(struct X86EMU *emu)
5190 1.1 joerg {
5191 1.1 joerg common_shift(emu, false, true);
5192 1.1 joerg }
5193 1.1 joerg /****************************************************************************
5194 1.1 joerg REMARKS:
5195 1.1 joerg Handles opcode 0x0f,0xaf
5196 1.1 joerg ****************************************************************************/
5197 1.1 joerg static void
5198 1.1 joerg x86emuOp2_32_imul_R_RM(struct X86EMU *emu)
5199 1.1 joerg {
5200 1.1 joerg uint32_t *destreg, srcval;
5201 1.1 joerg uint64_t res;
5202 1.1 joerg
5203 1.1 joerg fetch_decode_modrm(emu);
5204 1.1 joerg destreg = decode_rh_long_register(emu);
5205 1.1 joerg srcval = decode_and_fetch_long(emu);
5206 1.1 joerg res = (int32_t) *destreg * (int32_t)srcval;
5207 1.1 joerg if (res > 0xffffffff) {
5208 1.1 joerg SET_FLAG(F_CF);
5209 1.1 joerg SET_FLAG(F_OF);
5210 1.1 joerg } else {
5211 1.1 joerg CLEAR_FLAG(F_CF);
5212 1.1 joerg CLEAR_FLAG(F_OF);
5213 1.1 joerg }
5214 1.1 joerg *destreg = (uint32_t) res;
5215 1.1 joerg }
5216 1.1 joerg
5217 1.1 joerg static void
5218 1.1 joerg x86emuOp2_16_imul_R_RM(struct X86EMU *emu)
5219 1.1 joerg {
5220 1.1 joerg uint16_t *destreg, srcval;
5221 1.1 joerg uint32_t res;
5222 1.1 joerg
5223 1.1 joerg fetch_decode_modrm(emu);
5224 1.1 joerg destreg = decode_rh_word_register(emu);
5225 1.1 joerg srcval = decode_and_fetch_word(emu);
5226 1.1 joerg res = (int16_t) * destreg * (int16_t)srcval;
5227 1.1 joerg if (res > 0xFFFF) {
5228 1.1 joerg SET_FLAG(F_CF);
5229 1.1 joerg SET_FLAG(F_OF);
5230 1.1 joerg } else {
5231 1.1 joerg CLEAR_FLAG(F_CF);
5232 1.1 joerg CLEAR_FLAG(F_OF);
5233 1.1 joerg }
5234 1.1 joerg *destreg = (uint16_t) res;
5235 1.1 joerg }
5236 1.1 joerg
5237 1.1 joerg static void
5238 1.1 joerg x86emuOp2_imul_R_RM(struct X86EMU *emu)
5239 1.1 joerg {
5240 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
5241 1.1 joerg x86emuOp2_32_imul_R_RM(emu);
5242 1.1 joerg else
5243 1.1 joerg x86emuOp2_16_imul_R_RM(emu);
5244 1.1 joerg }
5245 1.1 joerg /****************************************************************************
5246 1.1 joerg REMARKS:
5247 1.1 joerg Handles opcode 0x0f,0xb2
5248 1.1 joerg ****************************************************************************/
5249 1.1 joerg static void
5250 1.1 joerg x86emuOp2_lss_R_IMM(struct X86EMU *emu)
5251 1.1 joerg {
5252 1.1 joerg common_load_far_pointer(emu, &emu->x86.R_SS);
5253 1.1 joerg }
5254 1.1 joerg /****************************************************************************
5255 1.1 joerg REMARKS:
5256 1.1 joerg Handles opcode 0x0f,0xb3
5257 1.1 joerg ****************************************************************************/
5258 1.1 joerg static void
5259 1.1 joerg x86emuOp2_btr_R(struct X86EMU *emu)
5260 1.1 joerg {
5261 1.1 joerg common_bitstring(emu, 2);
5262 1.1 joerg }
5263 1.1 joerg /****************************************************************************
5264 1.1 joerg REMARKS:
5265 1.1 joerg Handles opcode 0x0f,0xb4
5266 1.1 joerg ****************************************************************************/
5267 1.1 joerg static void
5268 1.1 joerg x86emuOp2_lfs_R_IMM(struct X86EMU *emu)
5269 1.1 joerg {
5270 1.1 joerg common_load_far_pointer(emu, &emu->x86.R_FS);
5271 1.1 joerg }
5272 1.1 joerg /****************************************************************************
5273 1.1 joerg REMARKS:
5274 1.1 joerg Handles opcode 0x0f,0xb5
5275 1.1 joerg ****************************************************************************/
5276 1.1 joerg static void
5277 1.1 joerg x86emuOp2_lgs_R_IMM(struct X86EMU *emu)
5278 1.1 joerg {
5279 1.1 joerg common_load_far_pointer(emu, &emu->x86.R_GS);
5280 1.1 joerg }
5281 1.1 joerg /****************************************************************************
5282 1.1 joerg REMARKS:
5283 1.1 joerg Handles opcode 0x0f,0xb6
5284 1.1 joerg ****************************************************************************/
5285 1.1 joerg static void
5286 1.1 joerg x86emuOp2_32_movzx_byte_R_RM(struct X86EMU *emu)
5287 1.1 joerg {
5288 1.1 joerg uint32_t *destreg;
5289 1.1 joerg
5290 1.1 joerg fetch_decode_modrm(emu);
5291 1.1 joerg destreg = decode_rh_long_register(emu);
5292 1.1 joerg *destreg = decode_and_fetch_byte(emu);
5293 1.1 joerg }
5294 1.1 joerg
5295 1.1 joerg static void
5296 1.1 joerg x86emuOp2_16_movzx_byte_R_RM(struct X86EMU *emu)
5297 1.1 joerg {
5298 1.1 joerg uint16_t *destreg;
5299 1.1 joerg
5300 1.1 joerg fetch_decode_modrm(emu);
5301 1.1 joerg destreg = decode_rh_word_register(emu);
5302 1.1 joerg *destreg = decode_and_fetch_byte(emu);
5303 1.1 joerg }
5304 1.1 joerg
5305 1.1 joerg static void
5306 1.1 joerg x86emuOp2_movzx_byte_R_RM(struct X86EMU *emu)
5307 1.1 joerg {
5308 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
5309 1.1 joerg x86emuOp2_32_movzx_byte_R_RM(emu);
5310 1.1 joerg else
5311 1.1 joerg x86emuOp2_16_movzx_byte_R_RM(emu);
5312 1.1 joerg }
5313 1.1 joerg /****************************************************************************
5314 1.1 joerg REMARKS:
5315 1.1 joerg Handles opcode 0x0f,0xb7
5316 1.1 joerg ****************************************************************************/
5317 1.1 joerg static void
5318 1.1 joerg x86emuOp2_movzx_word_R_RM(struct X86EMU *emu)
5319 1.1 joerg {
5320 1.1 joerg uint32_t *destreg;
5321 1.1 joerg
5322 1.1 joerg fetch_decode_modrm(emu);
5323 1.1 joerg destreg = decode_rh_long_register(emu);
5324 1.1 joerg *destreg = decode_and_fetch_word(emu);
5325 1.1 joerg }
5326 1.1 joerg /****************************************************************************
5327 1.1 joerg REMARKS:
5328 1.1 joerg Handles opcode 0x0f,0xba
5329 1.1 joerg ****************************************************************************/
5330 1.1 joerg static void
5331 1.1 joerg x86emuOp2_32_btX_I(struct X86EMU *emu)
5332 1.1 joerg {
5333 1.1 joerg int bit;
5334 1.1 joerg uint32_t srcval, mask;
5335 1.1 joerg uint8_t shift;
5336 1.1 joerg
5337 1.1 joerg fetch_decode_modrm(emu);
5338 1.1 joerg if (emu->cur_rh < 4)
5339 1.1 joerg X86EMU_halt_sys(emu);
5340 1.1 joerg
5341 1.1 joerg srcval = decode_and_fetch_long_imm8(emu, &shift);
5342 1.1 joerg bit = shift & 0x1F;
5343 1.1 joerg mask = (0x1 << bit);
5344 1.1 joerg
5345 1.1 joerg switch (emu->cur_rh) {
5346 1.1 joerg case 5:
5347 1.1 joerg write_back_long(emu, srcval | mask);
5348 1.1 joerg break;
5349 1.1 joerg case 6:
5350 1.1 joerg write_back_long(emu, srcval & ~mask);
5351 1.1 joerg break;
5352 1.1 joerg case 7:
5353 1.1 joerg write_back_long(emu, srcval ^ mask);
5354 1.1 joerg break;
5355 1.1 joerg }
5356 1.1 joerg CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
5357 1.1 joerg }
5358 1.1 joerg
5359 1.1 joerg static void
5360 1.1 joerg x86emuOp2_16_btX_I(struct X86EMU *emu)
5361 1.1 joerg {
5362 1.1 joerg int bit;
5363 1.1 joerg
5364 1.1 joerg uint16_t srcval, mask;
5365 1.1 joerg uint8_t shift;
5366 1.1 joerg
5367 1.1 joerg fetch_decode_modrm(emu);
5368 1.1 joerg if (emu->cur_rh < 4)
5369 1.1 joerg X86EMU_halt_sys(emu);
5370 1.1 joerg
5371 1.1 joerg srcval = decode_and_fetch_word_imm8(emu, &shift);
5372 1.1 joerg bit = shift & 0xF;
5373 1.1 joerg mask = (0x1 << bit);
5374 1.1 joerg switch (emu->cur_rh) {
5375 1.1 joerg case 5:
5376 1.1 joerg write_back_word(emu, srcval | mask);
5377 1.1 joerg break;
5378 1.1 joerg case 6:
5379 1.1 joerg write_back_word(emu, srcval & ~mask);
5380 1.1 joerg break;
5381 1.1 joerg case 7:
5382 1.1 joerg write_back_word(emu, srcval ^ mask);
5383 1.1 joerg break;
5384 1.1 joerg }
5385 1.1 joerg CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
5386 1.1 joerg }
5387 1.1 joerg
5388 1.1 joerg static void
5389 1.1 joerg x86emuOp2_btX_I(struct X86EMU *emu)
5390 1.1 joerg {
5391 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
5392 1.1 joerg x86emuOp2_32_btX_I(emu);
5393 1.1 joerg else
5394 1.1 joerg x86emuOp2_16_btX_I(emu);
5395 1.1 joerg }
5396 1.1 joerg /****************************************************************************
5397 1.1 joerg REMARKS:
5398 1.1 joerg Handles opcode 0x0f,0xbb
5399 1.1 joerg ****************************************************************************/
5400 1.1 joerg static void
5401 1.1 joerg x86emuOp2_btc_R(struct X86EMU *emu)
5402 1.1 joerg {
5403 1.1 joerg common_bitstring(emu, 3);
5404 1.1 joerg }
5405 1.1 joerg /****************************************************************************
5406 1.1 joerg REMARKS:
5407 1.1 joerg Handles opcode 0x0f,0xbc
5408 1.1 joerg ****************************************************************************/
5409 1.1 joerg static void
5410 1.1 joerg x86emuOp2_bsf(struct X86EMU *emu)
5411 1.1 joerg {
5412 1.1 joerg common_bitsearch(emu, +1);
5413 1.1 joerg }
5414 1.1 joerg /****************************************************************************
5415 1.1 joerg REMARKS:
5416 1.1 joerg Handles opcode 0x0f,0xbd
5417 1.1 joerg ****************************************************************************/
5418 1.1 joerg static void
5419 1.1 joerg x86emuOp2_bsr(struct X86EMU *emu)
5420 1.1 joerg {
5421 1.1 joerg common_bitsearch(emu, -1);
5422 1.1 joerg }
5423 1.1 joerg /****************************************************************************
5424 1.1 joerg REMARKS:
5425 1.1 joerg Handles opcode 0x0f,0xbe
5426 1.1 joerg ****************************************************************************/
5427 1.1 joerg static void
5428 1.1 joerg x86emuOp2_32_movsx_byte_R_RM(struct X86EMU *emu)
5429 1.1 joerg {
5430 1.1 joerg uint32_t *destreg;
5431 1.1 joerg
5432 1.8 joerg fetch_decode_modrm(emu);
5433 1.1 joerg destreg = decode_rh_long_register(emu);
5434 1.1 joerg *destreg = (int32_t)(int8_t)decode_and_fetch_byte(emu);
5435 1.1 joerg }
5436 1.1 joerg
5437 1.1 joerg static void
5438 1.1 joerg x86emuOp2_16_movsx_byte_R_RM(struct X86EMU *emu)
5439 1.1 joerg {
5440 1.1 joerg uint16_t *destreg;
5441 1.1 joerg
5442 1.1 joerg fetch_decode_modrm(emu);
5443 1.1 joerg destreg = decode_rh_word_register(emu);
5444 1.1 joerg *destreg = (int16_t)(int8_t)decode_and_fetch_byte(emu);
5445 1.1 joerg }
5446 1.1 joerg
5447 1.1 joerg static void
5448 1.1 joerg x86emuOp2_movsx_byte_R_RM(struct X86EMU *emu)
5449 1.1 joerg {
5450 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA)
5451 1.1 joerg x86emuOp2_32_movsx_byte_R_RM(emu);
5452 1.1 joerg else
5453 1.1 joerg x86emuOp2_16_movsx_byte_R_RM(emu);
5454 1.1 joerg }
5455 1.1 joerg /****************************************************************************
5456 1.1 joerg REMARKS:
5457 1.1 joerg Handles opcode 0x0f,0xbf
5458 1.1 joerg ****************************************************************************/
5459 1.1 joerg static void
5460 1.1 joerg x86emuOp2_movsx_word_R_RM(struct X86EMU *emu)
5461 1.1 joerg {
5462 1.1 joerg uint32_t *destreg;
5463 1.1 joerg
5464 1.1 joerg fetch_decode_modrm(emu);
5465 1.1 joerg destreg = decode_rh_long_register(emu);
5466 1.1 joerg *destreg = (int32_t)(int16_t)decode_and_fetch_word(emu);
5467 1.1 joerg }
5468 1.1 joerg
5469 1.1 joerg static void
5470 1.1 joerg X86EMU_exec_two_byte(struct X86EMU * emu)
5471 1.1 joerg {
5472 1.1 joerg uint8_t op2;
5473 1.1 joerg
5474 1.1 joerg op2 = fetch_byte_imm(emu);
5475 1.1 joerg
5476 1.1 joerg switch (op2) {
5477 1.1 joerg /* 0x00 Group F (ring 0 PM) */
5478 1.1 joerg /* 0x01 Group G (ring 0 PM) */
5479 1.1 joerg /* 0x02 lar (ring 0 PM) */
5480 1.1 joerg /* 0x03 lsl (ring 0 PM) */
5481 1.1 joerg /* 0x05 loadall (undocumented) */
5482 1.1 joerg /* 0x06 clts (ring 0 PM) */
5483 1.1 joerg /* 0x07 loadall (undocumented) */
5484 1.1 joerg /* 0x08 invd (ring 0 PM) */
5485 1.1 joerg /* 0x09 wbinvd (ring 0 PM) */
5486 1.1 joerg
5487 1.1 joerg /* 0x20 mov reg32(op2); break;creg (ring 0 PM) */
5488 1.1 joerg /* 0x21 mov reg32(op2); break;dreg (ring 0 PM) */
5489 1.1 joerg /* 0x22 mov creg(op2); break;reg32 (ring 0 PM) */
5490 1.1 joerg /* 0x23 mov dreg(op2); break;reg32 (ring 0 PM) */
5491 1.1 joerg /* 0x24 mov reg32(op2); break;treg (ring 0 PM) */
5492 1.1 joerg /* 0x26 mov treg(op2); break;reg32 (ring 0 PM) */
5493 1.1 joerg
5494 1.1 joerg case 0x31:
5495 1.1 joerg x86emuOp2_rdtsc(emu);
5496 1.1 joerg break;
5497 1.1 joerg
5498 1.1 joerg case 0x80:
5499 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_OF));
5500 1.1 joerg break;
5501 1.1 joerg case 0x81:
5502 1.1 joerg common_jmp_long(emu, !ACCESS_FLAG(F_OF));
5503 1.1 joerg break;
5504 1.1 joerg case 0x82:
5505 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_CF));
5506 1.1 joerg break;
5507 1.1 joerg case 0x83:
5508 1.1 joerg common_jmp_long(emu, !ACCESS_FLAG(F_CF));
5509 1.1 joerg break;
5510 1.1 joerg case 0x84:
5511 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_ZF));
5512 1.1 joerg break;
5513 1.1 joerg case 0x85:
5514 1.1 joerg common_jmp_long(emu, !ACCESS_FLAG(F_ZF));
5515 1.1 joerg break;
5516 1.1 joerg case 0x86:
5517 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
5518 1.1 joerg break;
5519 1.1 joerg case 0x87:
5520 1.1 joerg common_jmp_long(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
5521 1.1 joerg break;
5522 1.1 joerg case 0x88:
5523 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_SF));
5524 1.1 joerg break;
5525 1.1 joerg case 0x89:
5526 1.1 joerg common_jmp_long(emu, !ACCESS_FLAG(F_SF));
5527 1.1 joerg break;
5528 1.1 joerg case 0x8a:
5529 1.1 joerg common_jmp_long(emu, ACCESS_FLAG(F_PF));
5530 1.1 joerg break;
5531 1.1 joerg case 0x8b:
5532 1.1 joerg common_jmp_long(emu, !ACCESS_FLAG(F_PF));
5533 1.1 joerg break;
5534 1.1 joerg case 0x8c:
5535 1.1 joerg common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
5536 1.1 joerg break;
5537 1.1 joerg case 0x8d:
5538 1.1 joerg common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))));
5539 1.1 joerg break;
5540 1.1 joerg case 0x8e:
5541 1.1 joerg common_jmp_long(emu,
5542 1.1 joerg (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
5543 1.1 joerg break;
5544 1.1 joerg case 0x8f:
5545 1.1 joerg common_jmp_long(emu,
5546 1.1 joerg !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
5547 1.1 joerg break;
5548 1.1 joerg
5549 1.1 joerg case 0x90:
5550 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_OF));
5551 1.1 joerg break;
5552 1.1 joerg case 0x91:
5553 1.1 joerg common_set_byte(emu, !ACCESS_FLAG(F_OF));
5554 1.1 joerg break;
5555 1.1 joerg case 0x92:
5556 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_CF));
5557 1.1 joerg break;
5558 1.1 joerg case 0x93:
5559 1.1 joerg common_set_byte(emu, !ACCESS_FLAG(F_CF));
5560 1.1 joerg break;
5561 1.1 joerg case 0x94:
5562 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_ZF));
5563 1.1 joerg break;
5564 1.1 joerg case 0x95:
5565 1.1 joerg common_set_byte(emu, !ACCESS_FLAG(F_ZF));
5566 1.1 joerg break;
5567 1.1 joerg case 0x96:
5568 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
5569 1.1 joerg break;
5570 1.1 joerg case 0x97:
5571 1.1 joerg common_set_byte(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
5572 1.1 joerg break;
5573 1.1 joerg case 0x98:
5574 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_SF));
5575 1.1 joerg break;
5576 1.1 joerg case 0x99:
5577 1.1 joerg common_set_byte(emu, !ACCESS_FLAG(F_SF));
5578 1.1 joerg break;
5579 1.1 joerg case 0x9a:
5580 1.1 joerg common_set_byte(emu, ACCESS_FLAG(F_PF));
5581 1.1 joerg break;
5582 1.1 joerg case 0x9b:
5583 1.1 joerg common_set_byte(emu, !ACCESS_FLAG(F_PF));
5584 1.1 joerg break;
5585 1.1 joerg case 0x9c:
5586 1.1 joerg common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
5587 1.1 joerg break;
5588 1.1 joerg case 0x9d:
5589 1.1 joerg common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
5590 1.1 joerg break;
5591 1.1 joerg case 0x9e:
5592 1.1 joerg common_set_byte(emu,
5593 1.1 joerg (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
5594 1.1 joerg ACCESS_FLAG(F_ZF)));
5595 1.1 joerg break;
5596 1.1 joerg case 0x9f:
5597 1.1 joerg common_set_byte(emu,
5598 1.1 joerg !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
5599 1.1 joerg ACCESS_FLAG(F_ZF)));
5600 1.1 joerg break;
5601 1.1 joerg
5602 1.1 joerg case 0xa0:
5603 1.1 joerg x86emuOp2_push_FS(emu);
5604 1.1 joerg break;
5605 1.1 joerg case 0xa1:
5606 1.1 joerg x86emuOp2_pop_FS(emu);
5607 1.1 joerg break;
5608 1.4 jmcneill case 0xa2:
5609 1.4 jmcneill x86emuOp2_cpuid(emu);
5610 1.4 jmcneill break;
5611 1.1 joerg case 0xa3:
5612 1.1 joerg x86emuOp2_bt_R(emu);
5613 1.1 joerg break;
5614 1.1 joerg case 0xa4:
5615 1.1 joerg x86emuOp2_shld_IMM(emu);
5616 1.1 joerg break;
5617 1.1 joerg case 0xa5:
5618 1.1 joerg x86emuOp2_shld_CL(emu);
5619 1.1 joerg break;
5620 1.1 joerg case 0xa8:
5621 1.1 joerg x86emuOp2_push_GS(emu);
5622 1.1 joerg break;
5623 1.1 joerg case 0xa9:
5624 1.1 joerg x86emuOp2_pop_GS(emu);
5625 1.1 joerg break;
5626 1.1 joerg case 0xab:
5627 1.1 joerg x86emuOp2_bts_R(emu);
5628 1.1 joerg break;
5629 1.1 joerg case 0xac:
5630 1.1 joerg x86emuOp2_shrd_IMM(emu);
5631 1.1 joerg break;
5632 1.1 joerg case 0xad:
5633 1.1 joerg x86emuOp2_shrd_CL(emu);
5634 1.1 joerg break;
5635 1.1 joerg case 0xaf:
5636 1.1 joerg x86emuOp2_imul_R_RM(emu);
5637 1.1 joerg break;
5638 1.1 joerg
5639 1.1 joerg /* 0xb0 TODO: cmpxchg */
5640 1.1 joerg /* 0xb1 TODO: cmpxchg */
5641 1.1 joerg case 0xb2:
5642 1.1 joerg x86emuOp2_lss_R_IMM(emu);
5643 1.1 joerg break;
5644 1.1 joerg case 0xb3:
5645 1.1 joerg x86emuOp2_btr_R(emu);
5646 1.1 joerg break;
5647 1.1 joerg case 0xb4:
5648 1.1 joerg x86emuOp2_lfs_R_IMM(emu);
5649 1.1 joerg break;
5650 1.1 joerg case 0xb5:
5651 1.1 joerg x86emuOp2_lgs_R_IMM(emu);
5652 1.1 joerg break;
5653 1.1 joerg case 0xb6:
5654 1.1 joerg x86emuOp2_movzx_byte_R_RM(emu);
5655 1.1 joerg break;
5656 1.1 joerg case 0xb7:
5657 1.1 joerg x86emuOp2_movzx_word_R_RM(emu);
5658 1.1 joerg break;
5659 1.1 joerg case 0xba:
5660 1.1 joerg x86emuOp2_btX_I(emu);
5661 1.1 joerg break;
5662 1.1 joerg case 0xbb:
5663 1.1 joerg x86emuOp2_btc_R(emu);
5664 1.1 joerg break;
5665 1.1 joerg case 0xbc:
5666 1.1 joerg x86emuOp2_bsf(emu);
5667 1.1 joerg break;
5668 1.1 joerg case 0xbd:
5669 1.1 joerg x86emuOp2_bsr(emu);
5670 1.1 joerg break;
5671 1.1 joerg case 0xbe:
5672 1.1 joerg x86emuOp2_movsx_byte_R_RM(emu);
5673 1.1 joerg break;
5674 1.1 joerg case 0xbf:
5675 1.1 joerg x86emuOp2_movsx_word_R_RM(emu);
5676 1.1 joerg break;
5677 1.1 joerg
5678 1.1 joerg /* 0xc0 TODO: xadd */
5679 1.1 joerg /* 0xc1 TODO: xadd */
5680 1.1 joerg /* 0xc8 TODO: bswap */
5681 1.1 joerg /* 0xc9 TODO: bswap */
5682 1.1 joerg /* 0xca TODO: bswap */
5683 1.1 joerg /* 0xcb TODO: bswap */
5684 1.1 joerg /* 0xcc TODO: bswap */
5685 1.1 joerg /* 0xcd TODO: bswap */
5686 1.1 joerg /* 0xce TODO: bswap */
5687 1.1 joerg /* 0xcf TODO: bswap */
5688 1.1 joerg
5689 1.1 joerg default:
5690 1.1 joerg X86EMU_halt_sys(emu);
5691 1.1 joerg break;
5692 1.1 joerg }
5693 1.1 joerg }
5694 1.1 joerg
5695 1.1 joerg /*
5696 1.1 joerg * Carry Chain Calculation
5697 1.1 joerg *
5698 1.1 joerg * This represents a somewhat expensive calculation which is
5699 1.1 joerg * apparently required to emulate the setting of the OF and AF flag.
5700 1.1 joerg * The latter is not so important, but the former is. The overflow
5701 1.1 joerg * flag is the XOR of the top two bits of the carry chain for an
5702 1.1 joerg * addition (similar for subtraction). Since we do not want to
5703 1.1 joerg * simulate the addition in a bitwise manner, we try to calculate the
5704 1.1 joerg * carry chain given the two operands and the result.
5705 1.1 joerg *
5706 1.1 joerg * So, given the following table, which represents the addition of two
5707 1.1 joerg * bits, we can derive a formula for the carry chain.
5708 1.1 joerg *
5709 1.1 joerg * a b cin r cout
5710 1.1 joerg * 0 0 0 0 0
5711 1.1 joerg * 0 0 1 1 0
5712 1.1 joerg * 0 1 0 1 0
5713 1.1 joerg * 0 1 1 0 1
5714 1.1 joerg * 1 0 0 1 0
5715 1.1 joerg * 1 0 1 0 1
5716 1.1 joerg * 1 1 0 0 1
5717 1.1 joerg * 1 1 1 1 1
5718 1.1 joerg *
5719 1.1 joerg * Construction of table for cout:
5720 1.1 joerg *
5721 1.1 joerg * ab
5722 1.1 joerg * r \ 00 01 11 10
5723 1.1 joerg * |------------------
5724 1.1 joerg * 0 | 0 1 1 1
5725 1.1 joerg * 1 | 0 0 1 0
5726 1.1 joerg *
5727 1.1 joerg * By inspection, one gets: cc = ab + r'(a + b)
5728 1.1 joerg *
5729 1.1 joerg * That represents alot of operations, but NO CHOICE....
5730 1.1 joerg *
5731 1.1 joerg * Borrow Chain Calculation.
5732 1.1 joerg *
5733 1.1 joerg * The following table represents the subtraction of two bits, from
5734 1.1 joerg * which we can derive a formula for the borrow chain.
5735 1.1 joerg *
5736 1.1 joerg * a b bin r bout
5737 1.1 joerg * 0 0 0 0 0
5738 1.1 joerg * 0 0 1 1 1
5739 1.1 joerg * 0 1 0 1 1
5740 1.1 joerg * 0 1 1 0 1
5741 1.1 joerg * 1 0 0 1 0
5742 1.1 joerg * 1 0 1 0 0
5743 1.1 joerg * 1 1 0 0 0
5744 1.1 joerg * 1 1 1 1 1
5745 1.1 joerg *
5746 1.1 joerg * Construction of table for cout:
5747 1.1 joerg *
5748 1.1 joerg * ab
5749 1.1 joerg * r \ 00 01 11 10
5750 1.1 joerg * |------------------
5751 1.1 joerg * 0 | 0 1 0 0
5752 1.1 joerg * 1 | 1 1 1 0
5753 1.1 joerg *
5754 1.1 joerg * By inspection, one gets: bc = a'b + r(a' + b)
5755 1.1 joerg *
5756 1.1 joerg ****************************************************************************/
5757 1.1 joerg
5758 1.1 joerg /*------------------------- Global Variables ------------------------------*/
5759 1.1 joerg
5760 1.1 joerg static uint32_t x86emu_parity_tab[8] =
5761 1.1 joerg {
5762 1.1 joerg 0x96696996,
5763 1.1 joerg 0x69969669,
5764 1.1 joerg 0x69969669,
5765 1.1 joerg 0x96696996,
5766 1.1 joerg 0x69969669,
5767 1.1 joerg 0x96696996,
5768 1.1 joerg 0x96696996,
5769 1.1 joerg 0x69969669,
5770 1.1 joerg };
5771 1.1 joerg #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
5772 1.1 joerg #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
5773 1.1 joerg
5774 1.1 joerg /****************************************************************************
5775 1.1 joerg REMARKS:
5776 1.1 joerg Implements the AAA instruction and side effects.
5777 1.1 joerg ****************************************************************************/
5778 1.1 joerg static uint16_t
5779 1.1 joerg aaa_word(struct X86EMU *emu, uint16_t d)
5780 1.1 joerg {
5781 1.1 joerg uint16_t res;
5782 1.1 joerg if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
5783 1.1 joerg d += 0x6;
5784 1.1 joerg d += 0x100;
5785 1.1 joerg SET_FLAG(F_AF);
5786 1.1 joerg SET_FLAG(F_CF);
5787 1.1 joerg } else {
5788 1.1 joerg CLEAR_FLAG(F_CF);
5789 1.1 joerg CLEAR_FLAG(F_AF);
5790 1.1 joerg }
5791 1.1 joerg res = (uint16_t) (d & 0xFF0F);
5792 1.1 joerg CLEAR_FLAG(F_SF);
5793 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
5794 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5795 1.1 joerg return res;
5796 1.1 joerg }
5797 1.1 joerg /****************************************************************************
5798 1.1 joerg REMARKS:
5799 1.1 joerg Implements the AAA instruction and side effects.
5800 1.1 joerg ****************************************************************************/
5801 1.1 joerg static uint16_t
5802 1.1 joerg aas_word(struct X86EMU *emu, uint16_t d)
5803 1.1 joerg {
5804 1.1 joerg uint16_t res;
5805 1.1 joerg if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
5806 1.1 joerg d -= 0x6;
5807 1.1 joerg d -= 0x100;
5808 1.1 joerg SET_FLAG(F_AF);
5809 1.1 joerg SET_FLAG(F_CF);
5810 1.1 joerg } else {
5811 1.1 joerg CLEAR_FLAG(F_CF);
5812 1.1 joerg CLEAR_FLAG(F_AF);
5813 1.1 joerg }
5814 1.1 joerg res = (uint16_t) (d & 0xFF0F);
5815 1.1 joerg CLEAR_FLAG(F_SF);
5816 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
5817 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5818 1.1 joerg return res;
5819 1.1 joerg }
5820 1.1 joerg /****************************************************************************
5821 1.1 joerg REMARKS:
5822 1.1 joerg Implements the AAD instruction and side effects.
5823 1.1 joerg ****************************************************************************/
5824 1.1 joerg static uint16_t
5825 1.1 joerg aad_word(struct X86EMU *emu, uint16_t d)
5826 1.1 joerg {
5827 1.1 joerg uint16_t l;
5828 1.1 joerg uint8_t hb, lb;
5829 1.1 joerg
5830 1.1 joerg hb = (uint8_t) ((d >> 8) & 0xff);
5831 1.1 joerg lb = (uint8_t) ((d & 0xff));
5832 1.1 joerg l = (uint16_t) ((lb + 10 * hb) & 0xFF);
5833 1.1 joerg
5834 1.1 joerg CLEAR_FLAG(F_CF);
5835 1.1 joerg CLEAR_FLAG(F_AF);
5836 1.1 joerg CLEAR_FLAG(F_OF);
5837 1.1 joerg CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
5838 1.1 joerg CONDITIONAL_SET_FLAG(l == 0, F_ZF);
5839 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
5840 1.1 joerg return l;
5841 1.1 joerg }
5842 1.1 joerg /****************************************************************************
5843 1.1 joerg REMARKS:
5844 1.1 joerg Implements the AAM instruction and side effects.
5845 1.1 joerg ****************************************************************************/
5846 1.1 joerg static uint16_t
5847 1.1 joerg aam_word(struct X86EMU *emu, uint8_t d)
5848 1.1 joerg {
5849 1.1 joerg uint16_t h, l;
5850 1.1 joerg
5851 1.1 joerg h = (uint16_t) (d / 10);
5852 1.1 joerg l = (uint16_t) (d % 10);
5853 1.1 joerg l |= (uint16_t) (h << 8);
5854 1.1 joerg
5855 1.1 joerg CLEAR_FLAG(F_CF);
5856 1.1 joerg CLEAR_FLAG(F_AF);
5857 1.1 joerg CLEAR_FLAG(F_OF);
5858 1.1 joerg CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
5859 1.1 joerg CONDITIONAL_SET_FLAG(l == 0, F_ZF);
5860 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
5861 1.1 joerg return l;
5862 1.1 joerg }
5863 1.1 joerg /****************************************************************************
5864 1.1 joerg REMARKS:
5865 1.1 joerg Implements the ADC instruction and side effects.
5866 1.1 joerg ****************************************************************************/
5867 1.1 joerg static uint8_t
5868 1.1 joerg adc_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
5869 1.1 joerg {
5870 1.1 joerg uint32_t res; /* all operands in native machine order */
5871 1.1 joerg uint32_t cc;
5872 1.1 joerg
5873 1.1 joerg if (ACCESS_FLAG(F_CF))
5874 1.1 joerg res = 1 + d + s;
5875 1.1 joerg else
5876 1.1 joerg res = d + s;
5877 1.1 joerg
5878 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
5879 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
5880 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
5881 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5882 1.1 joerg
5883 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
5884 1.1 joerg cc = (s & d) | ((~res) & (s | d));
5885 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
5886 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
5887 1.1 joerg return (uint8_t) res;
5888 1.1 joerg }
5889 1.1 joerg /****************************************************************************
5890 1.1 joerg REMARKS:
5891 1.1 joerg Implements the ADC instruction and side effects.
5892 1.1 joerg ****************************************************************************/
5893 1.1 joerg static uint16_t
5894 1.1 joerg adc_word(struct X86EMU *emu, uint16_t d, uint16_t s)
5895 1.1 joerg {
5896 1.1 joerg uint32_t res; /* all operands in native machine order */
5897 1.1 joerg uint32_t cc;
5898 1.1 joerg
5899 1.1 joerg if (ACCESS_FLAG(F_CF))
5900 1.1 joerg res = 1 + d + s;
5901 1.1 joerg else
5902 1.1 joerg res = d + s;
5903 1.1 joerg
5904 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
5905 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
5906 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
5907 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5908 1.1 joerg
5909 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
5910 1.1 joerg cc = (s & d) | ((~res) & (s | d));
5911 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
5912 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
5913 1.1 joerg return (uint16_t) res;
5914 1.1 joerg }
5915 1.1 joerg /****************************************************************************
5916 1.1 joerg REMARKS:
5917 1.1 joerg Implements the ADC instruction and side effects.
5918 1.1 joerg ****************************************************************************/
5919 1.1 joerg static uint32_t
5920 1.1 joerg adc_long(struct X86EMU *emu, uint32_t d, uint32_t s)
5921 1.1 joerg {
5922 1.1 joerg uint32_t lo; /* all operands in native machine order */
5923 1.1 joerg uint32_t hi;
5924 1.1 joerg uint32_t res;
5925 1.1 joerg uint32_t cc;
5926 1.1 joerg
5927 1.1 joerg if (ACCESS_FLAG(F_CF)) {
5928 1.1 joerg lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
5929 1.1 joerg res = 1 + d + s;
5930 1.1 joerg } else {
5931 1.1 joerg lo = (d & 0xFFFF) + (s & 0xFFFF);
5932 1.1 joerg res = d + s;
5933 1.1 joerg }
5934 1.1 joerg hi = (lo >> 16) + (d >> 16) + (s >> 16);
5935 1.1 joerg
5936 1.1 joerg CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
5937 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
5938 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
5939 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5940 1.1 joerg
5941 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
5942 1.1 joerg cc = (s & d) | ((~res) & (s | d));
5943 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
5944 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
5945 1.1 joerg return res;
5946 1.1 joerg }
5947 1.1 joerg /****************************************************************************
5948 1.1 joerg REMARKS:
5949 1.1 joerg Implements the ADD instruction and side effects.
5950 1.1 joerg ****************************************************************************/
5951 1.1 joerg static uint8_t
5952 1.1 joerg add_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
5953 1.1 joerg {
5954 1.1 joerg uint32_t res; /* all operands in native machine order */
5955 1.1 joerg uint32_t cc;
5956 1.1 joerg
5957 1.1 joerg res = d + s;
5958 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
5959 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
5960 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
5961 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5962 1.1 joerg
5963 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
5964 1.1 joerg cc = (s & d) | ((~res) & (s | d));
5965 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
5966 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
5967 1.1 joerg return (uint8_t) res;
5968 1.1 joerg }
5969 1.1 joerg /****************************************************************************
5970 1.1 joerg REMARKS:
5971 1.1 joerg Implements the ADD instruction and side effects.
5972 1.1 joerg ****************************************************************************/
5973 1.1 joerg static uint16_t
5974 1.1 joerg add_word(struct X86EMU *emu, uint16_t d, uint16_t s)
5975 1.1 joerg {
5976 1.1 joerg uint32_t res; /* all operands in native machine order */
5977 1.1 joerg uint32_t cc;
5978 1.1 joerg
5979 1.1 joerg res = d + s;
5980 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
5981 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
5982 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
5983 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
5984 1.1 joerg
5985 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
5986 1.1 joerg cc = (s & d) | ((~res) & (s | d));
5987 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
5988 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
5989 1.1 joerg return (uint16_t) res;
5990 1.1 joerg }
5991 1.1 joerg /****************************************************************************
5992 1.1 joerg REMARKS:
5993 1.1 joerg Implements the ADD instruction and side effects.
5994 1.1 joerg ****************************************************************************/
5995 1.1 joerg static uint32_t
5996 1.1 joerg add_long(struct X86EMU *emu, uint32_t d, uint32_t s)
5997 1.1 joerg {
5998 1.1 joerg uint32_t lo; /* all operands in native machine order */
5999 1.1 joerg uint32_t hi;
6000 1.1 joerg uint32_t res;
6001 1.1 joerg uint32_t cc;
6002 1.1 joerg
6003 1.1 joerg lo = (d & 0xFFFF) + (s & 0xFFFF);
6004 1.1 joerg res = d + s;
6005 1.1 joerg hi = (lo >> 16) + (d >> 16) + (s >> 16);
6006 1.1 joerg
6007 1.1 joerg CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
6008 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
6009 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6010 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6011 1.1 joerg
6012 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
6013 1.1 joerg cc = (s & d) | ((~res) & (s | d));
6014 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
6015 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
6016 1.1 joerg
6017 1.1 joerg return res;
6018 1.1 joerg }
6019 1.1 joerg /****************************************************************************
6020 1.1 joerg REMARKS:
6021 1.1 joerg Implements the AND instruction and side effects.
6022 1.1 joerg ****************************************************************************/
6023 1.1 joerg static uint8_t
6024 1.1 joerg and_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6025 1.1 joerg {
6026 1.1 joerg uint8_t res; /* all operands in native machine order */
6027 1.1 joerg
6028 1.1 joerg res = d & s;
6029 1.1 joerg
6030 1.1 joerg /* set the flags */
6031 1.1 joerg CLEAR_FLAG(F_OF);
6032 1.1 joerg CLEAR_FLAG(F_CF);
6033 1.1 joerg CLEAR_FLAG(F_AF);
6034 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6035 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6036 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
6037 1.1 joerg return res;
6038 1.1 joerg }
6039 1.1 joerg /****************************************************************************
6040 1.1 joerg REMARKS:
6041 1.1 joerg Implements the AND instruction and side effects.
6042 1.1 joerg ****************************************************************************/
6043 1.1 joerg static uint16_t
6044 1.1 joerg and_word(struct X86EMU *emu, uint16_t d, uint16_t s)
6045 1.1 joerg {
6046 1.1 joerg uint16_t res; /* all operands in native machine order */
6047 1.1 joerg
6048 1.1 joerg res = d & s;
6049 1.1 joerg
6050 1.1 joerg /* set the flags */
6051 1.1 joerg CLEAR_FLAG(F_OF);
6052 1.1 joerg CLEAR_FLAG(F_CF);
6053 1.1 joerg CLEAR_FLAG(F_AF);
6054 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6055 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6056 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6057 1.1 joerg return res;
6058 1.1 joerg }
6059 1.1 joerg /****************************************************************************
6060 1.1 joerg REMARKS:
6061 1.1 joerg Implements the AND instruction and side effects.
6062 1.1 joerg ****************************************************************************/
6063 1.1 joerg static uint32_t
6064 1.1 joerg and_long(struct X86EMU *emu, uint32_t d, uint32_t s)
6065 1.1 joerg {
6066 1.1 joerg uint32_t res; /* all operands in native machine order */
6067 1.1 joerg
6068 1.1 joerg res = d & s;
6069 1.1 joerg
6070 1.1 joerg /* set the flags */
6071 1.1 joerg CLEAR_FLAG(F_OF);
6072 1.1 joerg CLEAR_FLAG(F_CF);
6073 1.1 joerg CLEAR_FLAG(F_AF);
6074 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6075 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6076 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6077 1.1 joerg return res;
6078 1.1 joerg }
6079 1.1 joerg /****************************************************************************
6080 1.1 joerg REMARKS:
6081 1.1 joerg Implements the CMP instruction and side effects.
6082 1.1 joerg ****************************************************************************/
6083 1.1 joerg static uint8_t
6084 1.1 joerg cmp_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6085 1.1 joerg {
6086 1.1 joerg uint32_t res; /* all operands in native machine order */
6087 1.1 joerg uint32_t bc;
6088 1.1 joerg
6089 1.1 joerg res = d - s;
6090 1.1 joerg CLEAR_FLAG(F_CF);
6091 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6092 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
6093 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6094 1.1 joerg
6095 1.1 joerg /* calculate the borrow chain. See note at top */
6096 1.1 joerg bc = (res & (~d | s)) | (~d & s);
6097 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
6098 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
6099 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6100 1.1 joerg return d;
6101 1.1 joerg }
6102 1.1 joerg
6103 1.1 joerg static void
6104 1.1 joerg cmp_byte_no_return(struct X86EMU *emu, uint8_t d, uint8_t s)
6105 1.1 joerg {
6106 1.1 joerg cmp_byte(emu, d, s);
6107 1.1 joerg }
6108 1.1 joerg /****************************************************************************
6109 1.1 joerg REMARKS:
6110 1.1 joerg Implements the CMP instruction and side effects.
6111 1.1 joerg ****************************************************************************/
6112 1.1 joerg static uint16_t
6113 1.1 joerg cmp_word(struct X86EMU *emu, uint16_t d, uint16_t s)
6114 1.1 joerg {
6115 1.1 joerg uint32_t res; /* all operands in native machine order */
6116 1.1 joerg uint32_t bc;
6117 1.1 joerg
6118 1.1 joerg res = d - s;
6119 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6120 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
6121 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6122 1.1 joerg
6123 1.1 joerg /* calculate the borrow chain. See note at top */
6124 1.1 joerg bc = (res & (~d | s)) | (~d & s);
6125 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
6126 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
6127 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6128 1.1 joerg return d;
6129 1.1 joerg }
6130 1.1 joerg
6131 1.1 joerg static void
6132 1.1 joerg cmp_word_no_return(struct X86EMU *emu, uint16_t d, uint16_t s)
6133 1.1 joerg {
6134 1.1 joerg cmp_word(emu, d, s);
6135 1.1 joerg }
6136 1.1 joerg /****************************************************************************
6137 1.1 joerg REMARKS:
6138 1.1 joerg Implements the CMP instruction and side effects.
6139 1.1 joerg ****************************************************************************/
6140 1.1 joerg static uint32_t
6141 1.1 joerg cmp_long(struct X86EMU *emu, uint32_t d, uint32_t s)
6142 1.1 joerg {
6143 1.1 joerg uint32_t res; /* all operands in native machine order */
6144 1.1 joerg uint32_t bc;
6145 1.1 joerg
6146 1.1 joerg res = d - s;
6147 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6148 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
6149 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6150 1.1 joerg
6151 1.1 joerg /* calculate the borrow chain. See note at top */
6152 1.1 joerg bc = (res & (~d | s)) | (~d & s);
6153 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
6154 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
6155 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6156 1.1 joerg return d;
6157 1.1 joerg }
6158 1.1 joerg
6159 1.1 joerg static void
6160 1.1 joerg cmp_long_no_return(struct X86EMU *emu, uint32_t d, uint32_t s)
6161 1.1 joerg {
6162 1.1 joerg cmp_long(emu, d, s);
6163 1.1 joerg }
6164 1.1 joerg /****************************************************************************
6165 1.1 joerg REMARKS:
6166 1.1 joerg Implements the DAA instruction and side effects.
6167 1.1 joerg ****************************************************************************/
6168 1.1 joerg static uint8_t
6169 1.1 joerg daa_byte(struct X86EMU *emu, uint8_t d)
6170 1.1 joerg {
6171 1.1 joerg uint32_t res = d;
6172 1.1 joerg if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
6173 1.1 joerg res += 6;
6174 1.1 joerg SET_FLAG(F_AF);
6175 1.1 joerg }
6176 1.1 joerg if (res > 0x9F || ACCESS_FLAG(F_CF)) {
6177 1.1 joerg res += 0x60;
6178 1.1 joerg SET_FLAG(F_CF);
6179 1.1 joerg }
6180 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6181 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
6182 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6183 1.1 joerg return (uint8_t) res;
6184 1.1 joerg }
6185 1.1 joerg /****************************************************************************
6186 1.1 joerg REMARKS:
6187 1.1 joerg Implements the DAS instruction and side effects.
6188 1.1 joerg ****************************************************************************/
6189 1.1 joerg static uint8_t
6190 1.1 joerg das_byte(struct X86EMU *emu, uint8_t d)
6191 1.1 joerg {
6192 1.1 joerg if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
6193 1.1 joerg d -= 6;
6194 1.1 joerg SET_FLAG(F_AF);
6195 1.1 joerg }
6196 1.1 joerg if (d > 0x9F || ACCESS_FLAG(F_CF)) {
6197 1.1 joerg d -= 0x60;
6198 1.1 joerg SET_FLAG(F_CF);
6199 1.1 joerg }
6200 1.1 joerg CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
6201 1.1 joerg CONDITIONAL_SET_FLAG(d == 0, F_ZF);
6202 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
6203 1.1 joerg return d;
6204 1.1 joerg }
6205 1.1 joerg /****************************************************************************
6206 1.1 joerg REMARKS:
6207 1.1 joerg Implements the DEC instruction and side effects.
6208 1.1 joerg ****************************************************************************/
6209 1.1 joerg static uint8_t
6210 1.1 joerg dec_byte(struct X86EMU *emu, uint8_t d)
6211 1.1 joerg {
6212 1.1 joerg uint32_t res; /* all operands in native machine order */
6213 1.1 joerg uint32_t bc;
6214 1.1 joerg
6215 1.1 joerg res = d - 1;
6216 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6217 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
6218 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6219 1.1 joerg
6220 1.1 joerg /* calculate the borrow chain. See note at top */
6221 1.1 joerg /* based on sub_byte, uses s==1. */
6222 1.1 joerg bc = (res & (~d | 1)) | (~d & 1);
6223 1.1 joerg /* carry flag unchanged */
6224 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
6225 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6226 1.1 joerg return (uint8_t) res;
6227 1.1 joerg }
6228 1.1 joerg /****************************************************************************
6229 1.1 joerg REMARKS:
6230 1.1 joerg Implements the DEC instruction and side effects.
6231 1.1 joerg ****************************************************************************/
6232 1.1 joerg static uint16_t
6233 1.1 joerg dec_word(struct X86EMU *emu, uint16_t d)
6234 1.1 joerg {
6235 1.1 joerg uint32_t res; /* all operands in native machine order */
6236 1.1 joerg uint32_t bc;
6237 1.1 joerg
6238 1.1 joerg res = d - 1;
6239 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6240 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
6241 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6242 1.1 joerg
6243 1.1 joerg /* calculate the borrow chain. See note at top */
6244 1.1 joerg /* based on the sub_byte routine, with s==1 */
6245 1.1 joerg bc = (res & (~d | 1)) | (~d & 1);
6246 1.1 joerg /* carry flag unchanged */
6247 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
6248 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6249 1.1 joerg return (uint16_t) res;
6250 1.1 joerg }
6251 1.1 joerg /****************************************************************************
6252 1.1 joerg REMARKS:
6253 1.1 joerg Implements the DEC instruction and side effects.
6254 1.1 joerg ****************************************************************************/
6255 1.1 joerg static uint32_t
6256 1.1 joerg dec_long(struct X86EMU *emu, uint32_t d)
6257 1.1 joerg {
6258 1.1 joerg uint32_t res; /* all operands in native machine order */
6259 1.1 joerg uint32_t bc;
6260 1.1 joerg
6261 1.1 joerg res = d - 1;
6262 1.1 joerg
6263 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6264 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
6265 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6266 1.1 joerg
6267 1.1 joerg /* calculate the borrow chain. See note at top */
6268 1.1 joerg bc = (res & (~d | 1)) | (~d & 1);
6269 1.1 joerg /* carry flag unchanged */
6270 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
6271 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6272 1.1 joerg return res;
6273 1.1 joerg }
6274 1.1 joerg /****************************************************************************
6275 1.1 joerg REMARKS:
6276 1.1 joerg Implements the INC instruction and side effects.
6277 1.1 joerg ****************************************************************************/
6278 1.1 joerg static uint8_t
6279 1.1 joerg inc_byte(struct X86EMU *emu, uint8_t d)
6280 1.1 joerg {
6281 1.1 joerg uint32_t res; /* all operands in native machine order */
6282 1.1 joerg uint32_t cc;
6283 1.1 joerg
6284 1.1 joerg res = d + 1;
6285 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
6286 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6287 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6288 1.1 joerg
6289 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
6290 1.1 joerg cc = ((1 & d) | (~res)) & (1 | d);
6291 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
6292 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
6293 1.1 joerg return (uint8_t) res;
6294 1.1 joerg }
6295 1.1 joerg /****************************************************************************
6296 1.1 joerg REMARKS:
6297 1.1 joerg Implements the INC instruction and side effects.
6298 1.1 joerg ****************************************************************************/
6299 1.1 joerg static uint16_t
6300 1.1 joerg inc_word(struct X86EMU *emu, uint16_t d)
6301 1.1 joerg {
6302 1.1 joerg uint32_t res; /* all operands in native machine order */
6303 1.1 joerg uint32_t cc;
6304 1.1 joerg
6305 1.1 joerg res = d + 1;
6306 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
6307 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6308 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6309 1.1 joerg
6310 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
6311 1.1 joerg cc = (1 & d) | ((~res) & (1 | d));
6312 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
6313 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
6314 1.1 joerg return (uint16_t) res;
6315 1.1 joerg }
6316 1.1 joerg /****************************************************************************
6317 1.1 joerg REMARKS:
6318 1.1 joerg Implements the INC instruction and side effects.
6319 1.1 joerg ****************************************************************************/
6320 1.1 joerg static uint32_t
6321 1.1 joerg inc_long(struct X86EMU *emu, uint32_t d)
6322 1.1 joerg {
6323 1.1 joerg uint32_t res; /* all operands in native machine order */
6324 1.1 joerg uint32_t cc;
6325 1.1 joerg
6326 1.1 joerg res = d + 1;
6327 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
6328 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6329 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6330 1.1 joerg
6331 1.1 joerg /* calculate the carry chain SEE NOTE AT TOP. */
6332 1.1 joerg cc = (1 & d) | ((~res) & (1 | d));
6333 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
6334 1.1 joerg CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
6335 1.1 joerg return res;
6336 1.1 joerg }
6337 1.1 joerg /****************************************************************************
6338 1.1 joerg REMARKS:
6339 1.1 joerg Implements the OR instruction and side effects.
6340 1.1 joerg ****************************************************************************/
6341 1.1 joerg static uint8_t
6342 1.1 joerg or_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6343 1.1 joerg {
6344 1.1 joerg uint8_t res; /* all operands in native machine order */
6345 1.1 joerg
6346 1.1 joerg res = d | s;
6347 1.1 joerg CLEAR_FLAG(F_OF);
6348 1.1 joerg CLEAR_FLAG(F_CF);
6349 1.1 joerg CLEAR_FLAG(F_AF);
6350 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6351 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6352 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
6353 1.1 joerg return res;
6354 1.1 joerg }
6355 1.1 joerg /****************************************************************************
6356 1.1 joerg REMARKS:
6357 1.1 joerg Implements the OR instruction and side effects.
6358 1.1 joerg ****************************************************************************/
6359 1.1 joerg static uint16_t
6360 1.1 joerg or_word(struct X86EMU *emu, uint16_t d, uint16_t s)
6361 1.1 joerg {
6362 1.1 joerg uint16_t res; /* all operands in native machine order */
6363 1.1 joerg
6364 1.1 joerg res = d | s;
6365 1.1 joerg /* set the carry flag to be bit 8 */
6366 1.1 joerg CLEAR_FLAG(F_OF);
6367 1.1 joerg CLEAR_FLAG(F_CF);
6368 1.1 joerg CLEAR_FLAG(F_AF);
6369 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6370 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6371 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6372 1.1 joerg return res;
6373 1.1 joerg }
6374 1.1 joerg /****************************************************************************
6375 1.1 joerg REMARKS:
6376 1.1 joerg Implements the OR instruction and side effects.
6377 1.1 joerg ****************************************************************************/
6378 1.1 joerg static uint32_t
6379 1.1 joerg or_long(struct X86EMU *emu, uint32_t d, uint32_t s)
6380 1.1 joerg {
6381 1.1 joerg uint32_t res; /* all operands in native machine order */
6382 1.1 joerg
6383 1.1 joerg res = d | s;
6384 1.1 joerg
6385 1.1 joerg /* set the carry flag to be bit 8 */
6386 1.1 joerg CLEAR_FLAG(F_OF);
6387 1.1 joerg CLEAR_FLAG(F_CF);
6388 1.1 joerg CLEAR_FLAG(F_AF);
6389 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6390 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
6391 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6392 1.1 joerg return res;
6393 1.1 joerg }
6394 1.1 joerg /****************************************************************************
6395 1.1 joerg REMARKS:
6396 1.1 joerg Implements the OR instruction and side effects.
6397 1.1 joerg ****************************************************************************/
6398 1.1 joerg static uint8_t
6399 1.1 joerg neg_byte(struct X86EMU *emu, uint8_t s)
6400 1.1 joerg {
6401 1.1 joerg uint8_t res;
6402 1.1 joerg uint8_t bc;
6403 1.1 joerg
6404 1.1 joerg CONDITIONAL_SET_FLAG(s != 0, F_CF);
6405 1.1 joerg res = (uint8_t) - s;
6406 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
6407 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6408 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
6409 1.1 joerg /* calculate the borrow chain --- modified such that d=0.
6410 1.1 joerg * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
6411 1.1 joerg * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
6412 1.1 joerg * res&0xfff... == res. Similarly ~d&s == s. So the simplified
6413 1.1 joerg * result is: */
6414 1.1 joerg bc = res | s;
6415 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
6416 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6417 1.1 joerg return res;
6418 1.1 joerg }
6419 1.1 joerg /****************************************************************************
6420 1.1 joerg REMARKS:
6421 1.1 joerg Implements the OR instruction and side effects.
6422 1.1 joerg ****************************************************************************/
6423 1.1 joerg static uint16_t
6424 1.1 joerg neg_word(struct X86EMU *emu, uint16_t s)
6425 1.1 joerg {
6426 1.1 joerg uint16_t res;
6427 1.1 joerg uint16_t bc;
6428 1.1 joerg
6429 1.1 joerg CONDITIONAL_SET_FLAG(s != 0, F_CF);
6430 1.1 joerg res = (uint16_t) - s;
6431 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
6432 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6433 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6434 1.1 joerg
6435 1.1 joerg /* calculate the borrow chain --- modified such that d=0.
6436 1.1 joerg * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
6437 1.1 joerg * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
6438 1.1 joerg * res&0xfff... == res. Similarly ~d&s == s. So the simplified
6439 1.1 joerg * result is: */
6440 1.1 joerg bc = res | s;
6441 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
6442 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6443 1.1 joerg return res;
6444 1.1 joerg }
6445 1.1 joerg /****************************************************************************
6446 1.1 joerg REMARKS:
6447 1.1 joerg Implements the OR instruction and side effects.
6448 1.1 joerg ****************************************************************************/
6449 1.1 joerg static uint32_t
6450 1.1 joerg neg_long(struct X86EMU *emu, uint32_t s)
6451 1.1 joerg {
6452 1.1 joerg uint32_t res;
6453 1.1 joerg uint32_t bc;
6454 1.1 joerg
6455 1.1 joerg CONDITIONAL_SET_FLAG(s != 0, F_CF);
6456 1.1 joerg res = (uint32_t) - s;
6457 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
6458 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
6459 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6460 1.1 joerg
6461 1.1 joerg /* calculate the borrow chain --- modified such that d=0.
6462 1.1 joerg * substitutiing d=0 into bc= res&(~d|s)|(~d&s); (the one used for
6463 1.1 joerg * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
6464 1.1 joerg * res&0xfff... == res. Similarly ~d&s == s. So the simplified
6465 1.1 joerg * result is: */
6466 1.1 joerg bc = res | s;
6467 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
6468 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
6469 1.1 joerg return res;
6470 1.1 joerg }
6471 1.1 joerg /****************************************************************************
6472 1.1 joerg REMARKS:
6473 1.1 joerg Implements the RCL instruction and side effects.
6474 1.1 joerg ****************************************************************************/
6475 1.1 joerg static uint8_t
6476 1.1 joerg rcl_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6477 1.1 joerg {
6478 1.1 joerg unsigned int res, cnt, mask, cf;
6479 1.1 joerg
6480 1.1 joerg /* s is the rotate distance. It varies from 0 - 8. */
6481 1.1 joerg /* have
6482 1.1 joerg *
6483 1.1 joerg * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
6484 1.1 joerg *
6485 1.1 joerg * want to rotate through the carry by "s" bits. We could loop, but
6486 1.1 joerg * that's inefficient. So the width is 9, and we split into three
6487 1.1 joerg * parts:
6488 1.1 joerg *
6489 1.1 joerg * The new carry flag (was B_n) the stuff in B_n-1 .. B_0 the stuff in
6490 1.1 joerg * B_7 .. B_n+1
6491 1.1 joerg *
6492 1.1 joerg * The new rotate is done mod 9, and given this, for a rotation of n bits
6493 1.1 joerg * (mod 9) the new carry flag is then located n bits from the MSB.
6494 1.1 joerg * The low part is then shifted up cnt bits, and the high part is or'd
6495 1.1 joerg * in. Using CAPS for new values, and lowercase for the original
6496 1.1 joerg * values, this can be expressed as:
6497 1.1 joerg *
6498 1.1 joerg * IF n > 0 1) CF <- b_(8-n) 2) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0
6499 1.1 joerg * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
6500 1.1 joerg res = d;
6501 1.1 joerg if ((cnt = s % 9) != 0) {
6502 1.1 joerg /* extract the new CARRY FLAG. */
6503 1.1 joerg /* CF <- b_(8-n) */
6504 1.1 joerg cf = (d >> (8 - cnt)) & 0x1;
6505 1.1 joerg
6506 1.1 joerg /* get the low stuff which rotated into the range B_7 .. B_cnt */
6507 1.1 joerg /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_0 */
6508 1.1 joerg /* note that the right hand side done by the mask */
6509 1.1 joerg res = (d << cnt) & 0xff;
6510 1.1 joerg
6511 1.1 joerg /* now the high stuff which rotated around into the positions
6512 1.1 joerg * B_cnt-2 .. B_0 */
6513 1.1 joerg /* B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */
6514 1.1 joerg /* shift it downward, 7-(n-2) = 9-n positions. and mask off
6515 1.1 joerg * the result before or'ing in. */
6516 1.1 joerg mask = (1 << (cnt - 1)) - 1;
6517 1.1 joerg res |= (d >> (9 - cnt)) & mask;
6518 1.1 joerg
6519 1.1 joerg /* if the carry flag was set, or it in. */
6520 1.1 joerg if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
6521 1.1 joerg /* B_(n-1) <- cf */
6522 1.1 joerg res |= 1 << (cnt - 1);
6523 1.1 joerg }
6524 1.1 joerg /* set the new carry flag, based on the variable "cf" */
6525 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6526 1.1 joerg /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
6527 1.1 joerg * the most significant bit. Blecck. */
6528 1.1 joerg /* parenthesized this expression since it appears to be
6529 1.1 joerg * causing OF to be misset */
6530 1.1 joerg CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
6531 1.1 joerg F_OF);
6532 1.1 joerg
6533 1.1 joerg }
6534 1.1 joerg return (uint8_t) res;
6535 1.1 joerg }
6536 1.1 joerg /****************************************************************************
6537 1.1 joerg REMARKS:
6538 1.1 joerg Implements the RCL instruction and side effects.
6539 1.1 joerg ****************************************************************************/
6540 1.1 joerg static uint16_t
6541 1.1 joerg rcl_word(struct X86EMU *emu, uint16_t d, uint8_t s)
6542 1.1 joerg {
6543 1.1 joerg unsigned int res, cnt, mask, cf;
6544 1.1 joerg
6545 1.1 joerg res = d;
6546 1.1 joerg if ((cnt = s % 17) != 0) {
6547 1.1 joerg cf = (d >> (16 - cnt)) & 0x1;
6548 1.1 joerg res = (d << cnt) & 0xffff;
6549 1.1 joerg mask = (1 << (cnt - 1)) - 1;
6550 1.1 joerg res |= (d >> (17 - cnt)) & mask;
6551 1.1 joerg if (ACCESS_FLAG(F_CF)) {
6552 1.1 joerg res |= 1 << (cnt - 1);
6553 1.1 joerg }
6554 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6555 1.1 joerg CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
6556 1.1 joerg F_OF);
6557 1.1 joerg }
6558 1.1 joerg return (uint16_t) res;
6559 1.1 joerg }
6560 1.1 joerg /****************************************************************************
6561 1.1 joerg REMARKS:
6562 1.1 joerg Implements the RCL instruction and side effects.
6563 1.1 joerg ****************************************************************************/
6564 1.1 joerg static uint32_t
6565 1.1 joerg rcl_long(struct X86EMU *emu, uint32_t d, uint8_t s)
6566 1.1 joerg {
6567 1.1 joerg uint32_t res, cnt, mask, cf;
6568 1.1 joerg
6569 1.1 joerg res = d;
6570 1.1 joerg if ((cnt = s % 33) != 0) {
6571 1.1 joerg cf = (d >> (32 - cnt)) & 0x1;
6572 1.1 joerg res = (d << cnt) & 0xffffffff;
6573 1.1 joerg mask = (1 << (cnt - 1)) - 1;
6574 1.1 joerg res |= (d >> (33 - cnt)) & mask;
6575 1.1 joerg if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
6576 1.1 joerg res |= 1 << (cnt - 1);
6577 1.1 joerg }
6578 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6579 1.1 joerg CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
6580 1.1 joerg F_OF);
6581 1.1 joerg }
6582 1.1 joerg return res;
6583 1.1 joerg }
6584 1.1 joerg /****************************************************************************
6585 1.1 joerg REMARKS:
6586 1.1 joerg Implements the RCR instruction and side effects.
6587 1.1 joerg ****************************************************************************/
6588 1.1 joerg static uint8_t
6589 1.1 joerg rcr_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6590 1.1 joerg {
6591 1.1 joerg uint32_t res, cnt;
6592 1.1 joerg uint32_t mask, cf, ocf = 0;
6593 1.1 joerg
6594 1.1 joerg /* rotate right through carry */
6595 1.1 joerg /* s is the rotate distance. It varies from 0 - 8. d is the byte
6596 1.1 joerg * object rotated.
6597 1.1 joerg *
6598 1.1 joerg * have
6599 1.1 joerg *
6600 1.1 joerg * CF B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
6601 1.1 joerg *
6602 1.1 joerg * The new rotate is done mod 9, and given this, for a rotation of n bits
6603 1.1 joerg * (mod 9) the new carry flag is then located n bits from the LSB.
6604 1.1 joerg * The low part is then shifted up cnt bits, and the high part is or'd
6605 1.1 joerg * in. Using CAPS for new values, and lowercase for the original
6606 1.1 joerg * values, this can be expressed as:
6607 1.1 joerg *
6608 1.1 joerg * IF n > 0 1) CF <- b_(n-1) 2) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n)
6609 1.1 joerg * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
6610 1.1 joerg res = d;
6611 1.1 joerg if ((cnt = s % 9) != 0) {
6612 1.1 joerg /* extract the new CARRY FLAG. */
6613 1.1 joerg /* CF <- b_(n-1) */
6614 1.1 joerg if (cnt == 1) {
6615 1.1 joerg cf = d & 0x1;
6616 1.1 joerg /* note hackery here. Access_flag(..) evaluates to
6617 1.1 joerg * either 0 if flag not set non-zero if flag is set.
6618 1.1 joerg * doing access_flag(..) != 0 casts that into either
6619 1.1 joerg * 0..1 in any representation of the flags register
6620 1.1 joerg * (i.e. packed bit array or unpacked.) */
6621 1.1 joerg ocf = ACCESS_FLAG(F_CF) != 0;
6622 1.1 joerg } else
6623 1.1 joerg cf = (d >> (cnt - 1)) & 0x1;
6624 1.1 joerg
6625 1.1 joerg /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_n */
6626 1.1 joerg /* note that the right hand side done by the mask This is
6627 1.1 joerg * effectively done by shifting the object to the right. The
6628 1.1 joerg * result must be masked, in case the object came in and was
6629 1.1 joerg * treated as a negative number. Needed??? */
6630 1.1 joerg
6631 1.1 joerg mask = (1 << (8 - cnt)) - 1;
6632 1.1 joerg res = (d >> cnt) & mask;
6633 1.1 joerg
6634 1.1 joerg /* now the high stuff which rotated around into the positions
6635 1.1 joerg * B_cnt-2 .. B_0 */
6636 1.1 joerg /* B_(7) .. B_(8-(n-1)) <- b_(n-2) .. b_(0) */
6637 1.1 joerg /* shift it downward, 7-(n-2) = 9-n positions. and mask off
6638 1.1 joerg * the result before or'ing in. */
6639 1.1 joerg res |= (d << (9 - cnt));
6640 1.1 joerg
6641 1.1 joerg /* if the carry flag was set, or it in. */
6642 1.1 joerg if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
6643 1.1 joerg /* B_(8-n) <- cf */
6644 1.1 joerg res |= 1 << (8 - cnt);
6645 1.1 joerg }
6646 1.1 joerg /* set the new carry flag, based on the variable "cf" */
6647 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6648 1.1 joerg /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
6649 1.1 joerg * the most significant bit. Blecck. */
6650 1.1 joerg /* parenthesized... */
6651 1.1 joerg if (cnt == 1) {
6652 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
6653 1.1 joerg F_OF);
6654 1.1 joerg }
6655 1.1 joerg }
6656 1.1 joerg return (uint8_t) res;
6657 1.1 joerg }
6658 1.1 joerg /****************************************************************************
6659 1.1 joerg REMARKS:
6660 1.1 joerg Implements the RCR instruction and side effects.
6661 1.1 joerg ****************************************************************************/
6662 1.1 joerg static uint16_t
6663 1.1 joerg rcr_word(struct X86EMU *emu, uint16_t d, uint8_t s)
6664 1.1 joerg {
6665 1.1 joerg uint32_t res, cnt;
6666 1.1 joerg uint32_t mask, cf, ocf = 0;
6667 1.1 joerg
6668 1.1 joerg /* rotate right through carry */
6669 1.1 joerg res = d;
6670 1.1 joerg if ((cnt = s % 17) != 0) {
6671 1.1 joerg if (cnt == 1) {
6672 1.1 joerg cf = d & 0x1;
6673 1.1 joerg ocf = ACCESS_FLAG(F_CF) != 0;
6674 1.1 joerg } else
6675 1.1 joerg cf = (d >> (cnt - 1)) & 0x1;
6676 1.1 joerg mask = (1 << (16 - cnt)) - 1;
6677 1.1 joerg res = (d >> cnt) & mask;
6678 1.1 joerg res |= (d << (17 - cnt));
6679 1.1 joerg if (ACCESS_FLAG(F_CF)) {
6680 1.1 joerg res |= 1 << (16 - cnt);
6681 1.1 joerg }
6682 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6683 1.1 joerg if (cnt == 1) {
6684 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
6685 1.1 joerg F_OF);
6686 1.1 joerg }
6687 1.1 joerg }
6688 1.1 joerg return (uint16_t) res;
6689 1.1 joerg }
6690 1.1 joerg /****************************************************************************
6691 1.1 joerg REMARKS:
6692 1.1 joerg Implements the RCR instruction and side effects.
6693 1.1 joerg ****************************************************************************/
6694 1.1 joerg static uint32_t
6695 1.1 joerg rcr_long(struct X86EMU *emu, uint32_t d, uint8_t s)
6696 1.1 joerg {
6697 1.1 joerg uint32_t res, cnt;
6698 1.1 joerg uint32_t mask, cf, ocf = 0;
6699 1.1 joerg
6700 1.1 joerg /* rotate right through carry */
6701 1.1 joerg res = d;
6702 1.1 joerg if ((cnt = s % 33) != 0) {
6703 1.1 joerg if (cnt == 1) {
6704 1.1 joerg cf = d & 0x1;
6705 1.1 joerg ocf = ACCESS_FLAG(F_CF) != 0;
6706 1.1 joerg } else
6707 1.1 joerg cf = (d >> (cnt - 1)) & 0x1;
6708 1.1 joerg mask = (1 << (32 - cnt)) - 1;
6709 1.1 joerg res = (d >> cnt) & mask;
6710 1.1 joerg if (cnt != 1)
6711 1.1 joerg res |= (d << (33 - cnt));
6712 1.1 joerg if (ACCESS_FLAG(F_CF)) { /* carry flag is set */
6713 1.1 joerg res |= 1 << (32 - cnt);
6714 1.1 joerg }
6715 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6716 1.1 joerg if (cnt == 1) {
6717 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
6718 1.1 joerg F_OF);
6719 1.1 joerg }
6720 1.1 joerg }
6721 1.1 joerg return res;
6722 1.1 joerg }
6723 1.1 joerg /****************************************************************************
6724 1.1 joerg REMARKS:
6725 1.1 joerg Implements the ROL instruction and side effects.
6726 1.1 joerg ****************************************************************************/
6727 1.1 joerg static uint8_t
6728 1.1 joerg rol_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6729 1.1 joerg {
6730 1.1 joerg unsigned int res, cnt, mask;
6731 1.1 joerg
6732 1.1 joerg /* rotate left */
6733 1.1 joerg /* s is the rotate distance. It varies from 0 - 8. d is the byte
6734 1.1 joerg * object rotated.
6735 1.1 joerg *
6736 1.1 joerg * have
6737 1.1 joerg *
6738 1.1 joerg * CF B_7 ... B_0
6739 1.1 joerg *
6740 1.1 joerg * The new rotate is done mod 8. Much simpler than the "rcl" or "rcr"
6741 1.1 joerg * operations.
6742 1.1 joerg *
6743 1.1 joerg * IF n > 0 1) B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) 2) B_(n-1) ..
6744 1.1 joerg * B_(0) <- b_(7) .. b_(8-n) */
6745 1.1 joerg res = d;
6746 1.1 joerg if ((cnt = s % 8) != 0) {
6747 1.1 joerg /* B_(7) .. B_(n) <- b_(8-(n+1)) .. b_(0) */
6748 1.1 joerg res = (d << cnt);
6749 1.1 joerg
6750 1.1 joerg /* B_(n-1) .. B_(0) <- b_(7) .. b_(8-n) */
6751 1.1 joerg mask = (1 << cnt) - 1;
6752 1.1 joerg res |= (d >> (8 - cnt)) & mask;
6753 1.1 joerg
6754 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6755 1.1 joerg * of the result!!! */
6756 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6757 1.1 joerg /* OVERFLOW is set *IFF* s==1, then it is the xor of CF and
6758 1.1 joerg * the most significant bit. Blecck. */
6759 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 &&
6760 1.1 joerg XOR2((res & 0x1) + ((res >> 6) & 0x2)),
6761 1.1 joerg F_OF);
6762 1.1 joerg } if (s != 0) {
6763 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6764 1.1 joerg * of the result!!! */
6765 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6766 1.1 joerg }
6767 1.1 joerg return (uint8_t) res;
6768 1.1 joerg }
6769 1.1 joerg /****************************************************************************
6770 1.1 joerg REMARKS:
6771 1.1 joerg Implements the ROL instruction and side effects.
6772 1.1 joerg ****************************************************************************/
6773 1.1 joerg static uint16_t
6774 1.1 joerg rol_word(struct X86EMU *emu, uint16_t d, uint8_t s)
6775 1.1 joerg {
6776 1.1 joerg unsigned int res, cnt, mask;
6777 1.1 joerg
6778 1.1 joerg res = d;
6779 1.1 joerg if ((cnt = s % 16) != 0) {
6780 1.1 joerg res = (d << cnt);
6781 1.1 joerg mask = (1 << cnt) - 1;
6782 1.1 joerg res |= (d >> (16 - cnt)) & mask;
6783 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6784 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 &&
6785 1.1 joerg XOR2((res & 0x1) + ((res >> 14) & 0x2)),
6786 1.1 joerg F_OF);
6787 1.1 joerg } if (s != 0) {
6788 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6789 1.1 joerg * of the result!!! */
6790 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6791 1.1 joerg }
6792 1.1 joerg return (uint16_t) res;
6793 1.1 joerg }
6794 1.1 joerg /****************************************************************************
6795 1.1 joerg REMARKS:
6796 1.1 joerg Implements the ROL instruction and side effects.
6797 1.1 joerg ****************************************************************************/
6798 1.1 joerg static uint32_t
6799 1.1 joerg rol_long(struct X86EMU *emu, uint32_t d, uint8_t s)
6800 1.1 joerg {
6801 1.1 joerg uint32_t res, cnt, mask;
6802 1.1 joerg
6803 1.1 joerg res = d;
6804 1.1 joerg if ((cnt = s % 32) != 0) {
6805 1.1 joerg res = (d << cnt);
6806 1.1 joerg mask = (1 << cnt) - 1;
6807 1.1 joerg res |= (d >> (32 - cnt)) & mask;
6808 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6809 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 &&
6810 1.1 joerg XOR2((res & 0x1) + ((res >> 30) & 0x2)),
6811 1.1 joerg F_OF);
6812 1.1 joerg } if (s != 0) {
6813 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6814 1.1 joerg * of the result!!! */
6815 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
6816 1.1 joerg }
6817 1.1 joerg return res;
6818 1.1 joerg }
6819 1.1 joerg /****************************************************************************
6820 1.1 joerg REMARKS:
6821 1.1 joerg Implements the ROR instruction and side effects.
6822 1.1 joerg ****************************************************************************/
6823 1.1 joerg static uint8_t
6824 1.1 joerg ror_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6825 1.1 joerg {
6826 1.1 joerg unsigned int res, cnt, mask;
6827 1.1 joerg
6828 1.1 joerg /* rotate right */
6829 1.1 joerg /* s is the rotate distance. It varies from 0 - 8. d is the byte
6830 1.1 joerg * object rotated.
6831 1.1 joerg *
6832 1.1 joerg * have
6833 1.1 joerg *
6834 1.1 joerg * B_7 ... B_0
6835 1.1 joerg *
6836 1.1 joerg * The rotate is done mod 8.
6837 1.1 joerg *
6838 1.1 joerg * IF n > 0 1) B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) 2) B_(7) ..
6839 1.1 joerg * B_(8-n) <- b_(n-1) .. b_(0) */
6840 1.1 joerg res = d;
6841 1.1 joerg if ((cnt = s % 8) != 0) { /* not a typo, do nada if cnt==0 */
6842 1.1 joerg /* B_(7) .. B_(8-n) <- b_(n-1) .. b_(0) */
6843 1.1 joerg res = (d << (8 - cnt));
6844 1.1 joerg
6845 1.1 joerg /* B_(8-(n+1)) .. B_(0) <- b_(7) .. b_(n) */
6846 1.1 joerg mask = (1 << (8 - cnt)) - 1;
6847 1.1 joerg res |= (d >> (cnt)) & mask;
6848 1.1 joerg
6849 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6850 1.1 joerg * of the result!!! */
6851 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
6852 1.1 joerg /* OVERFLOW is set *IFF* s==1, then it is the xor of the two
6853 1.1 joerg * most significant bits. Blecck. */
6854 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
6855 1.1 joerg } else if (s != 0) {
6856 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6857 1.1 joerg * of the result!!! */
6858 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
6859 1.1 joerg }
6860 1.1 joerg return (uint8_t) res;
6861 1.1 joerg }
6862 1.1 joerg /****************************************************************************
6863 1.1 joerg REMARKS:
6864 1.1 joerg Implements the ROR instruction and side effects.
6865 1.1 joerg ****************************************************************************/
6866 1.1 joerg static uint16_t
6867 1.1 joerg ror_word(struct X86EMU *emu, uint16_t d, uint8_t s)
6868 1.1 joerg {
6869 1.1 joerg unsigned int res, cnt, mask;
6870 1.1 joerg
6871 1.1 joerg res = d;
6872 1.1 joerg if ((cnt = s % 16) != 0) {
6873 1.1 joerg res = (d << (16 - cnt));
6874 1.1 joerg mask = (1 << (16 - cnt)) - 1;
6875 1.1 joerg res |= (d >> (cnt)) & mask;
6876 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
6877 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
6878 1.1 joerg } else if (s != 0) {
6879 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6880 1.1 joerg * of the result!!! */
6881 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
6882 1.1 joerg }
6883 1.1 joerg return (uint16_t) res;
6884 1.1 joerg }
6885 1.1 joerg /****************************************************************************
6886 1.1 joerg REMARKS:
6887 1.1 joerg Implements the ROR instruction and side effects.
6888 1.1 joerg ****************************************************************************/
6889 1.1 joerg static uint32_t
6890 1.1 joerg ror_long(struct X86EMU *emu, uint32_t d, uint8_t s)
6891 1.1 joerg {
6892 1.1 joerg uint32_t res, cnt, mask;
6893 1.1 joerg
6894 1.1 joerg res = d;
6895 1.1 joerg if ((cnt = s % 32) != 0) {
6896 1.1 joerg res = (d << (32 - cnt));
6897 1.1 joerg mask = (1 << (32 - cnt)) - 1;
6898 1.1 joerg res |= (d >> (cnt)) & mask;
6899 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
6900 1.1 joerg CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
6901 1.1 joerg } else if (s != 0) {
6902 1.1 joerg /* set the new carry flag, Note that it is the low order bit
6903 1.1 joerg * of the result!!! */
6904 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
6905 1.1 joerg }
6906 1.1 joerg return res;
6907 1.1 joerg }
6908 1.1 joerg /****************************************************************************
6909 1.1 joerg REMARKS:
6910 1.1 joerg Implements the SHL instruction and side effects.
6911 1.1 joerg ****************************************************************************/
6912 1.1 joerg static uint8_t
6913 1.1 joerg shl_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
6914 1.1 joerg {
6915 1.1 joerg unsigned int cnt, res, cf;
6916 1.1 joerg
6917 1.1 joerg if (s < 8) {
6918 1.1 joerg cnt = s % 8;
6919 1.1 joerg
6920 1.1 joerg /* last bit shifted out goes into carry flag */
6921 1.1 joerg if (cnt > 0) {
6922 1.1 joerg res = d << cnt;
6923 1.1 joerg cf = d & (1 << (8 - cnt));
6924 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6925 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
6926 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
6927 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6928 1.1 joerg } else {
6929 1.1 joerg res = (uint8_t) d;
6930 1.1 joerg }
6931 1.1 joerg
6932 1.1 joerg if (cnt == 1) {
6933 1.1 joerg /* Needs simplification. */
6934 1.1 joerg CONDITIONAL_SET_FLAG(
6935 1.1 joerg (((res & 0x80) == 0x80) ^
6936 1.1 joerg (ACCESS_FLAG(F_CF) != 0)),
6937 1.1 joerg /* was (emu->x86.R_FLG&F_CF)==F_CF)), */
6938 1.1 joerg F_OF);
6939 1.1 joerg } else {
6940 1.1 joerg CLEAR_FLAG(F_OF);
6941 1.1 joerg }
6942 1.1 joerg } else {
6943 1.1 joerg res = 0;
6944 1.1 joerg CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
6945 1.1 joerg CLEAR_FLAG(F_OF);
6946 1.1 joerg CLEAR_FLAG(F_SF);
6947 1.1 joerg SET_FLAG(F_PF);
6948 1.1 joerg SET_FLAG(F_ZF);
6949 1.1 joerg }
6950 1.1 joerg return (uint8_t) res;
6951 1.1 joerg }
6952 1.1 joerg /****************************************************************************
6953 1.1 joerg REMARKS:
6954 1.1 joerg Implements the SHL instruction and side effects.
6955 1.1 joerg ****************************************************************************/
6956 1.1 joerg static uint16_t
6957 1.1 joerg shl_word(struct X86EMU *emu, uint16_t d, uint8_t s)
6958 1.1 joerg {
6959 1.1 joerg unsigned int cnt, res, cf;
6960 1.1 joerg
6961 1.1 joerg if (s < 16) {
6962 1.1 joerg cnt = s % 16;
6963 1.1 joerg if (cnt > 0) {
6964 1.1 joerg res = d << cnt;
6965 1.1 joerg cf = d & (1 << (16 - cnt));
6966 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
6967 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
6968 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
6969 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
6970 1.1 joerg } else {
6971 1.1 joerg res = (uint16_t) d;
6972 1.1 joerg }
6973 1.1 joerg
6974 1.1 joerg if (cnt == 1) {
6975 1.1 joerg CONDITIONAL_SET_FLAG(
6976 1.1 joerg (((res & 0x8000) == 0x8000) ^
6977 1.1 joerg (ACCESS_FLAG(F_CF) != 0)),
6978 1.1 joerg F_OF);
6979 1.1 joerg } else {
6980 1.1 joerg CLEAR_FLAG(F_OF);
6981 1.1 joerg }
6982 1.1 joerg } else {
6983 1.1 joerg res = 0;
6984 1.1 joerg CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
6985 1.1 joerg CLEAR_FLAG(F_OF);
6986 1.1 joerg CLEAR_FLAG(F_SF);
6987 1.1 joerg SET_FLAG(F_PF);
6988 1.1 joerg SET_FLAG(F_ZF);
6989 1.1 joerg }
6990 1.1 joerg return (uint16_t) res;
6991 1.1 joerg }
6992 1.1 joerg /****************************************************************************
6993 1.1 joerg REMARKS:
6994 1.1 joerg Implements the SHL instruction and side effects.
6995 1.1 joerg ****************************************************************************/
6996 1.1 joerg static uint32_t
6997 1.1 joerg shl_long(struct X86EMU *emu, uint32_t d, uint8_t s)
6998 1.1 joerg {
6999 1.1 joerg unsigned int cnt, res, cf;
7000 1.1 joerg
7001 1.1 joerg if (s < 32) {
7002 1.1 joerg cnt = s % 32;
7003 1.1 joerg if (cnt > 0) {
7004 1.1 joerg res = d << cnt;
7005 1.1 joerg cf = d & (1 << (32 - cnt));
7006 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7007 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7008 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7009 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7010 1.1 joerg } else {
7011 1.1 joerg res = d;
7012 1.1 joerg }
7013 1.1 joerg if (cnt == 1) {
7014 1.1 joerg CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
7015 1.1 joerg (ACCESS_FLAG(F_CF) != 0)), F_OF);
7016 1.1 joerg } else {
7017 1.1 joerg CLEAR_FLAG(F_OF);
7018 1.1 joerg }
7019 1.1 joerg } else {
7020 1.1 joerg res = 0;
7021 1.1 joerg CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
7022 1.1 joerg CLEAR_FLAG(F_OF);
7023 1.1 joerg CLEAR_FLAG(F_SF);
7024 1.1 joerg SET_FLAG(F_PF);
7025 1.1 joerg SET_FLAG(F_ZF);
7026 1.1 joerg }
7027 1.1 joerg return res;
7028 1.1 joerg }
7029 1.1 joerg /****************************************************************************
7030 1.1 joerg REMARKS:
7031 1.1 joerg Implements the SHR instruction and side effects.
7032 1.1 joerg ****************************************************************************/
7033 1.1 joerg static uint8_t
7034 1.1 joerg shr_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7035 1.1 joerg {
7036 1.1 joerg unsigned int cnt, res, cf;
7037 1.1 joerg
7038 1.1 joerg if (s < 8) {
7039 1.1 joerg cnt = s % 8;
7040 1.1 joerg if (cnt > 0) {
7041 1.1 joerg cf = d & (1 << (cnt - 1));
7042 1.1 joerg res = d >> cnt;
7043 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7044 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
7045 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7046 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7047 1.1 joerg } else {
7048 1.1 joerg res = (uint8_t) d;
7049 1.1 joerg }
7050 1.1 joerg
7051 1.1 joerg if (cnt == 1) {
7052 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
7053 1.1 joerg } else {
7054 1.1 joerg CLEAR_FLAG(F_OF);
7055 1.1 joerg }
7056 1.1 joerg } else {
7057 1.1 joerg res = 0;
7058 1.1 joerg CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
7059 1.1 joerg CLEAR_FLAG(F_OF);
7060 1.1 joerg CLEAR_FLAG(F_SF);
7061 1.1 joerg SET_FLAG(F_PF);
7062 1.1 joerg SET_FLAG(F_ZF);
7063 1.1 joerg }
7064 1.1 joerg return (uint8_t) res;
7065 1.1 joerg }
7066 1.1 joerg /****************************************************************************
7067 1.1 joerg REMARKS:
7068 1.1 joerg Implements the SHR instruction and side effects.
7069 1.1 joerg ****************************************************************************/
7070 1.1 joerg static uint16_t
7071 1.1 joerg shr_word(struct X86EMU *emu, uint16_t d, uint8_t s)
7072 1.1 joerg {
7073 1.1 joerg unsigned int cnt, res, cf;
7074 1.1 joerg
7075 1.1 joerg if (s < 16) {
7076 1.1 joerg cnt = s % 16;
7077 1.1 joerg if (cnt > 0) {
7078 1.1 joerg cf = d & (1 << (cnt - 1));
7079 1.1 joerg res = d >> cnt;
7080 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7081 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7082 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7083 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7084 1.1 joerg } else {
7085 1.1 joerg res = d;
7086 1.1 joerg }
7087 1.1 joerg
7088 1.1 joerg if (cnt == 1) {
7089 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
7090 1.1 joerg } else {
7091 1.1 joerg CLEAR_FLAG(F_OF);
7092 1.1 joerg }
7093 1.1 joerg } else {
7094 1.1 joerg res = 0;
7095 1.1 joerg CLEAR_FLAG(F_CF);
7096 1.1 joerg CLEAR_FLAG(F_OF);
7097 1.1 joerg SET_FLAG(F_ZF);
7098 1.1 joerg CLEAR_FLAG(F_SF);
7099 1.1 joerg CLEAR_FLAG(F_PF);
7100 1.1 joerg }
7101 1.1 joerg return (uint16_t) res;
7102 1.1 joerg }
7103 1.1 joerg /****************************************************************************
7104 1.1 joerg REMARKS:
7105 1.1 joerg Implements the SHR instruction and side effects.
7106 1.1 joerg ****************************************************************************/
7107 1.1 joerg static uint32_t
7108 1.1 joerg shr_long(struct X86EMU *emu, uint32_t d, uint8_t s)
7109 1.1 joerg {
7110 1.1 joerg unsigned int cnt, res, cf;
7111 1.1 joerg
7112 1.1 joerg if (s < 32) {
7113 1.1 joerg cnt = s % 32;
7114 1.1 joerg if (cnt > 0) {
7115 1.1 joerg cf = d & (1 << (cnt - 1));
7116 1.1 joerg res = d >> cnt;
7117 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7118 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7119 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7120 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7121 1.1 joerg } else {
7122 1.1 joerg res = d;
7123 1.1 joerg }
7124 1.1 joerg if (cnt == 1) {
7125 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
7126 1.1 joerg } else {
7127 1.1 joerg CLEAR_FLAG(F_OF);
7128 1.1 joerg }
7129 1.1 joerg } else {
7130 1.1 joerg res = 0;
7131 1.1 joerg CLEAR_FLAG(F_CF);
7132 1.1 joerg CLEAR_FLAG(F_OF);
7133 1.1 joerg SET_FLAG(F_ZF);
7134 1.1 joerg CLEAR_FLAG(F_SF);
7135 1.1 joerg CLEAR_FLAG(F_PF);
7136 1.1 joerg }
7137 1.1 joerg return res;
7138 1.1 joerg }
7139 1.1 joerg /****************************************************************************
7140 1.1 joerg REMARKS:
7141 1.1 joerg Implements the SAR instruction and side effects.
7142 1.1 joerg ****************************************************************************/
7143 1.1 joerg static uint8_t
7144 1.1 joerg sar_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7145 1.1 joerg {
7146 1.1 joerg unsigned int cnt, res, cf, mask, sf;
7147 1.1 joerg
7148 1.1 joerg res = d;
7149 1.1 joerg sf = d & 0x80;
7150 1.1 joerg cnt = s % 8;
7151 1.1 joerg if (cnt > 0 && cnt < 8) {
7152 1.1 joerg mask = (1 << (8 - cnt)) - 1;
7153 1.1 joerg cf = d & (1 << (cnt - 1));
7154 1.1 joerg res = (d >> cnt) & mask;
7155 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7156 1.1 joerg if (sf) {
7157 1.1 joerg res |= ~mask;
7158 1.1 joerg }
7159 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
7160 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7161 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7162 1.1 joerg } else if (cnt >= 8) {
7163 1.1 joerg if (sf) {
7164 1.1 joerg res = 0xff;
7165 1.1 joerg SET_FLAG(F_CF);
7166 1.1 joerg CLEAR_FLAG(F_ZF);
7167 1.1 joerg SET_FLAG(F_SF);
7168 1.1 joerg SET_FLAG(F_PF);
7169 1.1 joerg } else {
7170 1.1 joerg res = 0;
7171 1.1 joerg CLEAR_FLAG(F_CF);
7172 1.1 joerg SET_FLAG(F_ZF);
7173 1.1 joerg CLEAR_FLAG(F_SF);
7174 1.1 joerg CLEAR_FLAG(F_PF);
7175 1.1 joerg }
7176 1.1 joerg }
7177 1.1 joerg return (uint8_t) res;
7178 1.1 joerg }
7179 1.1 joerg /****************************************************************************
7180 1.1 joerg REMARKS:
7181 1.1 joerg Implements the SAR instruction and side effects.
7182 1.1 joerg ****************************************************************************/
7183 1.1 joerg static uint16_t
7184 1.1 joerg sar_word(struct X86EMU *emu, uint16_t d, uint8_t s)
7185 1.1 joerg {
7186 1.1 joerg unsigned int cnt, res, cf, mask, sf;
7187 1.1 joerg
7188 1.1 joerg sf = d & 0x8000;
7189 1.1 joerg cnt = s % 16;
7190 1.1 joerg res = d;
7191 1.1 joerg if (cnt > 0 && cnt < 16) {
7192 1.1 joerg mask = (1 << (16 - cnt)) - 1;
7193 1.1 joerg cf = d & (1 << (cnt - 1));
7194 1.1 joerg res = (d >> cnt) & mask;
7195 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7196 1.1 joerg if (sf) {
7197 1.1 joerg res |= ~mask;
7198 1.1 joerg }
7199 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7200 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7201 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7202 1.1 joerg } else if (cnt >= 16) {
7203 1.1 joerg if (sf) {
7204 1.1 joerg res = 0xffff;
7205 1.1 joerg SET_FLAG(F_CF);
7206 1.1 joerg CLEAR_FLAG(F_ZF);
7207 1.1 joerg SET_FLAG(F_SF);
7208 1.1 joerg SET_FLAG(F_PF);
7209 1.1 joerg } else {
7210 1.1 joerg res = 0;
7211 1.1 joerg CLEAR_FLAG(F_CF);
7212 1.1 joerg SET_FLAG(F_ZF);
7213 1.1 joerg CLEAR_FLAG(F_SF);
7214 1.1 joerg CLEAR_FLAG(F_PF);
7215 1.1 joerg }
7216 1.1 joerg }
7217 1.1 joerg return (uint16_t) res;
7218 1.1 joerg }
7219 1.1 joerg /****************************************************************************
7220 1.1 joerg REMARKS:
7221 1.1 joerg Implements the SAR instruction and side effects.
7222 1.1 joerg ****************************************************************************/
7223 1.1 joerg static uint32_t
7224 1.1 joerg sar_long(struct X86EMU *emu, uint32_t d, uint8_t s)
7225 1.1 joerg {
7226 1.1 joerg uint32_t cnt, res, cf, mask, sf;
7227 1.1 joerg
7228 1.1 joerg sf = d & 0x80000000;
7229 1.1 joerg cnt = s % 32;
7230 1.1 joerg res = d;
7231 1.1 joerg if (cnt > 0 && cnt < 32) {
7232 1.1 joerg mask = (1 << (32 - cnt)) - 1;
7233 1.1 joerg cf = d & (1 << (cnt - 1));
7234 1.1 joerg res = (d >> cnt) & mask;
7235 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7236 1.1 joerg if (sf) {
7237 1.1 joerg res |= ~mask;
7238 1.1 joerg }
7239 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7240 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7241 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7242 1.1 joerg } else if (cnt >= 32) {
7243 1.1 joerg if (sf) {
7244 1.1 joerg res = 0xffffffff;
7245 1.1 joerg SET_FLAG(F_CF);
7246 1.1 joerg CLEAR_FLAG(F_ZF);
7247 1.1 joerg SET_FLAG(F_SF);
7248 1.1 joerg SET_FLAG(F_PF);
7249 1.1 joerg } else {
7250 1.1 joerg res = 0;
7251 1.1 joerg CLEAR_FLAG(F_CF);
7252 1.1 joerg SET_FLAG(F_ZF);
7253 1.1 joerg CLEAR_FLAG(F_SF);
7254 1.1 joerg CLEAR_FLAG(F_PF);
7255 1.1 joerg }
7256 1.1 joerg }
7257 1.1 joerg return res;
7258 1.1 joerg }
7259 1.1 joerg /****************************************************************************
7260 1.1 joerg REMARKS:
7261 1.1 joerg Implements the SHLD instruction and side effects.
7262 1.1 joerg ****************************************************************************/
7263 1.1 joerg static uint16_t
7264 1.1 joerg shld_word(struct X86EMU *emu, uint16_t d, uint16_t fill, uint8_t s)
7265 1.1 joerg {
7266 1.1 joerg unsigned int cnt, res, cf;
7267 1.1 joerg
7268 1.1 joerg if (s < 16) {
7269 1.1 joerg cnt = s % 16;
7270 1.1 joerg if (cnt > 0) {
7271 1.1 joerg res = (d << cnt) | (fill >> (16 - cnt));
7272 1.1 joerg cf = d & (1 << (16 - cnt));
7273 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7274 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7275 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7276 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7277 1.1 joerg } else {
7278 1.1 joerg res = d;
7279 1.1 joerg }
7280 1.1 joerg if (cnt == 1) {
7281 1.1 joerg CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
7282 1.1 joerg (ACCESS_FLAG(F_CF) != 0)), F_OF);
7283 1.1 joerg } else {
7284 1.1 joerg CLEAR_FLAG(F_OF);
7285 1.1 joerg }
7286 1.1 joerg } else {
7287 1.1 joerg res = 0;
7288 1.1 joerg CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
7289 1.1 joerg CLEAR_FLAG(F_OF);
7290 1.1 joerg CLEAR_FLAG(F_SF);
7291 1.1 joerg SET_FLAG(F_PF);
7292 1.1 joerg SET_FLAG(F_ZF);
7293 1.1 joerg }
7294 1.1 joerg return (uint16_t) res;
7295 1.1 joerg }
7296 1.1 joerg /****************************************************************************
7297 1.1 joerg REMARKS:
7298 1.1 joerg Implements the SHLD instruction and side effects.
7299 1.1 joerg ****************************************************************************/
7300 1.1 joerg static uint32_t
7301 1.1 joerg shld_long(struct X86EMU *emu, uint32_t d, uint32_t fill, uint8_t s)
7302 1.1 joerg {
7303 1.1 joerg unsigned int cnt, res, cf;
7304 1.1 joerg
7305 1.1 joerg if (s < 32) {
7306 1.1 joerg cnt = s % 32;
7307 1.1 joerg if (cnt > 0) {
7308 1.1 joerg res = (d << cnt) | (fill >> (32 - cnt));
7309 1.1 joerg cf = d & (1 << (32 - cnt));
7310 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7311 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7312 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7313 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7314 1.1 joerg } else {
7315 1.1 joerg res = d;
7316 1.1 joerg }
7317 1.1 joerg if (cnt == 1) {
7318 1.1 joerg CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
7319 1.1 joerg (ACCESS_FLAG(F_CF) != 0)), F_OF);
7320 1.1 joerg } else {
7321 1.1 joerg CLEAR_FLAG(F_OF);
7322 1.1 joerg }
7323 1.1 joerg } else {
7324 1.1 joerg res = 0;
7325 1.1 joerg CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
7326 1.1 joerg CLEAR_FLAG(F_OF);
7327 1.1 joerg CLEAR_FLAG(F_SF);
7328 1.1 joerg SET_FLAG(F_PF);
7329 1.1 joerg SET_FLAG(F_ZF);
7330 1.1 joerg }
7331 1.1 joerg return res;
7332 1.1 joerg }
7333 1.1 joerg /****************************************************************************
7334 1.1 joerg REMARKS:
7335 1.1 joerg Implements the SHRD instruction and side effects.
7336 1.1 joerg ****************************************************************************/
7337 1.1 joerg static uint16_t
7338 1.1 joerg shrd_word(struct X86EMU *emu, uint16_t d, uint16_t fill, uint8_t s)
7339 1.1 joerg {
7340 1.1 joerg unsigned int cnt, res, cf;
7341 1.1 joerg
7342 1.1 joerg if (s < 16) {
7343 1.1 joerg cnt = s % 16;
7344 1.1 joerg if (cnt > 0) {
7345 1.1 joerg cf = d & (1 << (cnt - 1));
7346 1.1 joerg res = (d >> cnt) | (fill << (16 - cnt));
7347 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7348 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7349 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7350 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7351 1.1 joerg } else {
7352 1.1 joerg res = d;
7353 1.1 joerg }
7354 1.1 joerg
7355 1.1 joerg if (cnt == 1) {
7356 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
7357 1.1 joerg } else {
7358 1.1 joerg CLEAR_FLAG(F_OF);
7359 1.1 joerg }
7360 1.1 joerg } else {
7361 1.1 joerg res = 0;
7362 1.1 joerg CLEAR_FLAG(F_CF);
7363 1.1 joerg CLEAR_FLAG(F_OF);
7364 1.1 joerg SET_FLAG(F_ZF);
7365 1.1 joerg CLEAR_FLAG(F_SF);
7366 1.1 joerg CLEAR_FLAG(F_PF);
7367 1.1 joerg }
7368 1.1 joerg return (uint16_t) res;
7369 1.1 joerg }
7370 1.1 joerg /****************************************************************************
7371 1.1 joerg REMARKS:
7372 1.1 joerg Implements the SHRD instruction and side effects.
7373 1.1 joerg ****************************************************************************/
7374 1.1 joerg static uint32_t
7375 1.1 joerg shrd_long(struct X86EMU *emu, uint32_t d, uint32_t fill, uint8_t s)
7376 1.1 joerg {
7377 1.1 joerg unsigned int cnt, res, cf;
7378 1.1 joerg
7379 1.1 joerg if (s < 32) {
7380 1.1 joerg cnt = s % 32;
7381 1.1 joerg if (cnt > 0) {
7382 1.1 joerg cf = d & (1 << (cnt - 1));
7383 1.1 joerg res = (d >> cnt) | (fill << (32 - cnt));
7384 1.1 joerg CONDITIONAL_SET_FLAG(cf, F_CF);
7385 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7386 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7387 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7388 1.1 joerg } else {
7389 1.1 joerg res = d;
7390 1.1 joerg }
7391 1.1 joerg if (cnt == 1) {
7392 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
7393 1.1 joerg } else {
7394 1.1 joerg CLEAR_FLAG(F_OF);
7395 1.1 joerg }
7396 1.1 joerg } else {
7397 1.1 joerg res = 0;
7398 1.1 joerg CLEAR_FLAG(F_CF);
7399 1.1 joerg CLEAR_FLAG(F_OF);
7400 1.1 joerg SET_FLAG(F_ZF);
7401 1.1 joerg CLEAR_FLAG(F_SF);
7402 1.1 joerg CLEAR_FLAG(F_PF);
7403 1.1 joerg }
7404 1.1 joerg return res;
7405 1.1 joerg }
7406 1.1 joerg /****************************************************************************
7407 1.1 joerg REMARKS:
7408 1.1 joerg Implements the SBB instruction and side effects.
7409 1.1 joerg ****************************************************************************/
7410 1.1 joerg static uint8_t
7411 1.1 joerg sbb_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7412 1.1 joerg {
7413 1.1 joerg uint32_t res; /* all operands in native machine order */
7414 1.1 joerg uint32_t bc;
7415 1.1 joerg
7416 1.1 joerg if (ACCESS_FLAG(F_CF))
7417 1.1 joerg res = d - s - 1;
7418 1.1 joerg else
7419 1.1 joerg res = d - s;
7420 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7421 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
7422 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7423 1.1 joerg
7424 1.1 joerg /* calculate the borrow chain. See note at top */
7425 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7426 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
7427 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
7428 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7429 1.1 joerg return (uint8_t) res;
7430 1.1 joerg }
7431 1.1 joerg /****************************************************************************
7432 1.1 joerg REMARKS:
7433 1.1 joerg Implements the SBB instruction and side effects.
7434 1.1 joerg ****************************************************************************/
7435 1.1 joerg static uint16_t
7436 1.1 joerg sbb_word(struct X86EMU *emu, uint16_t d, uint16_t s)
7437 1.1 joerg {
7438 1.1 joerg uint32_t res; /* all operands in native machine order */
7439 1.1 joerg uint32_t bc;
7440 1.1 joerg
7441 1.1 joerg if (ACCESS_FLAG(F_CF))
7442 1.1 joerg res = d - s - 1;
7443 1.1 joerg else
7444 1.1 joerg res = d - s;
7445 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7446 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7447 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7448 1.1 joerg
7449 1.1 joerg /* calculate the borrow chain. See note at top */
7450 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7451 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
7452 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
7453 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7454 1.1 joerg return (uint16_t) res;
7455 1.1 joerg }
7456 1.1 joerg /****************************************************************************
7457 1.1 joerg REMARKS:
7458 1.1 joerg Implements the SBB instruction and side effects.
7459 1.1 joerg ****************************************************************************/
7460 1.1 joerg static uint32_t
7461 1.1 joerg sbb_long(struct X86EMU *emu, uint32_t d, uint32_t s)
7462 1.1 joerg {
7463 1.1 joerg uint32_t res; /* all operands in native machine order */
7464 1.1 joerg uint32_t bc;
7465 1.1 joerg
7466 1.1 joerg if (ACCESS_FLAG(F_CF))
7467 1.1 joerg res = d - s - 1;
7468 1.1 joerg else
7469 1.1 joerg res = d - s;
7470 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7471 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7472 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7473 1.1 joerg
7474 1.1 joerg /* calculate the borrow chain. See note at top */
7475 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7476 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
7477 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
7478 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7479 1.1 joerg return res;
7480 1.1 joerg }
7481 1.1 joerg /****************************************************************************
7482 1.1 joerg REMARKS:
7483 1.1 joerg Implements the SUB instruction and side effects.
7484 1.1 joerg ****************************************************************************/
7485 1.1 joerg static uint8_t
7486 1.1 joerg sub_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7487 1.1 joerg {
7488 1.1 joerg uint32_t res; /* all operands in native machine order */
7489 1.1 joerg uint32_t bc;
7490 1.1 joerg
7491 1.1 joerg res = d - s;
7492 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7493 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
7494 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7495 1.1 joerg
7496 1.1 joerg /* calculate the borrow chain. See note at top */
7497 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7498 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
7499 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
7500 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7501 1.1 joerg return (uint8_t) res;
7502 1.1 joerg }
7503 1.1 joerg /****************************************************************************
7504 1.1 joerg REMARKS:
7505 1.1 joerg Implements the SUB instruction and side effects.
7506 1.1 joerg ****************************************************************************/
7507 1.1 joerg static uint16_t
7508 1.1 joerg sub_word(struct X86EMU *emu, uint16_t d, uint16_t s)
7509 1.1 joerg {
7510 1.1 joerg uint32_t res; /* all operands in native machine order */
7511 1.1 joerg uint32_t bc;
7512 1.1 joerg
7513 1.1 joerg res = d - s;
7514 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7515 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
7516 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7517 1.1 joerg
7518 1.1 joerg /* calculate the borrow chain. See note at top */
7519 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7520 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
7521 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
7522 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7523 1.1 joerg return (uint16_t) res;
7524 1.1 joerg }
7525 1.1 joerg /****************************************************************************
7526 1.1 joerg REMARKS:
7527 1.1 joerg Implements the SUB instruction and side effects.
7528 1.1 joerg ****************************************************************************/
7529 1.1 joerg static uint32_t
7530 1.1 joerg sub_long(struct X86EMU *emu, uint32_t d, uint32_t s)
7531 1.1 joerg {
7532 1.1 joerg uint32_t res; /* all operands in native machine order */
7533 1.1 joerg uint32_t bc;
7534 1.1 joerg
7535 1.1 joerg res = d - s;
7536 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7537 1.1 joerg CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
7538 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7539 1.1 joerg
7540 1.1 joerg /* calculate the borrow chain. See note at top */
7541 1.1 joerg bc = (res & (~d | s)) | (~d & s);
7542 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
7543 1.1 joerg CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
7544 1.1 joerg CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
7545 1.1 joerg return res;
7546 1.1 joerg }
7547 1.1 joerg /****************************************************************************
7548 1.1 joerg REMARKS:
7549 1.1 joerg Implements the TEST instruction and side effects.
7550 1.1 joerg ****************************************************************************/
7551 1.1 joerg static void
7552 1.1 joerg test_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7553 1.1 joerg {
7554 1.1 joerg uint32_t res; /* all operands in native machine order */
7555 1.1 joerg
7556 1.1 joerg res = d & s;
7557 1.1 joerg
7558 1.1 joerg CLEAR_FLAG(F_OF);
7559 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7560 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7561 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7562 1.1 joerg /* AF == dont care */
7563 1.1 joerg CLEAR_FLAG(F_CF);
7564 1.1 joerg }
7565 1.1 joerg /****************************************************************************
7566 1.1 joerg REMARKS:
7567 1.1 joerg Implements the TEST instruction and side effects.
7568 1.1 joerg ****************************************************************************/
7569 1.1 joerg static void
7570 1.1 joerg test_word(struct X86EMU *emu, uint16_t d, uint16_t s)
7571 1.1 joerg {
7572 1.1 joerg uint32_t res; /* all operands in native machine order */
7573 1.1 joerg
7574 1.1 joerg res = d & s;
7575 1.1 joerg
7576 1.1 joerg CLEAR_FLAG(F_OF);
7577 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7578 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7579 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7580 1.1 joerg /* AF == dont care */
7581 1.1 joerg CLEAR_FLAG(F_CF);
7582 1.1 joerg }
7583 1.1 joerg /****************************************************************************
7584 1.1 joerg REMARKS:
7585 1.1 joerg Implements the TEST instruction and side effects.
7586 1.1 joerg ****************************************************************************/
7587 1.1 joerg static void
7588 1.1 joerg test_long(struct X86EMU *emu, uint32_t d, uint32_t s)
7589 1.1 joerg {
7590 1.1 joerg uint32_t res; /* all operands in native machine order */
7591 1.1 joerg
7592 1.1 joerg res = d & s;
7593 1.1 joerg
7594 1.1 joerg CLEAR_FLAG(F_OF);
7595 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7596 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7597 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7598 1.1 joerg /* AF == dont care */
7599 1.1 joerg CLEAR_FLAG(F_CF);
7600 1.1 joerg }
7601 1.1 joerg /****************************************************************************
7602 1.1 joerg REMARKS:
7603 1.1 joerg Implements the XOR instruction and side effects.
7604 1.1 joerg ****************************************************************************/
7605 1.1 joerg static uint8_t
7606 1.1 joerg xor_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
7607 1.1 joerg {
7608 1.1 joerg uint8_t res; /* all operands in native machine order */
7609 1.1 joerg
7610 1.1 joerg res = d ^ s;
7611 1.1 joerg CLEAR_FLAG(F_OF);
7612 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
7613 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7614 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
7615 1.1 joerg CLEAR_FLAG(F_CF);
7616 1.1 joerg CLEAR_FLAG(F_AF);
7617 1.1 joerg return res;
7618 1.1 joerg }
7619 1.1 joerg /****************************************************************************
7620 1.1 joerg REMARKS:
7621 1.1 joerg Implements the XOR instruction and side effects.
7622 1.1 joerg ****************************************************************************/
7623 1.1 joerg static uint16_t
7624 1.1 joerg xor_word(struct X86EMU *emu, uint16_t d, uint16_t s)
7625 1.1 joerg {
7626 1.1 joerg uint16_t res; /* all operands in native machine order */
7627 1.1 joerg
7628 1.1 joerg res = d ^ s;
7629 1.1 joerg CLEAR_FLAG(F_OF);
7630 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
7631 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7632 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7633 1.1 joerg CLEAR_FLAG(F_CF);
7634 1.1 joerg CLEAR_FLAG(F_AF);
7635 1.1 joerg return res;
7636 1.1 joerg }
7637 1.1 joerg /****************************************************************************
7638 1.1 joerg REMARKS:
7639 1.1 joerg Implements the XOR instruction and side effects.
7640 1.1 joerg ****************************************************************************/
7641 1.1 joerg static uint32_t
7642 1.1 joerg xor_long(struct X86EMU *emu, uint32_t d, uint32_t s)
7643 1.1 joerg {
7644 1.1 joerg uint32_t res; /* all operands in native machine order */
7645 1.1 joerg
7646 1.1 joerg res = d ^ s;
7647 1.1 joerg CLEAR_FLAG(F_OF);
7648 1.1 joerg CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
7649 1.1 joerg CONDITIONAL_SET_FLAG(res == 0, F_ZF);
7650 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
7651 1.1 joerg CLEAR_FLAG(F_CF);
7652 1.1 joerg CLEAR_FLAG(F_AF);
7653 1.1 joerg return res;
7654 1.1 joerg }
7655 1.1 joerg /****************************************************************************
7656 1.1 joerg REMARKS:
7657 1.1 joerg Implements the IMUL instruction and side effects.
7658 1.1 joerg ****************************************************************************/
7659 1.1 joerg static void
7660 1.1 joerg imul_byte(struct X86EMU *emu, uint8_t s)
7661 1.1 joerg {
7662 1.1 joerg int16_t res = (int16_t) ((int8_t) emu->x86.R_AL * (int8_t) s);
7663 1.1 joerg
7664 1.1 joerg emu->x86.R_AX = res;
7665 1.1 joerg if (((emu->x86.R_AL & 0x80) == 0 && emu->x86.R_AH == 0x00) ||
7666 1.1 joerg ((emu->x86.R_AL & 0x80) != 0 && emu->x86.R_AH == 0xFF)) {
7667 1.1 joerg CLEAR_FLAG(F_CF);
7668 1.1 joerg CLEAR_FLAG(F_OF);
7669 1.1 joerg } else {
7670 1.1 joerg SET_FLAG(F_CF);
7671 1.1 joerg SET_FLAG(F_OF);
7672 1.1 joerg }
7673 1.1 joerg }
7674 1.1 joerg /****************************************************************************
7675 1.1 joerg REMARKS:
7676 1.1 joerg Implements the IMUL instruction and side effects.
7677 1.1 joerg ****************************************************************************/
7678 1.1 joerg static void
7679 1.1 joerg imul_word(struct X86EMU *emu, uint16_t s)
7680 1.1 joerg {
7681 1.1 joerg int32_t res = (int16_t) emu->x86.R_AX * (int16_t) s;
7682 1.1 joerg
7683 1.1 joerg emu->x86.R_AX = (uint16_t) res;
7684 1.1 joerg emu->x86.R_DX = (uint16_t) (res >> 16);
7685 1.1 joerg if (((emu->x86.R_AX & 0x8000) == 0 && emu->x86.R_DX == 0x00) ||
7686 1.1 joerg ((emu->x86.R_AX & 0x8000) != 0 && emu->x86.R_DX == 0xFF)) {
7687 1.1 joerg CLEAR_FLAG(F_CF);
7688 1.1 joerg CLEAR_FLAG(F_OF);
7689 1.1 joerg } else {
7690 1.1 joerg SET_FLAG(F_CF);
7691 1.1 joerg SET_FLAG(F_OF);
7692 1.1 joerg }
7693 1.1 joerg }
7694 1.1 joerg /****************************************************************************
7695 1.1 joerg REMARKS:
7696 1.1 joerg Implements the IMUL instruction and side effects.
7697 1.1 joerg ****************************************************************************/
7698 1.1 joerg static void
7699 1.1 joerg imul_long(struct X86EMU *emu, uint32_t s)
7700 1.1 joerg {
7701 1.1 joerg int64_t res;
7702 1.1 joerg
7703 1.1 joerg res = (int64_t)(int32_t)emu->x86.R_EAX * (int32_t)s;
7704 1.1 joerg emu->x86.R_EAX = (uint32_t)res;
7705 1.1 joerg emu->x86.R_EDX = ((uint64_t)res) >> 32;
7706 1.1 joerg if (((emu->x86.R_EAX & 0x80000000) == 0 && emu->x86.R_EDX == 0x00) ||
7707 1.1 joerg ((emu->x86.R_EAX & 0x80000000) != 0 && emu->x86.R_EDX == 0xFF)) {
7708 1.1 joerg CLEAR_FLAG(F_CF);
7709 1.1 joerg CLEAR_FLAG(F_OF);
7710 1.1 joerg } else {
7711 1.1 joerg SET_FLAG(F_CF);
7712 1.1 joerg SET_FLAG(F_OF);
7713 1.1 joerg }
7714 1.1 joerg }
7715 1.1 joerg /****************************************************************************
7716 1.1 joerg REMARKS:
7717 1.1 joerg Implements the MUL instruction and side effects.
7718 1.1 joerg ****************************************************************************/
7719 1.1 joerg static void
7720 1.1 joerg mul_byte(struct X86EMU *emu, uint8_t s)
7721 1.1 joerg {
7722 1.1 joerg uint16_t res = (uint16_t) (emu->x86.R_AL * s);
7723 1.1 joerg
7724 1.1 joerg emu->x86.R_AX = res;
7725 1.1 joerg if (emu->x86.R_AH == 0) {
7726 1.1 joerg CLEAR_FLAG(F_CF);
7727 1.1 joerg CLEAR_FLAG(F_OF);
7728 1.1 joerg } else {
7729 1.1 joerg SET_FLAG(F_CF);
7730 1.1 joerg SET_FLAG(F_OF);
7731 1.1 joerg }
7732 1.1 joerg }
7733 1.1 joerg /****************************************************************************
7734 1.1 joerg REMARKS:
7735 1.1 joerg Implements the MUL instruction and side effects.
7736 1.1 joerg ****************************************************************************/
7737 1.1 joerg static void
7738 1.1 joerg mul_word(struct X86EMU *emu, uint16_t s)
7739 1.1 joerg {
7740 1.1 joerg uint32_t res = emu->x86.R_AX * s;
7741 1.1 joerg
7742 1.1 joerg emu->x86.R_AX = (uint16_t) res;
7743 1.1 joerg emu->x86.R_DX = (uint16_t) (res >> 16);
7744 1.1 joerg if (emu->x86.R_DX == 0) {
7745 1.1 joerg CLEAR_FLAG(F_CF);
7746 1.1 joerg CLEAR_FLAG(F_OF);
7747 1.1 joerg } else {
7748 1.1 joerg SET_FLAG(F_CF);
7749 1.1 joerg SET_FLAG(F_OF);
7750 1.1 joerg }
7751 1.1 joerg }
7752 1.1 joerg /****************************************************************************
7753 1.1 joerg REMARKS:
7754 1.1 joerg Implements the MUL instruction and side effects.
7755 1.1 joerg ****************************************************************************/
7756 1.1 joerg static void
7757 1.1 joerg mul_long(struct X86EMU *emu, uint32_t s)
7758 1.1 joerg {
7759 1.1 joerg uint64_t res = (uint64_t) emu->x86.R_EAX * s;
7760 1.1 joerg
7761 1.1 joerg emu->x86.R_EAX = (uint32_t) res;
7762 1.1 joerg emu->x86.R_EDX = (uint32_t) (res >> 32);
7763 1.1 joerg
7764 1.1 joerg if (emu->x86.R_EDX == 0) {
7765 1.1 joerg CLEAR_FLAG(F_CF);
7766 1.1 joerg CLEAR_FLAG(F_OF);
7767 1.1 joerg } else {
7768 1.1 joerg SET_FLAG(F_CF);
7769 1.1 joerg SET_FLAG(F_OF);
7770 1.1 joerg }
7771 1.1 joerg }
7772 1.1 joerg /****************************************************************************
7773 1.1 joerg REMARKS:
7774 1.1 joerg Implements the IDIV instruction and side effects.
7775 1.1 joerg ****************************************************************************/
7776 1.1 joerg static void
7777 1.1 joerg idiv_byte(struct X86EMU *emu, uint8_t s)
7778 1.1 joerg {
7779 1.1 joerg int32_t dvd, div, mod;
7780 1.1 joerg
7781 1.1 joerg dvd = (int16_t) emu->x86.R_AX;
7782 1.1 joerg if (s == 0) {
7783 1.5 joerg x86emu_intr_raise(emu, 8);
7784 1.1 joerg return;
7785 1.1 joerg }
7786 1.1 joerg div = dvd / (int8_t) s;
7787 1.1 joerg mod = dvd % (int8_t) s;
7788 1.1 joerg if (div > 0x7f || div < -0x7f) {
7789 1.5 joerg x86emu_intr_raise(emu, 8);
7790 1.1 joerg return;
7791 1.1 joerg }
7792 1.1 joerg emu->x86.R_AL = (int8_t) div;
7793 1.1 joerg emu->x86.R_AH = (int8_t) mod;
7794 1.1 joerg }
7795 1.1 joerg /****************************************************************************
7796 1.1 joerg REMARKS:
7797 1.1 joerg Implements the IDIV instruction and side effects.
7798 1.1 joerg ****************************************************************************/
7799 1.1 joerg static void
7800 1.1 joerg idiv_word(struct X86EMU *emu, uint16_t s)
7801 1.1 joerg {
7802 1.1 joerg int32_t dvd, div, mod;
7803 1.1 joerg
7804 1.1 joerg dvd = (((int32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
7805 1.1 joerg if (s == 0) {
7806 1.5 joerg x86emu_intr_raise(emu, 8);
7807 1.1 joerg return;
7808 1.1 joerg }
7809 1.1 joerg div = dvd / (int16_t) s;
7810 1.1 joerg mod = dvd % (int16_t) s;
7811 1.1 joerg if (div > 0x7fff || div < -0x7fff) {
7812 1.5 joerg x86emu_intr_raise(emu, 8);
7813 1.1 joerg return;
7814 1.1 joerg }
7815 1.1 joerg CLEAR_FLAG(F_CF);
7816 1.1 joerg CLEAR_FLAG(F_SF);
7817 1.1 joerg CONDITIONAL_SET_FLAG(div == 0, F_ZF);
7818 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
7819 1.1 joerg
7820 1.1 joerg emu->x86.R_AX = (uint16_t) div;
7821 1.1 joerg emu->x86.R_DX = (uint16_t) mod;
7822 1.1 joerg }
7823 1.1 joerg /****************************************************************************
7824 1.1 joerg REMARKS:
7825 1.1 joerg Implements the IDIV instruction and side effects.
7826 1.1 joerg ****************************************************************************/
7827 1.1 joerg static void
7828 1.1 joerg idiv_long(struct X86EMU *emu, uint32_t s)
7829 1.1 joerg {
7830 1.1 joerg int64_t dvd, div, mod;
7831 1.1 joerg
7832 1.1 joerg dvd = (((int64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
7833 1.1 joerg if (s == 0) {
7834 1.5 joerg x86emu_intr_raise(emu, 8);
7835 1.1 joerg return;
7836 1.1 joerg }
7837 1.1 joerg div = dvd / (int32_t) s;
7838 1.1 joerg mod = dvd % (int32_t) s;
7839 1.1 joerg if (div > 0x7fffffff || div < -0x7fffffff) {
7840 1.5 joerg x86emu_intr_raise(emu, 8);
7841 1.1 joerg return;
7842 1.1 joerg }
7843 1.1 joerg CLEAR_FLAG(F_CF);
7844 1.1 joerg CLEAR_FLAG(F_AF);
7845 1.1 joerg CLEAR_FLAG(F_SF);
7846 1.1 joerg SET_FLAG(F_ZF);
7847 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
7848 1.1 joerg
7849 1.1 joerg emu->x86.R_EAX = (uint32_t) div;
7850 1.1 joerg emu->x86.R_EDX = (uint32_t) mod;
7851 1.1 joerg }
7852 1.1 joerg /****************************************************************************
7853 1.1 joerg REMARKS:
7854 1.1 joerg Implements the DIV instruction and side effects.
7855 1.1 joerg ****************************************************************************/
7856 1.1 joerg static void
7857 1.1 joerg div_byte(struct X86EMU *emu, uint8_t s)
7858 1.1 joerg {
7859 1.1 joerg uint32_t dvd, div, mod;
7860 1.1 joerg
7861 1.1 joerg dvd = emu->x86.R_AX;
7862 1.1 joerg if (s == 0) {
7863 1.5 joerg x86emu_intr_raise(emu, 8);
7864 1.1 joerg return;
7865 1.1 joerg }
7866 1.1 joerg div = dvd / (uint8_t) s;
7867 1.1 joerg mod = dvd % (uint8_t) s;
7868 1.1 joerg if (div > 0xff) {
7869 1.5 joerg x86emu_intr_raise(emu, 8);
7870 1.1 joerg return;
7871 1.1 joerg }
7872 1.1 joerg emu->x86.R_AL = (uint8_t) div;
7873 1.1 joerg emu->x86.R_AH = (uint8_t) mod;
7874 1.1 joerg }
7875 1.1 joerg /****************************************************************************
7876 1.1 joerg REMARKS:
7877 1.1 joerg Implements the DIV instruction and side effects.
7878 1.1 joerg ****************************************************************************/
7879 1.1 joerg static void
7880 1.1 joerg div_word(struct X86EMU *emu, uint16_t s)
7881 1.1 joerg {
7882 1.1 joerg uint32_t dvd, div, mod;
7883 1.1 joerg
7884 1.1 joerg dvd = (((uint32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
7885 1.1 joerg if (s == 0) {
7886 1.5 joerg x86emu_intr_raise(emu, 8);
7887 1.1 joerg return;
7888 1.1 joerg }
7889 1.1 joerg div = dvd / (uint16_t) s;
7890 1.1 joerg mod = dvd % (uint16_t) s;
7891 1.1 joerg if (div > 0xffff) {
7892 1.5 joerg x86emu_intr_raise(emu, 8);
7893 1.1 joerg return;
7894 1.1 joerg }
7895 1.1 joerg CLEAR_FLAG(F_CF);
7896 1.1 joerg CLEAR_FLAG(F_SF);
7897 1.1 joerg CONDITIONAL_SET_FLAG(div == 0, F_ZF);
7898 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
7899 1.1 joerg
7900 1.1 joerg emu->x86.R_AX = (uint16_t) div;
7901 1.1 joerg emu->x86.R_DX = (uint16_t) mod;
7902 1.1 joerg }
7903 1.1 joerg /****************************************************************************
7904 1.1 joerg REMARKS:
7905 1.1 joerg Implements the DIV instruction and side effects.
7906 1.1 joerg ****************************************************************************/
7907 1.1 joerg static void
7908 1.1 joerg div_long(struct X86EMU *emu, uint32_t s)
7909 1.1 joerg {
7910 1.1 joerg uint64_t dvd, div, mod;
7911 1.1 joerg
7912 1.1 joerg dvd = (((uint64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
7913 1.1 joerg if (s == 0) {
7914 1.5 joerg x86emu_intr_raise(emu, 8);
7915 1.1 joerg return;
7916 1.1 joerg }
7917 1.1 joerg div = dvd / (uint32_t) s;
7918 1.1 joerg mod = dvd % (uint32_t) s;
7919 1.1 joerg if (div > 0xffffffff) {
7920 1.5 joerg x86emu_intr_raise(emu, 8);
7921 1.1 joerg return;
7922 1.1 joerg }
7923 1.1 joerg CLEAR_FLAG(F_CF);
7924 1.1 joerg CLEAR_FLAG(F_AF);
7925 1.1 joerg CLEAR_FLAG(F_SF);
7926 1.1 joerg SET_FLAG(F_ZF);
7927 1.1 joerg CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
7928 1.1 joerg
7929 1.1 joerg emu->x86.R_EAX = (uint32_t) div;
7930 1.1 joerg emu->x86.R_EDX = (uint32_t) mod;
7931 1.1 joerg }
7932 1.1 joerg /****************************************************************************
7933 1.1 joerg REMARKS:
7934 1.1 joerg Implements the IN string instruction and side effects.
7935 1.1 joerg ****************************************************************************/
7936 1.1 joerg static void
7937 1.1 joerg ins(struct X86EMU *emu, int size)
7938 1.1 joerg {
7939 1.1 joerg int inc = size;
7940 1.1 joerg
7941 1.1 joerg if (ACCESS_FLAG(F_DF)) {
7942 1.1 joerg inc = -size;
7943 1.1 joerg }
7944 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7945 1.1 joerg /* dont care whether REPE or REPNE */
7946 1.1 joerg /* in until CX is ZERO. */
7947 1.1 joerg uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
7948 1.1 joerg emu->x86.R_ECX : emu->x86.R_CX);
7949 1.1 joerg switch (size) {
7950 1.1 joerg case 1:
7951 1.1 joerg while (count--) {
7952 1.1 joerg store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
7953 1.1 joerg (*emu->emu_inb) (emu, emu->x86.R_DX));
7954 1.1 joerg emu->x86.R_DI += inc;
7955 1.1 joerg }
7956 1.1 joerg break;
7957 1.1 joerg
7958 1.1 joerg case 2:
7959 1.1 joerg while (count--) {
7960 1.1 joerg store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
7961 1.1 joerg (*emu->emu_inw) (emu, emu->x86.R_DX));
7962 1.1 joerg emu->x86.R_DI += inc;
7963 1.1 joerg }
7964 1.1 joerg break;
7965 1.1 joerg case 4:
7966 1.1 joerg while (count--) {
7967 1.1 joerg store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
7968 1.1 joerg (*emu->emu_inl) (emu, emu->x86.R_DX));
7969 1.1 joerg emu->x86.R_DI += inc;
7970 1.1 joerg break;
7971 1.1 joerg }
7972 1.1 joerg }
7973 1.1 joerg emu->x86.R_CX = 0;
7974 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
7975 1.1 joerg emu->x86.R_ECX = 0;
7976 1.1 joerg }
7977 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7978 1.1 joerg } else {
7979 1.1 joerg switch (size) {
7980 1.1 joerg case 1:
7981 1.1 joerg store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
7982 1.1 joerg (*emu->emu_inb) (emu, emu->x86.R_DX));
7983 1.1 joerg break;
7984 1.1 joerg case 2:
7985 1.1 joerg store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
7986 1.1 joerg (*emu->emu_inw) (emu, emu->x86.R_DX));
7987 1.1 joerg break;
7988 1.1 joerg case 4:
7989 1.1 joerg store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
7990 1.1 joerg (*emu->emu_inl) (emu, emu->x86.R_DX));
7991 1.1 joerg break;
7992 1.1 joerg }
7993 1.1 joerg emu->x86.R_DI += inc;
7994 1.1 joerg }
7995 1.1 joerg }
7996 1.1 joerg /****************************************************************************
7997 1.1 joerg REMARKS:
7998 1.1 joerg Implements the OUT string instruction and side effects.
7999 1.1 joerg ****************************************************************************/
8000 1.1 joerg static void
8001 1.1 joerg outs(struct X86EMU *emu, int size)
8002 1.1 joerg {
8003 1.1 joerg int inc = size;
8004 1.1 joerg
8005 1.1 joerg if (ACCESS_FLAG(F_DF)) {
8006 1.1 joerg inc = -size;
8007 1.1 joerg }
8008 1.1 joerg if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8009 1.1 joerg /* dont care whether REPE or REPNE */
8010 1.1 joerg /* out until CX is ZERO. */
8011 1.1 joerg uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
8012 1.1 joerg emu->x86.R_ECX : emu->x86.R_CX);
8013 1.1 joerg switch (size) {
8014 1.1 joerg case 1:
8015 1.1 joerg while (count--) {
8016 1.1 joerg (*emu->emu_outb) (emu, emu->x86.R_DX,
8017 1.1 joerg fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
8018 1.1 joerg emu->x86.R_SI += inc;
8019 1.1 joerg }
8020 1.1 joerg break;
8021 1.1 joerg
8022 1.1 joerg case 2:
8023 1.1 joerg while (count--) {
8024 1.1 joerg (*emu->emu_outw) (emu, emu->x86.R_DX,
8025 1.1 joerg fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
8026 1.1 joerg emu->x86.R_SI += inc;
8027 1.1 joerg }
8028 1.1 joerg break;
8029 1.1 joerg case 4:
8030 1.1 joerg while (count--) {
8031 1.1 joerg (*emu->emu_outl) (emu, emu->x86.R_DX,
8032 1.1 joerg fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
8033 1.1 joerg emu->x86.R_SI += inc;
8034 1.1 joerg break;
8035 1.1 joerg }
8036 1.1 joerg }
8037 1.1 joerg emu->x86.R_CX = 0;
8038 1.1 joerg if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
8039 1.1 joerg emu->x86.R_ECX = 0;
8040 1.1 joerg }
8041 1.1 joerg emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8042 1.1 joerg } else {
8043 1.1 joerg switch (size) {
8044 1.1 joerg case 1:
8045 1.1 joerg (*emu->emu_outb) (emu, emu->x86.R_DX,
8046 1.1 joerg fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
8047 1.1 joerg break;
8048 1.1 joerg case 2:
8049 1.1 joerg (*emu->emu_outw) (emu, emu->x86.R_DX,
8050 1.1 joerg fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
8051 1.1 joerg break;
8052 1.1 joerg case 4:
8053 1.1 joerg (*emu->emu_outl) (emu, emu->x86.R_DX,
8054 1.1 joerg fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
8055 1.1 joerg break;
8056 1.1 joerg }
8057 1.1 joerg emu->x86.R_SI += inc;
8058 1.1 joerg }
8059 1.1 joerg }
8060 1.1 joerg /****************************************************************************
8061 1.1 joerg REMARKS:
8062 1.1 joerg Pushes a word onto the stack.
8063 1.1 joerg
8064 1.1 joerg NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
8065 1.1 joerg ****************************************************************************/
8066 1.1 joerg static void
8067 1.1 joerg push_word(struct X86EMU *emu, uint16_t w)
8068 1.1 joerg {
8069 1.1 joerg emu->x86.R_SP -= 2;
8070 1.1 joerg store_word(emu, emu->x86.R_SS, emu->x86.R_SP, w);
8071 1.1 joerg }
8072 1.1 joerg /****************************************************************************
8073 1.1 joerg REMARKS:
8074 1.1 joerg Pushes a long onto the stack.
8075 1.1 joerg
8076 1.1 joerg NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
8077 1.1 joerg ****************************************************************************/
8078 1.1 joerg static void
8079 1.1 joerg push_long(struct X86EMU *emu, uint32_t w)
8080 1.1 joerg {
8081 1.1 joerg emu->x86.R_SP -= 4;
8082 1.1 joerg store_long(emu, emu->x86.R_SS, emu->x86.R_SP, w);
8083 1.1 joerg }
8084 1.1 joerg /****************************************************************************
8085 1.1 joerg REMARKS:
8086 1.1 joerg Pops a word from the stack.
8087 1.1 joerg
8088 1.1 joerg NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
8089 1.1 joerg ****************************************************************************/
8090 1.1 joerg static uint16_t
8091 1.1 joerg pop_word(struct X86EMU *emu)
8092 1.1 joerg {
8093 1.1 joerg uint16_t res;
8094 1.1 joerg
8095 1.1 joerg res = fetch_word(emu, emu->x86.R_SS, emu->x86.R_SP);
8096 1.1 joerg emu->x86.R_SP += 2;
8097 1.1 joerg return res;
8098 1.1 joerg }
8099 1.1 joerg /****************************************************************************
8100 1.1 joerg REMARKS:
8101 1.1 joerg Pops a long from the stack.
8102 1.1 joerg
8103 1.1 joerg NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
8104 1.1 joerg ****************************************************************************/
8105 1.1 joerg static uint32_t
8106 1.1 joerg pop_long(struct X86EMU *emu)
8107 1.1 joerg {
8108 1.1 joerg uint32_t res;
8109 1.1 joerg
8110 1.1 joerg res = fetch_long(emu, emu->x86.R_SS, emu->x86.R_SP);
8111 1.1 joerg emu->x86.R_SP += 4;
8112 1.1 joerg return res;
8113 1.1 joerg }
8114