I386OP(shift_rotate32)1 static UINT32 I386OP(shift_rotate32)(UINT8 modrm, UINT32 value, UINT8 shift)
2 {
3 	UINT32 dst, src;
4 	dst = value;
5 	src = value;
6 
7 	if( shift == 0 ) {
8 		CYCLES_RM(modrm, 3, 7);
9 	} else if( shift == 1 ) {
10 
11 		switch( (modrm >> 3) & 0x7 )
12 		{
13 			case 0:			/* ROL rm32, 1 */
14 				I.CF = (src & 0x80000000) ? 1 : 0;
15 				dst = (src << 1) + I.CF;
16 				I.OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
17 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
18 				break;
19 			case 1:			/* ROR rm32, 1 */
20 				I.CF = (src & 0x1) ? 1 : 0;
21 				dst = (I.CF << 31) | (src >> 1);
22 				I.OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
23 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
24 				break;
25 			case 2:			/* RCL rm32, 1 */
26 				dst = (src << 1) + I.CF;
27 				I.CF = (src & 0x80000000) ? 1 : 0;
28 				I.OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
29 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
30 				break;
31 			case 3:			/* RCR rm32, 1 */
32 				dst = (I.CF << 31) | (src >> 1);
33 				I.CF = src & 0x1;
34 				I.OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
35 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
36 				break;
37 			case 4:			/* SHL/SAL rm32, 1 */
38 			case 6:
39 				dst = src << 1;
40 				I.CF = (src & 0x80000000) ? 1 : 0;
41 				I.OF = (((I.CF << 31) ^ dst) & 0x80000000) ? 1 : 0;
42 				SetSZPF32(dst);
43 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
44 				break;
45 			case 5:			/* SHR rm32, 1 */
46 				dst = src >> 1;
47 				I.CF = src & 0x1;
48 				I.OF = (src & 0x80000000) ? 1 : 0;
49 				SetSZPF32(dst);
50 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
51 				break;
52 			case 7:			/* SAR rm32, 1 */
53 				dst = (INT32)(src) >> 1;
54 				I.CF = src & 0x1;
55 				I.OF = 0;
56 				SetSZPF32(dst);
57 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
58 				break;
59 		}
60 
61 	} else {
62 
63 		switch( (modrm >> 3) & 0x7 )
64 		{
65 			case 0:			/* ROL rm32, i8 */
66 				dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
67 					  ((src & ((UINT32)0xffffffff << (32-shift))) >> (32-shift));
68 				I.CF = (src >> (32-shift)) & 0x1;
69 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
70 				break;
71 			case 1:			/* ROR rm32, i8 */
72 				dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
73 					  ((src & ((UINT32)0xffffffff >> (32-shift))) << (32-shift));
74 				I.CF = (src >> (shift-1)) & 0x1;
75 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
76 				break;
77 			case 2:			/* RCL rm32, i8 */
78 				dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
79 					  ((src & ((UINT32)0xffffffff << (33-shift))) >> (33-shift)) |
80 					  (I.CF << (shift-1));
81 				I.CF = (src >> (32-shift)) & 0x1;
82 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
83 				break;
84 			case 3:			/* RCR rm32, i8 */
85 				dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
86 					  ((src & ((UINT32)0xffffffff >> (32-shift))) << (33-shift)) |
87 					  (I.CF << (32-shift));
88 				I.CF = (src >> (shift-1)) & 0x1;
89 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
90 				break;
91 			case 4:			/* SHL/SAL rm32, i8 */
92 			case 6:
93 				dst = src << shift;
94 				I.CF = (src & (1 << (32-shift))) ? 1 : 0;
95 				SetSZPF32(dst);
96 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
97 				break;
98 			case 5:			/* SHR rm32, i8 */
99 				dst = src >> shift;
100 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
101 				SetSZPF32(dst);
102 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
103 				break;
104 			case 7:			/* SAR rm32, i8 */
105 				dst = (INT32)src >> shift;
106 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
107 				SetSZPF32(dst);
108 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
109 				break;
110 		}
111 
112 	}
113 	return dst;
114 }
115 
116 
117 
I386OP(adc_rm32_r32)118 static void I386OP(adc_rm32_r32)(void)		// Opcode 0x11
119 {
120 	UINT32 src, dst;
121 	UINT8 modrm = FETCH();
122 	if( modrm >= 0xc0 ) {
123 		src = LOAD_REG32(modrm);
124 		dst = LOAD_RM32(modrm);
125 		src = ADD32(src, I.CF);
126 		dst = ADD32(dst, src);
127 		STORE_RM32(modrm, dst);
128 		CYCLES(CYCLES_ALU_REG_REG);
129 	} else {
130 		UINT32 ea = GetEA(modrm);
131 		src = LOAD_REG32(modrm);
132 		dst = READ32(ea);
133 		src = ADD32(src, I.CF);
134 		dst = ADD32(dst, src);
135 		WRITE32(ea, dst);
136 		CYCLES(CYCLES_ALU_REG_MEM);
137 	}
138 }
139 
I386OP(adc_r32_rm32)140 static void I386OP(adc_r32_rm32)(void)		// Opcode 0x13
141 {
142 	UINT32 src, dst;
143 	UINT8 modrm = FETCH();
144 	if( modrm >= 0xc0 ) {
145 		src = LOAD_RM32(modrm);
146 		dst = LOAD_REG32(modrm);
147 		src = ADD32(src, I.CF);
148 		dst = ADD32(dst, src);
149 		STORE_REG32(modrm, dst);
150 		CYCLES(CYCLES_ALU_REG_REG);
151 	} else {
152 		UINT32 ea = GetEA(modrm);
153 		src = READ32(ea);
154 		dst = LOAD_REG32(modrm);
155 		src = ADD32(src, I.CF);
156 		dst = ADD32(dst, src);
157 		STORE_REG32(modrm, dst);
158 		CYCLES(CYCLES_ALU_MEM_REG);
159 	}
160 }
161 
I386OP(adc_eax_i32)162 static void I386OP(adc_eax_i32)(void)		// Opcode 0x15
163 {
164 	UINT32 src, dst;
165 	src = FETCH32();
166 	dst = REG32(EAX);
167 	src = ADD32(src, I.CF);
168 	dst = ADD32(dst, src);
169 	REG32(EAX) = dst;
170 	CYCLES(CYCLES_ALU_IMM_ACC);
171 }
172 
I386OP(add_rm32_r32)173 static void I386OP(add_rm32_r32)(void)		// Opcode 0x01
174 {
175 	UINT32 src, dst;
176 	UINT8 modrm = FETCH();
177 	if( modrm >= 0xc0 ) {
178 		src = LOAD_REG32(modrm);
179 		dst = LOAD_RM32(modrm);
180 		dst = ADD32(dst, src);
181 		STORE_RM32(modrm, dst);
182 		CYCLES(CYCLES_ALU_REG_REG);
183 	} else {
184 		UINT32 ea = GetEA(modrm);
185 		src = LOAD_REG32(modrm);
186 		dst = READ32(ea);
187 		dst = ADD32(dst, src);
188 		WRITE32(ea, dst);
189 		CYCLES(CYCLES_ALU_REG_MEM);
190 	}
191 }
192 
I386OP(add_r32_rm32)193 static void I386OP(add_r32_rm32)(void)		// Opcode 0x03
194 {
195 	UINT32 src, dst;
196 	UINT8 modrm = FETCH();
197 	if( modrm >= 0xc0 ) {
198 		src = LOAD_RM32(modrm);
199 		dst = LOAD_REG32(modrm);
200 		dst = ADD32(dst, src);
201 		STORE_REG32(modrm, dst);
202 		CYCLES(CYCLES_ALU_REG_REG);
203 	} else {
204 		UINT32 ea = GetEA(modrm);
205 		src = READ32(ea);
206 		dst = LOAD_REG32(modrm);
207 		dst = ADD32(dst, src);
208 		STORE_REG32(modrm, dst);
209 		CYCLES(CYCLES_ALU_MEM_REG);
210 	}
211 }
212 
I386OP(add_eax_i32)213 static void I386OP(add_eax_i32)(void)		// Opcode 0x05
214 {
215 	UINT32 src, dst;
216 	src = FETCH32();
217 	dst = REG32(EAX);
218 	dst = ADD32(dst, src);
219 	REG32(EAX) = dst;
220 	CYCLES(CYCLES_ALU_IMM_ACC);
221 }
222 
I386OP(and_rm32_r32)223 static void I386OP(and_rm32_r32)(void)		// Opcode 0x21
224 {
225 	UINT32 src, dst;
226 	UINT8 modrm = FETCH();
227 	if( modrm >= 0xc0 ) {
228 		src = LOAD_REG32(modrm);
229 		dst = LOAD_RM32(modrm);
230 		dst = AND32(dst, src);
231 		STORE_RM32(modrm, dst);
232 		CYCLES(CYCLES_ALU_REG_REG);
233 	} else {
234 		UINT32 ea = GetEA(modrm);
235 		src = LOAD_REG32(modrm);
236 		dst = READ32(ea);
237 		dst = AND32(dst, src);
238 		WRITE32(ea, dst);
239 		CYCLES(CYCLES_ALU_REG_MEM);
240 	}
241 }
242 
I386OP(and_r32_rm32)243 static void I386OP(and_r32_rm32)(void)		// Opcode 0x23
244 {
245 	UINT32 src, dst;
246 	UINT8 modrm = FETCH();
247 	if( modrm >= 0xc0 ) {
248 		src = LOAD_RM32(modrm);
249 		dst = LOAD_REG32(modrm);
250 		dst = AND32(dst, src);
251 		STORE_REG32(modrm, dst);
252 		CYCLES(CYCLES_ALU_REG_REG);
253 	} else {
254 		UINT32 ea = GetEA(modrm);
255 		src = READ32(ea);
256 		dst = LOAD_REG32(modrm);
257 		dst = AND32(dst, src);
258 		STORE_REG32(modrm, dst);
259 		CYCLES(CYCLES_ALU_MEM_REG);
260 	}
261 }
262 
I386OP(and_eax_i32)263 static void I386OP(and_eax_i32)(void)		// Opcode 0x25
264 {
265 	UINT32 src, dst;
266 	src = FETCH32();
267 	dst = REG32(EAX);
268 	dst = AND32(dst, src);
269 	REG32(EAX) = dst;
270 	CYCLES(CYCLES_ALU_IMM_ACC);
271 }
272 
I386OP(bsf_r32_rm32)273 static void I386OP(bsf_r32_rm32)(void)		// Opcode 0x0f bc
274 {
275 	UINT32 src, dst, temp;
276 	UINT8 modrm = FETCH();
277 
278 	if( modrm >= 0xc0 ) {
279 		src = LOAD_RM32(modrm);
280 	} else {
281 		UINT32 ea = GetEA(modrm);
282 		src = READ32(ea);
283 	}
284 
285 	dst = 0;
286 
287 	if( src == 0 ) {
288 		I.ZF = 1;
289 	} else {
290 		I.ZF = 0;
291 		temp = 0;
292 		while( (src & (1 << temp)) == 0 ) {
293 			temp++;
294 			dst = temp;
295 			CYCLES(CYCLES_BSF);
296 		}
297 	}
298 	CYCLES(CYCLES_BSF_BASE);
299 	STORE_REG32(modrm, dst);
300 }
301 
I386OP(bsr_r32_rm32)302 static void I386OP(bsr_r32_rm32)(void)		// Opcode 0x0f bd
303 {
304 	UINT32 src, dst, temp;
305 	UINT8 modrm = FETCH();
306 
307 	if( modrm >= 0xc0 ) {
308 		src = LOAD_RM32(modrm);
309 	} else {
310 		UINT32 ea = GetEA(modrm);
311 		src = READ32(ea);
312 	}
313 
314 	dst = 0;
315 
316 	if( src == 0 ) {
317 		I.ZF = 1;
318 	} else {
319 		I.ZF = 0;
320 		temp = 31;
321 		while( (src & (1 << temp)) == 0 ) {
322 			temp--;
323 			dst = temp;
324 			CYCLES(CYCLES_BSR);
325 		}
326 	}
327 	CYCLES(CYCLES_BSR_BASE);
328 	STORE_REG32(modrm, dst);
329 }
330 
I386OP(bt_rm32_r32)331 static void I386OP(bt_rm32_r32)(void)		// Opcode 0x0f a3
332 {
333 	UINT8 modrm = FETCH();
334 	if( modrm >= 0xc0 ) {
335 		UINT32 dst = LOAD_RM32(modrm);
336 		UINT32 bit = LOAD_REG32(modrm);
337 
338 		if( dst & (1 << bit) )
339 			I.CF = 1;
340 		else
341 			I.CF = 0;
342 
343 		CYCLES(CYCLES_BT_REG_REG);
344 	} else {
345 		UINT32 ea = GetEA(modrm);
346 		UINT32 dst = READ32(ea);
347 		UINT32 bit = LOAD_REG32(modrm);
348 
349 		if( dst & (1 << bit) )
350 			I.CF = 1;
351 		else
352 			I.CF = 0;
353 
354 		CYCLES(CYCLES_BT_REG_MEM);
355 	}
356 }
357 
I386OP(btc_rm32_r32)358 static void I386OP(btc_rm32_r32)(void)		// Opcode 0x0f bb
359 {
360 	UINT8 modrm = FETCH();
361 	if( modrm >= 0xc0 ) {
362 		UINT32 dst = LOAD_RM32(modrm);
363 		UINT32 bit = LOAD_REG32(modrm);
364 
365 		if( dst & (1 << bit) )
366 			I.CF = 1;
367 		else
368 			I.CF = 0;
369 		dst ^= (1 << bit);
370 
371 		STORE_RM32(modrm, dst);
372 		CYCLES(CYCLES_BTC_REG_REG);
373 	} else {
374 		UINT32 ea = GetEA(modrm);
375 		UINT32 dst = READ32(ea);
376 		UINT32 bit = LOAD_REG32(modrm);
377 
378 		if( dst & (1 << bit) )
379 			I.CF = 1;
380 		else
381 			I.CF = 0;
382 		dst ^= (1 << bit);
383 
384 		WRITE32(ea, dst);
385 		CYCLES(CYCLES_BTC_REG_MEM);
386 	}
387 }
388 
I386OP(btr_rm32_r32)389 static void I386OP(btr_rm32_r32)(void)		// Opcode 0x0f b3
390 {
391 	UINT8 modrm = FETCH();
392 	if( modrm >= 0xc0 ) {
393 		UINT32 dst = LOAD_RM32(modrm);
394 		UINT32 bit = LOAD_REG32(modrm);
395 
396 		if( dst & (1 << bit) )
397 			I.CF = 1;
398 		else
399 			I.CF = 0;
400 		dst &= ~(1 << bit);
401 
402 		STORE_RM32(modrm, dst);
403 		CYCLES(CYCLES_BTR_REG_REG);
404 	} else {
405 		UINT32 ea = GetEA(modrm);
406 		UINT32 dst = READ32(ea);
407 		UINT32 bit = LOAD_REG32(modrm);
408 
409 		if( dst & (1 << bit) )
410 			I.CF = 1;
411 		else
412 			I.CF = 0;
413 		dst &= ~(1 << bit);
414 
415 		WRITE32(ea, dst);
416 		CYCLES(CYCLES_BTR_REG_MEM);
417 	}
418 }
419 
I386OP(bts_rm32_r32)420 static void I386OP(bts_rm32_r32)(void)		// Opcode 0x0f ab
421 {
422 	UINT8 modrm = FETCH();
423 	if( modrm >= 0xc0 ) {
424 		UINT32 dst = LOAD_RM32(modrm);
425 		UINT32 bit = LOAD_REG32(modrm);
426 
427 		if( dst & (1 << bit) )
428 			I.CF = 1;
429 		else
430 			I.CF = 0;
431 		dst |= (1 << bit);
432 
433 		STORE_RM32(modrm, dst);
434 		CYCLES(CYCLES_BTS_REG_REG);
435 	} else {
436 		UINT32 ea = GetEA(modrm);
437 		UINT32 dst = READ32(ea);
438 		UINT32 bit = LOAD_REG32(modrm);
439 
440 		if( dst & (1 << bit) )
441 			I.CF = 1;
442 		else
443 			I.CF = 0;
444 		dst |= (1 << bit);
445 
446 		WRITE32(ea, dst);
447 		CYCLES(CYCLES_BTS_REG_MEM);
448 	}
449 }
450 
I386OP(call_abs32)451 static void I386OP(call_abs32)(void)		// Opcode 0x9a
452 {
453 	UINT32 offset = FETCH32();
454 	UINT16 ptr = FETCH16();
455 
456 	if( PROTECTED_MODE ) {
457 		/* TODO */
458 	//	osd_die("i386: call_abs32 in protected mode unimplemented\n");
459 	} else {
460 		PUSH32( I.sreg[CS].selector );
461 		PUSH32( I.eip );
462 		I.sreg[CS].selector = ptr;
463 		I.eip = offset;
464 		i386_load_segment_descriptor(CS);
465 	}
466 	CYCLES(CYCLES_CALL_INTERSEG);
467 	CHANGE_PC(I.eip);
468 }
469 
I386OP(call_rel32)470 static void I386OP(call_rel32)(void)		// Opcode 0xe8
471 {
472 	INT32 disp = FETCH32();
473 
474 	PUSH32( I.eip );
475 	I.eip += disp;
476 	CHANGE_PC(I.eip);
477 	CYCLES(CYCLES_CALL);		/* TODO: Timing = 7 + m */
478 }
479 
I386OP(cdq)480 static void I386OP(cdq)(void)				// Opcode 0x99
481 {
482 	if( REG32(EAX) & 0x80000000 ) {
483 		REG32(EDX) = 0xffffffff;
484 	} else {
485 		REG32(EDX) = 0x00000000;
486 	}
487 	CYCLES(CYCLES_CWD);
488 }
489 
I386OP(cmp_rm32_r32)490 static void I386OP(cmp_rm32_r32)(void)		// Opcode 0x39
491 {
492 	UINT32 src, dst;
493 	UINT8 modrm = FETCH();
494 	if( modrm >= 0xc0 ) {
495 		src = LOAD_REG32(modrm);
496 		dst = LOAD_RM32(modrm);
497 		SUB32(dst, src);
498 		CYCLES(CYCLES_CMP_REG_REG);
499 	} else {
500 		UINT32 ea = GetEA(modrm);
501 		src = LOAD_REG32(modrm);
502 		dst = READ32(ea);
503 		SUB32(dst, src);
504 		CYCLES(CYCLES_CMP_REG_MEM);
505 	}
506 }
507 
I386OP(cmp_r32_rm32)508 static void I386OP(cmp_r32_rm32)(void)		// Opcode 0x3b
509 {
510 	UINT32 src, dst;
511 	UINT8 modrm = FETCH();
512 	if( modrm >= 0xc0 ) {
513 		src = LOAD_RM32(modrm);
514 		dst = LOAD_REG32(modrm);
515 		SUB32(dst, src);
516 		CYCLES(CYCLES_CMP_REG_REG);
517 	} else {
518 		UINT32 ea = GetEA(modrm);
519 		src = READ32(ea);
520 		dst = LOAD_REG32(modrm);
521 		SUB32(dst, src);
522 		CYCLES(CYCLES_CMP_MEM_REG);
523 	}
524 }
525 
I386OP(cmp_eax_i32)526 static void I386OP(cmp_eax_i32)(void)		// Opcode 0x3d
527 {
528 	UINT32 src, dst;
529 	src = FETCH32();
530 	dst = REG32(EAX);
531 	SUB32(dst, src);
532 	CYCLES(CYCLES_CMP_IMM_ACC);
533 }
534 
I386OP(cmpsd)535 static void I386OP(cmpsd)(void)				// Opcode 0xa7
536 {
537 	UINT32 eas, ead, src, dst;
538 	if( I.segment_prefix ) {
539 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
540 	} else {
541 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
542 	}
543 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
544 	src = READ32(eas);
545 	dst = READ32(ead);
546 	SUB32(dst, src);
547 	BUMP_SI(4);
548 	BUMP_DI(4);
549 	CYCLES(CYCLES_CMPS);
550 }
551 
I386OP(cwde)552 static void I386OP(cwde)(void)				// Opcode 0x98
553 {
554 	REG32(EAX) = (INT32)((INT16)REG16(AX));
555 	CYCLES(CYCLES_CBW);
556 }
557 
I386OP(dec_eax)558 static void I386OP(dec_eax)(void)			// Opcode 0x48
559 {
560 	REG32(EAX) = DEC32( REG32(EAX) );
561 	CYCLES(CYCLES_DEC_REG);
562 }
563 
I386OP(dec_ecx)564 static void I386OP(dec_ecx)(void)			// Opcode 0x49
565 {
566 	REG32(ECX) = DEC32( REG32(ECX) );
567 	CYCLES(CYCLES_DEC_REG);
568 }
569 
I386OP(dec_edx)570 static void I386OP(dec_edx)(void)			// Opcode 0x4a
571 {
572 	REG32(EDX) = DEC32( REG32(EDX) );
573 	CYCLES(CYCLES_DEC_REG);
574 }
575 
I386OP(dec_ebx)576 static void I386OP(dec_ebx)(void)			// Opcode 0x4b
577 {
578 	REG32(EBX) = DEC32( REG32(EBX) );
579 	CYCLES(CYCLES_DEC_REG);
580 }
581 
I386OP(dec_esp)582 static void I386OP(dec_esp)(void)			// Opcode 0x4c
583 {
584 	REG32(ESP) = DEC32( REG32(ESP) );
585 	CYCLES(CYCLES_DEC_REG);
586 }
587 
I386OP(dec_ebp)588 static void I386OP(dec_ebp)(void)			// Opcode 0x4d
589 {
590 	REG32(EBP) = DEC32( REG32(EBP) );
591 	CYCLES(CYCLES_DEC_REG);
592 }
593 
I386OP(dec_esi)594 static void I386OP(dec_esi)(void)			// Opcode 0x4e
595 {
596 	REG32(ESI) = DEC32( REG32(ESI) );
597 	CYCLES(CYCLES_DEC_REG);
598 }
599 
I386OP(dec_edi)600 static void I386OP(dec_edi)(void)			// Opcode 0x4f
601 {
602 	REG32(EDI) = DEC32( REG32(EDI) );
603 	CYCLES(CYCLES_DEC_REG);
604 }
605 
I386OP(imul_r32_rm32)606 static void I386OP(imul_r32_rm32)(void)		// Opcode 0x0f af
607 {
608 	UINT8 modrm = FETCH();
609 	INT64 result;
610 	INT64 src, dst;
611 	if( modrm >= 0xc0 ) {
612 		src = (INT64)(INT32)LOAD_RM32(modrm);
613 		CYCLES(CYCLES_IMUL32_REG_REG);		/* TODO: Correct multiply timing */
614 	} else {
615 		UINT32 ea = GetEA(modrm);
616 		src = (INT64)(INT32)READ32(ea);
617 		CYCLES(CYCLES_IMUL32_REG_REG);		/* TODO: Correct multiply timing */
618 	}
619 
620 	dst = (INT64)(INT32)LOAD_REG32(modrm);
621 	result = src * dst;
622 
623 	STORE_REG32(modrm, (UINT32)result);
624 
625 	I.CF = I.OF = !(result == (INT64)(INT32)result);
626 }
627 
I386OP(imul_r32_rm32_i32)628 static void I386OP(imul_r32_rm32_i32)(void)	// Opcode 0x69
629 {
630 	UINT8 modrm = FETCH();
631 	INT64 result;
632 	INT64 src, dst;
633 	if( modrm >= 0xc0 ) {
634 		dst = (INT64)(INT32)LOAD_RM32(modrm);
635 		CYCLES(CYCLES_IMUL32_REG_IMM_REG);		/* TODO: Correct multiply timing */
636 	} else {
637 		UINT32 ea = GetEA(modrm);
638 		dst = (INT64)(INT32)READ32(ea);
639 		CYCLES(CYCLES_IMUL32_MEM_IMM_REG);		/* TODO: Correct multiply timing */
640 	}
641 
642 	src = (INT64)(INT32)FETCH32();
643 	result = src * dst;
644 
645 	STORE_REG32(modrm, (UINT32)result);
646 
647 	I.CF = I.OF = !(result == (INT64)(INT32)result);
648 }
649 
I386OP(imul_r32_rm32_i8)650 static void I386OP(imul_r32_rm32_i8)(void)	// Opcode 0x6b
651 {
652 	UINT8 modrm = FETCH();
653 	INT64 result;
654 	INT64 src, dst;
655 	if( modrm >= 0xc0 ) {
656 		dst = (INT64)(INT32)LOAD_RM32(modrm);
657 		CYCLES(CYCLES_IMUL32_REG_IMM_REG);		/* TODO: Correct multiply timing */
658 	} else {
659 		UINT32 ea = GetEA(modrm);
660 		dst = (INT64)(INT32)READ32(ea);
661 		CYCLES(CYCLES_IMUL32_MEM_IMM_REG);		/* TODO: Correct multiply timing */
662 	}
663 
664 	src = (INT64)(INT8)FETCH();
665 	result = src * dst;
666 
667 	STORE_REG32(modrm, (UINT32)result);
668 
669 	I.CF = I.OF = !(result == (INT64)(INT32)result);
670 }
671 
I386OP(in_eax_i8)672 static void I386OP(in_eax_i8)(void)			// Opcode 0xe5
673 {
674 	UINT16 port = FETCH();
675 	UINT32 data = READPORT32(port);
676 	REG32(EAX) = data;
677 	CYCLES(CYCLES_IN_VAR);
678 }
679 
I386OP(in_eax_dx)680 static void I386OP(in_eax_dx)(void)			// Opcode 0xed
681 {
682 	UINT16 port = REG16(DX);
683 	UINT32 data = READPORT32(port);
684 	REG32(EAX) = data;
685 	CYCLES(CYCLES_IN);
686 }
687 
I386OP(inc_eax)688 static void I386OP(inc_eax)(void)			// Opcode 0x40
689 {
690 	REG32(EAX) = INC32( REG32(EAX) );
691 	CYCLES(CYCLES_INC_REG);
692 }
693 
I386OP(inc_ecx)694 static void I386OP(inc_ecx)(void)			// Opcode 0x41
695 {
696 	REG32(ECX) = INC32( REG32(ECX) );
697 	CYCLES(CYCLES_INC_REG);
698 }
699 
I386OP(inc_edx)700 static void I386OP(inc_edx)(void)			// Opcode 0x42
701 {
702 	REG32(EDX) = INC32( REG32(EDX) );
703 	CYCLES(CYCLES_INC_REG);
704 }
705 
I386OP(inc_ebx)706 static void I386OP(inc_ebx)(void)			// Opcode 0x43
707 {
708 	REG32(EBX) = INC32( REG32(EBX) );
709 	CYCLES(CYCLES_INC_REG);
710 }
711 
I386OP(inc_esp)712 static void I386OP(inc_esp)(void)			// Opcode 0x44
713 {
714 	REG32(ESP) = INC32( REG32(ESP) );
715 	CYCLES(CYCLES_INC_REG);
716 }
717 
I386OP(inc_ebp)718 static void I386OP(inc_ebp)(void)			// Opcode 0x45
719 {
720 	REG32(EBP) = INC32( REG32(EBP) );
721 	CYCLES(CYCLES_INC_REG);
722 }
723 
I386OP(inc_esi)724 static void I386OP(inc_esi)(void)			// Opcode 0x46
725 {
726 	REG32(ESI) = INC32( REG32(ESI) );
727 	CYCLES(CYCLES_INC_REG);
728 }
729 
I386OP(inc_edi)730 static void I386OP(inc_edi)(void)			// Opcode 0x47
731 {
732 	REG32(EDI) = INC32( REG32(EDI) );
733 	CYCLES(CYCLES_INC_REG);
734 }
735 
I386OP(iret32)736 static void I386OP(iret32)(void)			// Opcode 0xcf
737 {
738 	if( PROTECTED_MODE ) {
739 		/* TODO: Virtual 8086-mode */
740 		/* TODO: Nested task */
741 		/* TODO: #SS(0) exception */
742 		/* TODO: All the protection-related stuff... */
743 		I.eip = POP32();
744 		I.sreg[CS].selector = POP32() & 0xffff;
745 		set_flags( POP32() );
746 		i386_load_segment_descriptor(CS);
747 		CHANGE_PC(I.eip);
748 	} else {
749 		/* TODO: #SS(0) exception */
750 		/* TODO: #GP(0) exception */
751 		I.eip = POP32();
752 		I.sreg[CS].selector = POP32() & 0xffff;
753 		set_flags( POP32() );
754 		i386_load_segment_descriptor(CS);
755 		CHANGE_PC(I.eip);
756 	}
757 	CYCLES(CYCLES_IRET);
758 }
759 
I386OP(ja_rel32)760 static void I386OP(ja_rel32)(void)			// Opcode 0x0f 87
761 {
762 	INT32 disp = FETCH32();
763 	if( I.CF == 0 && I.ZF == 0 ) {
764 		I.eip += disp;
765 		CHANGE_PC(I.eip);
766 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
767 	} else {
768 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
769 	}
770 }
771 
I386OP(jbe_rel32)772 static void I386OP(jbe_rel32)(void)			// Opcode 0x0f 86
773 {
774 	INT32 disp = FETCH32();
775 	if( I.CF != 0 || I.ZF != 0 ) {
776 		I.eip += disp;
777 		CHANGE_PC(I.eip);
778 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
779 	} else {
780 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
781 	}
782 }
783 
I386OP(jc_rel32)784 static void I386OP(jc_rel32)(void)			// Opcode 0x0f 82
785 {
786 	INT32 disp = FETCH32();
787 	if( I.CF != 0 ) {
788 		I.eip += disp;
789 		CHANGE_PC(I.eip);
790 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
791 	} else {
792 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
793 	}
794 }
795 
I386OP(jg_rel32)796 static void I386OP(jg_rel32)(void)			// Opcode 0x0f 8f
797 {
798 	INT32 disp = FETCH32();
799 	if( I.ZF == 0 && (I.SF == I.OF) ) {
800 		I.eip += disp;
801 		CHANGE_PC(I.eip);
802 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
803 	} else {
804 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
805 	}
806 }
807 
I386OP(jge_rel32)808 static void I386OP(jge_rel32)(void)			// Opcode 0x0f 8d
809 {
810 	INT32 disp = FETCH32();
811 	if( (I.SF == I.OF) ) {
812 		I.eip += disp;
813 		CHANGE_PC(I.eip);
814 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
815 	} else {
816 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
817 	}
818 }
819 
I386OP(jl_rel32)820 static void I386OP(jl_rel32)(void)			// Opcode 0x0f 8c
821 {
822 	INT32 disp = FETCH32();
823 	if( (I.SF != I.OF) ) {
824 		I.eip += disp;
825 		CHANGE_PC(I.eip);
826 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
827 	} else {
828 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
829 	}
830 }
831 
I386OP(jle_rel32)832 static void I386OP(jle_rel32)(void)			// Opcode 0x0f 8e
833 {
834 	INT32 disp = FETCH32();
835 	if( I.ZF != 0 || (I.SF != I.OF) ) {
836 		I.eip += disp;
837 		CHANGE_PC(I.eip);
838 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
839 	} else {
840 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
841 	}
842 }
843 
I386OP(jnc_rel32)844 static void I386OP(jnc_rel32)(void)			// Opcode 0x0f 83
845 {
846 	INT32 disp = FETCH32();
847 	if( I.CF == 0 ) {
848 		I.eip += disp;
849 		CHANGE_PC(I.eip);
850 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
851 	} else {
852 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
853 	}
854 }
855 
I386OP(jno_rel32)856 static void I386OP(jno_rel32)(void)			// Opcode 0x0f 81
857 {
858 	INT32 disp = FETCH32();
859 	if( I.OF == 0 ) {
860 		I.eip += disp;
861 		CHANGE_PC(I.eip);
862 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
863 	} else {
864 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
865 	}
866 }
867 
I386OP(jnp_rel32)868 static void I386OP(jnp_rel32)(void)			// Opcode 0x0f 8b
869 {
870 	INT32 disp = FETCH32();
871 	if( I.PF == 0 ) {
872 		I.eip += disp;
873 		CHANGE_PC(I.eip);
874 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
875 	} else {
876 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
877 	}
878 }
879 
I386OP(jns_rel32)880 static void I386OP(jns_rel32)(void)			// Opcode 0x0f 89
881 {
882 	INT32 disp = FETCH32();
883 	if( I.SF == 0 ) {
884 		I.eip += disp;
885 		CHANGE_PC(I.eip);
886 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
887 	} else {
888 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
889 	}
890 }
891 
I386OP(jnz_rel32)892 static void I386OP(jnz_rel32)(void)			// Opcode 0x0f 85
893 {
894 	INT32 disp = FETCH32();
895 	if( I.ZF == 0 ) {
896 		I.eip += disp;
897 		CHANGE_PC(I.eip);
898 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
899 	} else {
900 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
901 	}
902 }
903 
I386OP(jo_rel32)904 static void I386OP(jo_rel32)(void)			// Opcode 0x0f 80
905 {
906 	INT32 disp = FETCH32();
907 	if( I.OF != 0 ) {
908 		I.eip += disp;
909 		CHANGE_PC(I.eip);
910 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
911 	} else {
912 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
913 	}
914 }
915 
I386OP(jp_rel32)916 static void I386OP(jp_rel32)(void)			// Opcode 0x0f 8a
917 {
918 	INT32 disp = FETCH32();
919 	if( I.PF != 0 ) {
920 		I.eip += disp;
921 		CHANGE_PC(I.eip);
922 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
923 	} else {
924 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
925 	}
926 }
927 
I386OP(js_rel32)928 static void I386OP(js_rel32)(void)			// Opcode 0x0f 88
929 {
930 	INT32 disp = FETCH32();
931 	if( I.SF != 0 ) {
932 		I.eip += disp;
933 		CHANGE_PC(I.eip);
934 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
935 	} else {
936 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
937 	}
938 }
939 
I386OP(jz_rel32)940 static void I386OP(jz_rel32)(void)			// Opcode 0x0f 84
941 {
942 	INT32 disp = FETCH32();
943 	if( I.ZF != 0 ) {
944 		I.eip += disp;
945 		CHANGE_PC(I.eip);
946 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
947 	} else {
948 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
949 	}
950 }
951 
I386OP(jcxz32)952 static void I386OP(jcxz32)(void)			// Opcode 0xe3
953 {
954 	INT8 disp = FETCH();
955 	if( REG32(ECX) == 0 ) {
956 		I.eip += disp;
957 		CHANGE_PC(I.eip);
958 		CYCLES(CYCLES_JCXZ);		/* TODO: Timing = 9 + m */
959 	} else {
960 		CYCLES(CYCLES_JCXZ_NOBRANCH);
961 	}
962 }
963 
I386OP(jmp_rel32)964 static void I386OP(jmp_rel32)(void)			// Opcode 0xe9
965 {
966 	UINT32 disp = FETCH32();
967 	/* TODO: Segment limit */
968 	I.eip += disp;
969 	CHANGE_PC(I.eip);
970 	CYCLES(CYCLES_JMP);		/* TODO: Timing = 7 + m */
971 }
972 
I386OP(jmp_abs32)973 static void I386OP(jmp_abs32)(void)			// Opcode 0xea
974 {
975 	UINT32 address = FETCH32();
976 	UINT16 segment = FETCH16();
977 
978 	if( PROTECTED_MODE ) {
979 		/* TODO: #GP */
980 		/* TODO: access rights, etc. */
981 		I.eip = address;
982 		I.sreg[CS].selector = segment;
983 		i386_load_segment_descriptor(CS);
984 		CHANGE_PC(I.eip);
985 	} else {
986 		I.eip = address;
987 		I.sreg[CS].selector = segment;
988 		i386_load_segment_descriptor(CS);
989 		CHANGE_PC(I.eip);
990 	}
991 	CYCLES(CYCLES_JMP_INTERSEG);
992 }
993 
I386OP(lea32)994 static void I386OP(lea32)(void)				// Opcode 0x8d
995 {
996 	UINT8 modrm = FETCH();
997 	UINT32 ea = GetNonTranslatedEA(modrm);
998 	if (!I.address_size)
999 	{
1000 		ea &= 0xffff;
1001 	}
1002 	STORE_REG32(modrm, ea);
1003 	CYCLES(CYCLES_LEA);
1004 }
1005 
I386OP(leave32)1006 static void I386OP(leave32)(void)			// Opcode 0xc9
1007 {
1008 	REG32(ESP) = REG32(EBP);
1009 	REG32(EBP) = POP32();
1010 	CYCLES(CYCLES_LEAVE);
1011 }
1012 
I386OP(lodsd)1013 static void I386OP(lodsd)(void)				// Opcode 0xad
1014 {
1015 	UINT32 eas;
1016 	if( I.segment_prefix ) {
1017 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
1018 	} else {
1019 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
1020 	}
1021 	REG32(EAX) = READ32(eas);
1022 	BUMP_SI(4);
1023 	CYCLES(CYCLES_LODS);
1024 }
1025 
I386OP(loop32)1026 static void I386OP(loop32)(void)			// Opcode 0xe2
1027 {
1028 	INT8 disp = FETCH();
1029 	REG32(ECX)--;
1030 	if( REG32(ECX) != 0 ) {
1031 		I.eip += disp;
1032 		CHANGE_PC(I.eip);
1033 	}
1034 	CYCLES(CYCLES_LOOP);		/* TODO: Timing = 11 + m */
1035 }
1036 
I386OP(loopne32)1037 static void I386OP(loopne32)(void)			// Opcode 0xe0
1038 {
1039 	INT8 disp = FETCH();
1040 	REG32(ECX)--;
1041 	if( REG32(ECX) != 0 && I.ZF == 0 ) {
1042 		I.eip += disp;
1043 		CHANGE_PC(I.eip);
1044 	}
1045 	CYCLES(CYCLES_LOOPNZ);		/* TODO: Timing = 11 + m */
1046 }
1047 
I386OP(loopz32)1048 static void I386OP(loopz32)(void)			// Opcode 0xe1
1049 {
1050 	INT8 disp = FETCH();
1051 	REG32(ECX)--;
1052 	if( REG32(ECX) != 0 && I.ZF != 0 ) {
1053 		I.eip += disp;
1054 		CHANGE_PC(I.eip);
1055 	}
1056 	CYCLES(CYCLES_LOOPZ);		/* TODO: Timing = 11 + m */
1057 }
1058 
I386OP(mov_rm32_r32)1059 static void I386OP(mov_rm32_r32)(void)		// Opcode 0x89
1060 {
1061 	UINT32 src;
1062 	UINT8 modrm = FETCH();
1063 	if( modrm >= 0xc0 ) {
1064 		src = LOAD_REG32(modrm);
1065 		STORE_RM32(modrm, src);
1066 		CYCLES(CYCLES_MOV_REG_REG);
1067 	} else {
1068 		UINT32 ea = GetEA(modrm);
1069 		src = LOAD_REG32(modrm);
1070 		WRITE32(ea, src);
1071 		CYCLES(CYCLES_MOV_REG_MEM);
1072 	}
1073 }
1074 
I386OP(mov_r32_rm32)1075 static void I386OP(mov_r32_rm32)(void)		// Opcode 0x8b
1076 {
1077 	UINT32 src;
1078 	UINT8 modrm = FETCH();
1079 	if( modrm >= 0xc0 ) {
1080 		src = LOAD_RM32(modrm);
1081 		STORE_REG32(modrm, src);
1082 		CYCLES(CYCLES_MOV_REG_REG);
1083 	} else {
1084 		UINT32 ea = GetEA(modrm);
1085 		src = READ32(ea);
1086 		STORE_REG32(modrm, src);
1087 		CYCLES(CYCLES_MOV_MEM_REG);
1088 	}
1089 }
1090 
I386OP(mov_rm32_i32)1091 static void I386OP(mov_rm32_i32)(void)		// Opcode 0xc7
1092 {
1093 	UINT8 modrm = FETCH();
1094 	if( modrm >= 0xc0 ) {
1095 		UINT32 value = FETCH32();
1096 		STORE_RM32(modrm, value);
1097 		CYCLES(CYCLES_MOV_IMM_REG);
1098 	} else {
1099 		UINT32 ea = GetEA(modrm);
1100 		UINT32 value = FETCH32();
1101 		WRITE32(ea, value);
1102 		CYCLES(CYCLES_MOV_IMM_MEM);
1103 	}
1104 }
1105 
I386OP(mov_eax_m32)1106 static void I386OP(mov_eax_m32)(void)		// Opcode 0xa1
1107 {
1108 	UINT32 offset, ea;
1109 	if( I.address_size ) {
1110 		offset = FETCH32();
1111 	} else {
1112 		offset = FETCH16();
1113 	}
1114 	if( I.segment_prefix ) {
1115 		ea = i386_translate( I.segment_override, offset );
1116 	} else {
1117 		ea = i386_translate( DS, offset );
1118 	}
1119 	REG32(EAX) = READ32(ea);
1120 	CYCLES(CYCLES_MOV_MEM_ACC);
1121 }
1122 
I386OP(mov_m32_eax)1123 static void I386OP(mov_m32_eax)(void)		// Opcode 0xa3
1124 {
1125 	UINT32 offset, ea;
1126 	if( I.address_size ) {
1127 		offset = FETCH32();
1128 	} else {
1129 		offset = FETCH16();
1130 	}
1131 	if( I.segment_prefix ) {
1132 		ea = i386_translate( I.segment_override, offset );
1133 	} else {
1134 		ea = i386_translate( DS, offset );
1135 	}
1136 	WRITE32( ea, REG32(EAX) );
1137 	CYCLES(CYCLES_MOV_ACC_MEM);
1138 }
1139 
I386OP(mov_eax_i32)1140 static void I386OP(mov_eax_i32)(void)		// Opcode 0xb8
1141 {
1142 	REG32(EAX) = FETCH32();
1143 	CYCLES(CYCLES_MOV_IMM_REG);
1144 }
1145 
I386OP(mov_ecx_i32)1146 static void I386OP(mov_ecx_i32)(void)		// Opcode 0xb9
1147 {
1148 	REG32(ECX) = FETCH32();
1149 	CYCLES(CYCLES_MOV_IMM_REG);
1150 }
1151 
I386OP(mov_edx_i32)1152 static void I386OP(mov_edx_i32)(void)		// Opcode 0xba
1153 {
1154 	REG32(EDX) = FETCH32();
1155 	CYCLES(CYCLES_MOV_IMM_REG);
1156 }
1157 
I386OP(mov_ebx_i32)1158 static void I386OP(mov_ebx_i32)(void)		// Opcode 0xbb
1159 {
1160 	REG32(EBX) = FETCH32();
1161 	CYCLES(CYCLES_MOV_IMM_REG);
1162 }
1163 
I386OP(mov_esp_i32)1164 static void I386OP(mov_esp_i32)(void)		// Opcode 0xbc
1165 {
1166 	REG32(ESP) = FETCH32();
1167 	CYCLES(CYCLES_MOV_IMM_REG);
1168 }
1169 
I386OP(mov_ebp_i32)1170 static void I386OP(mov_ebp_i32)(void)		// Opcode 0xbd
1171 {
1172 	REG32(EBP) = FETCH32();
1173 	CYCLES(CYCLES_MOV_IMM_REG);
1174 }
1175 
I386OP(mov_esi_i32)1176 static void I386OP(mov_esi_i32)(void)		// Opcode 0xbe
1177 {
1178 	REG32(ESI) = FETCH32();
1179 	CYCLES(CYCLES_MOV_IMM_REG);
1180 }
1181 
I386OP(mov_edi_i32)1182 static void I386OP(mov_edi_i32)(void)		// Opcode 0xbf
1183 {
1184 	REG32(EDI) = FETCH32();
1185 	CYCLES(CYCLES_MOV_IMM_REG);
1186 }
1187 
I386OP(movsd)1188 static void I386OP(movsd)(void)				// Opcode 0xa5
1189 {
1190 	UINT32 eas, ead, v;
1191 	if( I.segment_prefix ) {
1192 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
1193 	} else {
1194 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
1195 	}
1196 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1197 	v = READ32(eas);
1198 	WRITE32(ead, v);
1199 	BUMP_SI(4);
1200 	BUMP_DI(4);
1201 	CYCLES(CYCLES_MOVS);
1202 }
1203 
I386OP(movsx_r32_rm8)1204 static void I386OP(movsx_r32_rm8)(void)		// Opcode 0x0f be
1205 {
1206 	UINT8 modrm = FETCH();
1207 	if( modrm >= 0xc0 ) {
1208 		INT32 src = (INT8)LOAD_RM8(modrm);
1209 		STORE_REG32(modrm, src);
1210 		CYCLES(CYCLES_MOVSX_REG_REG);
1211 	} else {
1212 		UINT32 ea = GetEA(modrm);
1213 		INT32 src = (INT8)READ8(ea);
1214 		STORE_REG32(modrm, src);
1215 		CYCLES(CYCLES_MOVSX_MEM_REG);
1216 	}
1217 }
1218 
I386OP(movsx_r32_rm16)1219 static void I386OP(movsx_r32_rm16)(void)	// Opcode 0x0f bf
1220 {
1221 	UINT8 modrm = FETCH();
1222 	if( modrm >= 0xc0 ) {
1223 		INT32 src = (INT16)LOAD_RM16(modrm);
1224 		STORE_REG32(modrm, src);
1225 		CYCLES(CYCLES_MOVSX_REG_REG);
1226 	} else {
1227 		UINT32 ea = GetEA(modrm);
1228 		INT32 src = (INT16)READ16(ea);
1229 		STORE_REG32(modrm, src);
1230 		CYCLES(CYCLES_MOVSX_MEM_REG);
1231 	}
1232 }
1233 
I386OP(movzx_r32_rm8)1234 static void I386OP(movzx_r32_rm8)(void)		// Opcode 0x0f b6
1235 {
1236 	UINT8 modrm = FETCH();
1237 	if( modrm >= 0xc0 ) {
1238 		UINT32 src = (UINT8)LOAD_RM8(modrm);
1239 		STORE_REG32(modrm, src);
1240 		CYCLES(CYCLES_MOVZX_REG_REG);
1241 	} else {
1242 		UINT32 ea = GetEA(modrm);
1243 		UINT32 src = (UINT8)READ8(ea);
1244 		STORE_REG32(modrm, src);
1245 		CYCLES(CYCLES_MOVZX_MEM_REG);
1246 	}
1247 }
1248 
I386OP(movzx_r32_rm16)1249 static void I386OP(movzx_r32_rm16)(void)	// Opcode 0x0f b7
1250 {
1251 	UINT8 modrm = FETCH();
1252 	if( modrm >= 0xc0 ) {
1253 		UINT32 src = (UINT16)LOAD_RM16(modrm);
1254 		STORE_REG32(modrm, src);
1255 		CYCLES(CYCLES_MOVZX_REG_REG);
1256 	} else {
1257 		UINT32 ea = GetEA(modrm);
1258 		UINT32 src = (UINT16)READ16(ea);
1259 		STORE_REG32(modrm, src);
1260 		CYCLES(CYCLES_MOVZX_MEM_REG);
1261 	}
1262 }
1263 
I386OP(or_rm32_r32)1264 static void I386OP(or_rm32_r32)(void)		// Opcode 0x09
1265 {
1266 	UINT32 src, dst;
1267 	UINT8 modrm = FETCH();
1268 	if( modrm >= 0xc0 ) {
1269 		src = LOAD_REG32(modrm);
1270 		dst = LOAD_RM32(modrm);
1271 		dst = OR32(dst, src);
1272 		STORE_RM32(modrm, dst);
1273 		CYCLES(CYCLES_ALU_REG_REG);
1274 	} else {
1275 		UINT32 ea = GetEA(modrm);
1276 		src = LOAD_REG32(modrm);
1277 		dst = READ32(ea);
1278 		dst = OR32(dst, src);
1279 		WRITE32(ea, dst);
1280 		CYCLES(CYCLES_ALU_REG_MEM);
1281 	}
1282 }
1283 
I386OP(or_r32_rm32)1284 static void I386OP(or_r32_rm32)(void)		// Opcode 0x0b
1285 {
1286 	UINT32 src, dst;
1287 	UINT8 modrm = FETCH();
1288 	if( modrm >= 0xc0 ) {
1289 		src = LOAD_RM32(modrm);
1290 		dst = LOAD_REG32(modrm);
1291 		dst = OR32(dst, src);
1292 		STORE_REG32(modrm, dst);
1293 		CYCLES(CYCLES_ALU_REG_REG);
1294 	} else {
1295 		UINT32 ea = GetEA(modrm);
1296 		src = READ32(ea);
1297 		dst = LOAD_REG32(modrm);
1298 		dst = OR32(dst, src);
1299 		STORE_REG32(modrm, dst);
1300 		CYCLES(CYCLES_ALU_MEM_REG);
1301 	}
1302 }
1303 
I386OP(or_eax_i32)1304 static void I386OP(or_eax_i32)(void)		// Opcode 0x0d
1305 {
1306 	UINT32 src, dst;
1307 	src = FETCH32();
1308 	dst = REG32(EAX);
1309 	dst = OR32(dst, src);
1310 	REG32(EAX) = dst;
1311 	CYCLES(CYCLES_ALU_IMM_ACC);
1312 }
1313 
I386OP(out_eax_i8)1314 static void I386OP(out_eax_i8)(void)		// Opcode 0xe7
1315 {
1316 	UINT16 port = FETCH();
1317 	UINT32 data = REG32(EAX);
1318 	WRITEPORT32(port, data);
1319 	CYCLES(CYCLES_OUT_VAR);
1320 }
1321 
I386OP(out_eax_dx)1322 static void I386OP(out_eax_dx)(void)		// Opcode 0xef
1323 {
1324 	UINT16 port = REG16(DX);
1325 	UINT32 data = REG32(EAX);
1326 	WRITEPORT32(port, data);
1327 	CYCLES(CYCLES_OUT);
1328 }
1329 
I386OP(pop_eax)1330 static void I386OP(pop_eax)(void)			// Opcode 0x58
1331 {
1332 	REG32(EAX) = POP32();
1333 	CYCLES(CYCLES_POP_REG_SHORT);
1334 }
1335 
I386OP(pop_ecx)1336 static void I386OP(pop_ecx)(void)			// Opcode 0x59
1337 {
1338 	REG32(ECX) = POP32();
1339 	CYCLES(CYCLES_POP_REG_SHORT);
1340 }
1341 
I386OP(pop_edx)1342 static void I386OP(pop_edx)(void)			// Opcode 0x5a
1343 {
1344 	REG32(EDX) = POP32();
1345 	CYCLES(CYCLES_POP_REG_SHORT);
1346 }
1347 
I386OP(pop_ebx)1348 static void I386OP(pop_ebx)(void)			// Opcode 0x5b
1349 {
1350 	REG32(EBX) = POP32();
1351 	CYCLES(CYCLES_POP_REG_SHORT);
1352 }
1353 
I386OP(pop_esp)1354 static void I386OP(pop_esp)(void)			// Opcode 0x5c
1355 {
1356 	REG32(ESP) = POP32();
1357 	CYCLES(CYCLES_POP_REG_SHORT);
1358 }
1359 
I386OP(pop_ebp)1360 static void I386OP(pop_ebp)(void)			// Opcode 0x5d
1361 {
1362 	REG32(EBP) = POP32();
1363 	CYCLES(CYCLES_POP_REG_SHORT);
1364 }
1365 
I386OP(pop_esi)1366 static void I386OP(pop_esi)(void)			// Opcode 0x5e
1367 {
1368 	REG32(ESI) = POP32();
1369 	CYCLES(CYCLES_POP_REG_SHORT);
1370 }
1371 
I386OP(pop_edi)1372 static void I386OP(pop_edi)(void)			// Opcode 0x5f
1373 {
1374 	REG32(EDI) = POP32();
1375 	CYCLES(CYCLES_POP_REG_SHORT);
1376 }
1377 
I386OP(pop_ds32)1378 static void I386OP(pop_ds32)(void)			// Opcode 0x1f
1379 {
1380 	I.sreg[DS].selector = POP32();
1381 	if( PROTECTED_MODE ) {
1382 		i386_load_segment_descriptor(DS);
1383 	} else {
1384 		i386_load_segment_descriptor(DS);
1385 	}
1386 	CYCLES(CYCLES_POP_SREG);
1387 }
1388 
I386OP(pop_es32)1389 static void I386OP(pop_es32)(void)			// Opcode 0x07
1390 {
1391 	I.sreg[ES].selector = POP32();
1392 	if( PROTECTED_MODE ) {
1393 		i386_load_segment_descriptor(ES);
1394 	} else {
1395 		i386_load_segment_descriptor(ES);
1396 	}
1397 	CYCLES(CYCLES_POP_SREG);
1398 }
1399 
I386OP(pop_fs32)1400 static void I386OP(pop_fs32)(void)			// Opcode 0x0f a1
1401 {
1402 	I.sreg[FS].selector = POP32();
1403 	if( PROTECTED_MODE ) {
1404 		i386_load_segment_descriptor(FS);
1405 	} else {
1406 		i386_load_segment_descriptor(FS);
1407 	}
1408 	CYCLES(CYCLES_POP_SREG);
1409 }
1410 
I386OP(pop_gs32)1411 static void I386OP(pop_gs32)(void)			// Opcode 0x0f a9
1412 {
1413 	I.sreg[GS].selector = POP32();
1414 	if( PROTECTED_MODE ) {
1415 		i386_load_segment_descriptor(GS);
1416 	} else {
1417 		i386_load_segment_descriptor(GS);
1418 	}
1419 	CYCLES(CYCLES_POP_SREG);
1420 }
1421 
I386OP(pop_ss32)1422 static void I386OP(pop_ss32)(void)			// Opcode 0x17
1423 {
1424 	I.sreg[SS].selector = POP32();
1425 	if( PROTECTED_MODE ) {
1426 		i386_load_segment_descriptor(SS);
1427 	} else {
1428 		i386_load_segment_descriptor(SS);
1429 	}
1430 	CYCLES(CYCLES_POP_SREG);
1431 }
1432 
I386OP(pop_rm32)1433 static void I386OP(pop_rm32)(void)			// Opcode 0x8f
1434 {
1435 	UINT8 modrm = FETCH();
1436 	UINT32 value = POP32();
1437 
1438 	if( modrm >= 0xc0 ) {
1439 		STORE_RM32(modrm, value);
1440 	} else {
1441 		UINT32 ea = GetEA(modrm);
1442 		WRITE32(ea, value);
1443 	}
1444 	CYCLES(CYCLES_POP_RM);
1445 }
1446 
I386OP(popad)1447 static void I386OP(popad)(void)				// Opcode 0x61
1448 {
1449 	REG32(EDI) = POP32();
1450 	REG32(ESI) = POP32();
1451 	REG32(EBP) = POP32();
1452 	REG32(ESP) += 4;
1453 	REG32(EBX) = POP32();
1454 	REG32(EDX) = POP32();
1455 	REG32(ECX) = POP32();
1456 	REG32(EAX) = POP32();
1457 	CYCLES(CYCLES_POPA);
1458 }
1459 
I386OP(popfd)1460 static void I386OP(popfd)(void)				// Opcode 0x9d
1461 {
1462 	UINT32 value = POP32();
1463 	set_flags(value);
1464 	CYCLES(CYCLES_POPF);
1465 }
1466 
I386OP(push_eax)1467 static void I386OP(push_eax)(void)			// Opcode 0x50
1468 {
1469 	PUSH32( REG32(EAX) );
1470 	CYCLES(CYCLES_PUSH_REG_SHORT);
1471 }
1472 
I386OP(push_ecx)1473 static void I386OP(push_ecx)(void)			// Opcode 0x51
1474 {
1475 	PUSH32( REG32(ECX) );
1476 	CYCLES(CYCLES_PUSH_REG_SHORT);
1477 }
1478 
I386OP(push_edx)1479 static void I386OP(push_edx)(void)			// Opcode 0x52
1480 {
1481 	PUSH32( REG32(EDX) );
1482 	CYCLES(CYCLES_PUSH_REG_SHORT);
1483 }
1484 
I386OP(push_ebx)1485 static void I386OP(push_ebx)(void)			// Opcode 0x53
1486 {
1487 	PUSH32( REG32(EBX) );
1488 	CYCLES(CYCLES_PUSH_REG_SHORT);
1489 }
1490 
I386OP(push_esp)1491 static void I386OP(push_esp)(void)			// Opcode 0x54
1492 {
1493 	PUSH32( REG32(ESP) );
1494 	CYCLES(CYCLES_PUSH_REG_SHORT);
1495 }
1496 
I386OP(push_ebp)1497 static void I386OP(push_ebp)(void)			// Opcode 0x55
1498 {
1499 	PUSH32( REG32(EBP) );
1500 	CYCLES(CYCLES_PUSH_REG_SHORT);
1501 }
1502 
I386OP(push_esi)1503 static void I386OP(push_esi)(void)			// Opcode 0x56
1504 {
1505 	PUSH32( REG32(ESI) );
1506 	CYCLES(CYCLES_PUSH_REG_SHORT);
1507 }
1508 
I386OP(push_edi)1509 static void I386OP(push_edi)(void)			// Opcode 0x57
1510 {
1511 	PUSH32( REG32(EDI) );
1512 	CYCLES(CYCLES_PUSH_REG_SHORT);
1513 }
1514 
I386OP(push_cs32)1515 static void I386OP(push_cs32)(void)			// Opcode 0x0e
1516 {
1517 	PUSH32( I.sreg[CS].selector );
1518 	CYCLES(CYCLES_PUSH_SREG);
1519 }
1520 
I386OP(push_ds32)1521 static void I386OP(push_ds32)(void)			// Opcode 0x1e
1522 {
1523 	PUSH32( I.sreg[DS].selector );
1524 	CYCLES(CYCLES_PUSH_SREG);
1525 }
1526 
I386OP(push_es32)1527 static void I386OP(push_es32)(void)			// Opcode 0x06
1528 {
1529 	PUSH32( I.sreg[ES].selector );
1530 	CYCLES(CYCLES_PUSH_SREG);
1531 }
1532 
I386OP(push_fs32)1533 static void I386OP(push_fs32)(void)			// Opcode 0x0f a0
1534 {
1535 	PUSH32( I.sreg[FS].selector );
1536 	CYCLES(CYCLES_PUSH_SREG);
1537 }
1538 
I386OP(push_gs32)1539 static void I386OP(push_gs32)(void)			// Opcode 0x0f a8
1540 {
1541 	PUSH32( I.sreg[GS].selector );
1542 	CYCLES(CYCLES_PUSH_SREG);
1543 }
1544 
I386OP(push_ss32)1545 static void I386OP(push_ss32)(void)			// Opcode 0x16
1546 {
1547 	PUSH32( I.sreg[SS].selector );
1548 	CYCLES(CYCLES_PUSH_SREG);
1549 }
1550 
I386OP(push_i32)1551 static void I386OP(push_i32)(void)			// Opcode 0x68
1552 {
1553 	UINT32 value = FETCH32();
1554 	PUSH32(value);
1555 	CYCLES(CYCLES_PUSH_IMM);
1556 }
1557 
I386OP(pushad)1558 static void I386OP(pushad)(void)			// Opcode 0x60
1559 {
1560 	UINT32 temp = REG32(ESP);
1561 	PUSH32( REG32(EAX) );
1562 	PUSH32( REG32(ECX) );
1563 	PUSH32( REG32(EDX) );
1564 	PUSH32( REG32(EBX) );
1565 	PUSH32( temp );
1566 	PUSH32( REG32(EBP) );
1567 	PUSH32( REG32(ESI) );
1568 	PUSH32( REG32(EDI) );
1569 	CYCLES(CYCLES_PUSHA);
1570 }
1571 
I386OP(pushfd)1572 static void I386OP(pushfd)(void)			// Opcode 0x9c
1573 {
1574 	PUSH32( get_flags() & 0x00fcffff );
1575 	CYCLES(CYCLES_PUSHF);
1576 }
1577 
I386OP(ret_near32_i16)1578 static void I386OP(ret_near32_i16)(void)	// Opcode 0xc2
1579 {
1580 	INT16 disp = FETCH16();
1581 	I.eip = POP32();
1582 	REG32(ESP) += disp;
1583 	CHANGE_PC(I.eip);
1584 	CYCLES(CYCLES_RET_IMM);		/* TODO: Timing = 10 + m */
1585 }
1586 
I386OP(ret_near32)1587 static void I386OP(ret_near32)(void)		// Opcode 0xc3
1588 {
1589 	I.eip = POP32();
1590 	CHANGE_PC(I.eip);
1591 	CYCLES(CYCLES_RET);		/* TODO: Timing = 10 + m */
1592 }
1593 
I386OP(sbb_rm32_r32)1594 static void I386OP(sbb_rm32_r32)(void)		// Opcode 0x19
1595 {
1596 	UINT32 src, dst;
1597 	UINT8 modrm = FETCH();
1598 	if( modrm >= 0xc0 ) {
1599 		src = LOAD_REG32(modrm) + I.CF;
1600 		dst = LOAD_RM32(modrm);
1601 		dst = SUB32(dst, src);
1602 		STORE_RM32(modrm, dst);
1603 		CYCLES(CYCLES_ALU_REG_REG);
1604 	} else {
1605 		UINT32 ea = GetEA(modrm);
1606 		src = LOAD_REG32(modrm) + I.CF;
1607 		dst = READ32(ea);
1608 		dst = SUB32(dst, src);
1609 		WRITE32(ea, dst);
1610 		CYCLES(CYCLES_ALU_REG_MEM);
1611 	}
1612 }
1613 
I386OP(sbb_r32_rm32)1614 static void I386OP(sbb_r32_rm32)(void)		// Opcode 0x1b
1615 {
1616 	UINT32 src, dst;
1617 	UINT8 modrm = FETCH();
1618 	if( modrm >= 0xc0 ) {
1619 		src = LOAD_RM32(modrm) + I.CF;
1620 		dst = LOAD_REG32(modrm);
1621 		dst = SUB32(dst, src);
1622 		STORE_REG32(modrm, dst);
1623 		CYCLES(CYCLES_ALU_REG_REG);
1624 	} else {
1625 		UINT32 ea = GetEA(modrm);
1626 		src = READ32(ea) + I.CF;
1627 		dst = LOAD_REG32(modrm);
1628 		dst = SUB32(dst, src);
1629 		STORE_REG32(modrm, dst);
1630 		CYCLES(CYCLES_ALU_MEM_REG);
1631 	}
1632 }
1633 
I386OP(sbb_eax_i32)1634 static void I386OP(sbb_eax_i32)(void)		// Opcode 0x1d
1635 {
1636 	UINT32 src, dst;
1637 	src = FETCH32() + I.CF;
1638 	dst = REG32(EAX);
1639 	dst = SUB32(dst, src);
1640 	REG32(EAX) = dst;
1641 	CYCLES(CYCLES_ALU_IMM_ACC);
1642 }
1643 
I386OP(scasd)1644 static void I386OP(scasd)(void)				// Opcode 0xaf
1645 {
1646 	UINT32 eas, src, dst;
1647 	eas = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1648 	src = READ32(eas);
1649 	dst = REG32(EAX);
1650 	SUB32(dst, src);
1651 	BUMP_DI(4);
1652 	CYCLES(CYCLES_SCAS);
1653 }
1654 
I386OP(shld32_i8)1655 static void I386OP(shld32_i8)(void)			// Opcode 0x0f a4
1656 {
1657 	/* TODO: Correct flags */
1658 	UINT8 modrm = FETCH();
1659 	if( modrm >= 0xc0 ) {
1660 		UINT32 dst = LOAD_RM32(modrm);
1661 		UINT32 upper = LOAD_REG32(modrm);
1662 		UINT8 shift = FETCH();
1663 		if( shift > 31 || shift == 0 ) {
1664 
1665 		} else {
1666 			I.CF = (dst & (1 << (32-shift))) ? 1 : 0;
1667 			dst = (dst << shift) | (upper >> (32-shift));
1668 			SetSZPF32(dst);
1669 		}
1670 		STORE_RM32(modrm, dst);
1671 		CYCLES(CYCLES_SHLD_REG);
1672 	} else {
1673 		UINT32 ea = GetEA(modrm);
1674 		UINT32 dst = READ32(ea);
1675 		UINT32 upper = LOAD_REG32(modrm);
1676 		UINT8 shift = FETCH();
1677 		if( shift > 31 || shift == 0 ) {
1678 
1679 		} else {
1680 			I.CF = (dst & (1 << (32-shift))) ? 1 : 0;
1681 			dst = (dst << shift) | (upper >> (32-shift));
1682 			SetSZPF32(dst);
1683 		}
1684 		WRITE32(ea, dst);
1685 		CYCLES(CYCLES_SHLD_MEM);
1686 	}
1687 }
1688 
I386OP(shld32_cl)1689 static void I386OP(shld32_cl)(void)			// Opcode 0x0f a5
1690 {
1691 	/* TODO: Correct flags */
1692 	UINT8 modrm = FETCH();
1693 	if( modrm >= 0xc0 ) {
1694 		UINT32 dst = LOAD_RM32(modrm);
1695 		UINT32 upper = LOAD_REG32(modrm);
1696 		UINT8 shift = REG8(CL);
1697 		if( shift > 31 || shift == 0 ) {
1698 
1699 		} else {
1700 			I.CF = (dst & (1 << (32-shift))) ? 1 : 0;
1701 			dst = (dst << shift) | (upper >> (32-shift));
1702 			SetSZPF32(dst);
1703 		}
1704 		STORE_RM32(modrm, dst);
1705 		CYCLES(CYCLES_SHLD_REG);
1706 	} else {
1707 		UINT32 ea = GetEA(modrm);
1708 		UINT32 dst = READ32(ea);
1709 		UINT32 upper = LOAD_REG32(modrm);
1710 		UINT8 shift = REG8(CL);
1711 		if( shift > 31 || shift == 0 ) {
1712 
1713 		} else {
1714 			I.CF = (dst & (1 << (32-shift))) ? 1 : 0;
1715 			dst = (dst << shift) | (upper >> (32-shift));
1716 			SetSZPF32(dst);
1717 		}
1718 		WRITE32(ea, dst);
1719 		CYCLES(CYCLES_SHLD_MEM);
1720 	}
1721 }
1722 
I386OP(shrd32_i8)1723 static void I386OP(shrd32_i8)(void)			// Opcode 0x0f ac
1724 {
1725 	/* TODO: Correct flags */
1726 	UINT8 modrm = FETCH();
1727 	if( modrm >= 0xc0 ) {
1728 		UINT32 dst = LOAD_RM32(modrm);
1729 		UINT32 upper = LOAD_REG32(modrm);
1730 		UINT8 shift = FETCH();
1731 		if( shift > 31 || shift == 0 ) {
1732 
1733 		} else {
1734 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1735 			dst = (dst >> shift) | (upper << (32-shift));
1736 			SetSZPF32(dst);
1737 		}
1738 		STORE_RM32(modrm, dst);
1739 		CYCLES(CYCLES_SHRD_REG);
1740 	} else {
1741 		UINT32 ea = GetEA(modrm);
1742 		UINT32 dst = READ32(ea);
1743 		UINT32 upper = LOAD_REG32(modrm);
1744 		UINT8 shift = FETCH();
1745 		if( shift > 31 || shift == 0 ) {
1746 
1747 		} else {
1748 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1749 			dst = (dst >> shift) | (upper << (32-shift));
1750 			SetSZPF32(dst);
1751 		}
1752 		WRITE32(ea, dst);
1753 		CYCLES(CYCLES_SHRD_MEM);
1754 	}
1755 }
1756 
I386OP(shrd32_cl)1757 static void I386OP(shrd32_cl)(void)			// Opcode 0x0f ad
1758 {
1759 	/* TODO: Correct flags */
1760 	UINT8 modrm = FETCH();
1761 	if( modrm >= 0xc0 ) {
1762 		UINT32 dst = LOAD_RM32(modrm);
1763 		UINT32 upper = LOAD_REG32(modrm);
1764 		UINT8 shift = REG8(CL);
1765 		if( shift > 31 || shift == 0 ) {
1766 
1767 		} else {
1768 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1769 			dst = (dst >> shift) | (upper << (32-shift));
1770 			SetSZPF32(dst);
1771 		}
1772 		STORE_RM32(modrm, dst);
1773 		CYCLES(CYCLES_SHRD_REG);
1774 	} else {
1775 		UINT32 ea = GetEA(modrm);
1776 		UINT32 dst = READ32(ea);
1777 		UINT32 upper = LOAD_REG32(modrm);
1778 		UINT8 shift = REG8(CL);
1779 		if( shift > 31 || shift == 0 ) {
1780 
1781 		} else {
1782 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1783 			dst = (dst >> shift) | (upper << (32-shift));
1784 			SetSZPF32(dst);
1785 		}
1786 		WRITE32(ea, dst);
1787 		CYCLES(CYCLES_SHRD_MEM);
1788 	}
1789 }
1790 
I386OP(stosd)1791 static void I386OP(stosd)(void)				// Opcode 0xab
1792 {
1793 	UINT32 eas = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1794 	WRITE32(eas, REG32(EAX));
1795 	BUMP_DI(4);
1796 	CYCLES(CYCLES_STOS);
1797 }
1798 
I386OP(sub_rm32_r32)1799 static void I386OP(sub_rm32_r32)(void)		// Opcode 0x29
1800 {
1801 	UINT32 src, dst;
1802 	UINT8 modrm = FETCH();
1803 	if( modrm >= 0xc0 ) {
1804 		src = LOAD_REG32(modrm);
1805 		dst = LOAD_RM32(modrm);
1806 		dst = SUB32(dst, src);
1807 		STORE_RM32(modrm, dst);
1808 		CYCLES(CYCLES_ALU_REG_REG);
1809 	} else {
1810 		UINT32 ea = GetEA(modrm);
1811 		src = LOAD_REG32(modrm);
1812 		dst = READ32(ea);
1813 		dst = SUB32(dst, src);
1814 		WRITE32(ea, dst);
1815 		CYCLES(CYCLES_ALU_REG_MEM);
1816 	}
1817 }
1818 
I386OP(sub_r32_rm32)1819 static void I386OP(sub_r32_rm32)(void)		// Opcode 0x2b
1820 {
1821 	UINT32 src, dst;
1822 	UINT8 modrm = FETCH();
1823 	if( modrm >= 0xc0 ) {
1824 		src = LOAD_RM32(modrm);
1825 		dst = LOAD_REG32(modrm);
1826 		dst = SUB32(dst, src);
1827 		STORE_REG32(modrm, dst);
1828 		CYCLES(CYCLES_ALU_REG_REG);
1829 	} else {
1830 		UINT32 ea = GetEA(modrm);
1831 		src = READ32(ea);
1832 		dst = LOAD_REG32(modrm);
1833 		dst = SUB32(dst, src);
1834 		STORE_REG32(modrm, dst);
1835 		CYCLES(CYCLES_ALU_MEM_REG);
1836 	}
1837 }
1838 
I386OP(sub_eax_i32)1839 static void I386OP(sub_eax_i32)(void)		// Opcode 0x2d
1840 {
1841 	UINT32 src, dst;
1842 	src = FETCH32();
1843 	dst = REG32(EAX);
1844 	dst = SUB32(dst, src);
1845 	REG32(EAX) = dst;
1846 	CYCLES(CYCLES_ALU_IMM_ACC);
1847 }
1848 
I386OP(test_eax_i32)1849 static void I386OP(test_eax_i32)(void)		// Opcode 0xa9
1850 {
1851 	UINT32 src = FETCH32();
1852 	UINT32 dst = REG32(EAX);
1853 	dst = src & dst;
1854 	SetSZPF32(dst);
1855 	I.CF = 0;
1856 	I.OF = 0;
1857 	CYCLES(CYCLES_TEST_IMM_ACC);
1858 }
1859 
I386OP(test_rm32_r32)1860 static void I386OP(test_rm32_r32)(void)		// Opcode 0x85
1861 {
1862 	UINT32 src, dst;
1863 	UINT8 modrm = FETCH();
1864 	if( modrm >= 0xc0 ) {
1865 		src = LOAD_REG32(modrm);
1866 		dst = LOAD_RM32(modrm);
1867 		dst = src & dst;
1868 		SetSZPF32(dst);
1869 		I.CF = 0;
1870 		I.OF = 0;
1871 		CYCLES(CYCLES_TEST_REG_REG);
1872 	} else {
1873 		UINT32 ea = GetEA(modrm);
1874 		src = LOAD_REG32(modrm);
1875 		dst = READ32(ea);
1876 		dst = src & dst;
1877 		SetSZPF32(dst);
1878 		I.CF = 0;
1879 		I.OF = 0;
1880 		CYCLES(CYCLES_TEST_REG_MEM);
1881 	}
1882 }
1883 
I386OP(xchg_eax_ecx)1884 static void I386OP(xchg_eax_ecx)(void)		// Opcode 0x91
1885 {
1886 	UINT32 temp;
1887 	temp = REG32(EAX);
1888 	REG32(EAX) = REG32(ECX);
1889 	REG32(ECX) = temp;
1890 	CYCLES(CYCLES_XCHG_REG_REG);
1891 }
1892 
I386OP(xchg_eax_edx)1893 static void I386OP(xchg_eax_edx)(void)		// Opcode 0x92
1894 {
1895 	UINT32 temp;
1896 	temp = REG32(EAX);
1897 	REG32(EAX) = REG32(EDX);
1898 	REG32(EDX) = temp;
1899 	CYCLES(CYCLES_XCHG_REG_REG);
1900 }
1901 
I386OP(xchg_eax_ebx)1902 static void I386OP(xchg_eax_ebx)(void)		// Opcode 0x93
1903 {
1904 	UINT32 temp;
1905 	temp = REG32(EAX);
1906 	REG32(EAX) = REG32(EBX);
1907 	REG32(EBX) = temp;
1908 	CYCLES(CYCLES_XCHG_REG_REG);
1909 }
1910 
I386OP(xchg_eax_esp)1911 static void I386OP(xchg_eax_esp)(void)		// Opcode 0x94
1912 {
1913 	UINT32 temp;
1914 	temp = REG32(EAX);
1915 	REG32(EAX) = REG32(ESP);
1916 	REG32(ESP) = temp;
1917 	CYCLES(CYCLES_XCHG_REG_REG);
1918 }
1919 
I386OP(xchg_eax_ebp)1920 static void I386OP(xchg_eax_ebp)(void)		// Opcode 0x95
1921 {
1922 	UINT32 temp;
1923 	temp = REG32(EAX);
1924 	REG32(EAX) = REG32(EBP);
1925 	REG32(EBP) = temp;
1926 	CYCLES(CYCLES_XCHG_REG_REG);
1927 }
1928 
I386OP(xchg_eax_esi)1929 static void I386OP(xchg_eax_esi)(void)		// Opcode 0x96
1930 {
1931 	UINT32 temp;
1932 	temp = REG32(EAX);
1933 	REG32(EAX) = REG32(ESI);
1934 	REG32(ESI) = temp;
1935 	CYCLES(CYCLES_XCHG_REG_REG);
1936 }
1937 
I386OP(xchg_eax_edi)1938 static void I386OP(xchg_eax_edi)(void)		// Opcode 0x97
1939 {
1940 	UINT32 temp;
1941 	temp = REG32(EAX);
1942 	REG32(EAX) = REG32(EDI);
1943 	REG32(EDI) = temp;
1944 	CYCLES(CYCLES_XCHG_REG_REG);
1945 }
1946 
I386OP(xchg_r32_rm32)1947 static void I386OP(xchg_r32_rm32)(void)		// Opcode 0x87
1948 {
1949 	UINT8 modrm = FETCH();
1950 	if( modrm >= 0xc0 ) {
1951 		UINT32 src = LOAD_RM32(modrm);
1952 		UINT32 dst = LOAD_REG32(modrm);
1953 		STORE_REG32(modrm, src);
1954 		STORE_RM32(modrm, dst);
1955 		CYCLES(CYCLES_XCHG_REG_REG);
1956 	} else {
1957 		UINT32 ea = GetEA(modrm);
1958 		UINT32 src = READ32(ea);
1959 		UINT32 dst = LOAD_REG32(modrm);
1960 		STORE_REG32(modrm, src);
1961 		WRITE32(ea, dst);
1962 		CYCLES(CYCLES_XCHG_REG_MEM);
1963 	}
1964 }
1965 
I386OP(xor_rm32_r32)1966 static void I386OP(xor_rm32_r32)(void)		// Opcode 0x31
1967 {
1968 	UINT32 src, dst;
1969 	UINT8 modrm = FETCH();
1970 	if( modrm >= 0xc0 ) {
1971 		src = LOAD_REG32(modrm);
1972 		dst = LOAD_RM32(modrm);
1973 		dst = XOR32(dst, src);
1974 		STORE_RM32(modrm, dst);
1975 		CYCLES(CYCLES_ALU_REG_REG);
1976 	} else {
1977 		UINT32 ea = GetEA(modrm);
1978 		src = LOAD_REG32(modrm);
1979 		dst = READ32(ea);
1980 		dst = XOR32(dst, src);
1981 		WRITE32(ea, dst);
1982 		CYCLES(CYCLES_ALU_REG_MEM);
1983 	}
1984 }
1985 
I386OP(xor_r32_rm32)1986 static void I386OP(xor_r32_rm32)(void)		// Opcode 0x33
1987 {
1988 	UINT32 src, dst;
1989 	UINT8 modrm = FETCH();
1990 	if( modrm >= 0xc0 ) {
1991 		src = LOAD_RM32(modrm);
1992 		dst = LOAD_REG32(modrm);
1993 		dst = XOR32(dst, src);
1994 		STORE_REG32(modrm, dst);
1995 		CYCLES(CYCLES_ALU_REG_REG);
1996 	} else {
1997 		UINT32 ea = GetEA(modrm);
1998 		src = READ32(ea);
1999 		dst = LOAD_REG32(modrm);
2000 		dst = XOR32(dst, src);
2001 		STORE_REG32(modrm, dst);
2002 		CYCLES(CYCLES_ALU_MEM_REG);
2003 	}
2004 }
2005 
I386OP(xor_eax_i32)2006 static void I386OP(xor_eax_i32)(void)		// Opcode 0x35
2007 {
2008 	UINT32 src, dst;
2009 	src = FETCH32();
2010 	dst = REG32(EAX);
2011 	dst = XOR32(dst, src);
2012 	REG32(EAX) = dst;
2013 	CYCLES(CYCLES_ALU_IMM_ACC);
2014 }
2015 
2016 
2017 
I386OP(group81_32)2018 static void I386OP(group81_32)(void)		// Opcode 0x81
2019 {
2020 	UINT32 ea;
2021 	UINT32 src, dst;
2022 	UINT8 modrm = FETCH();
2023 
2024 	switch( (modrm >> 3) & 0x7 )
2025 	{
2026 		case 0:		// ADD Rm32, i32
2027 			if( modrm >= 0xc0 ) {
2028 				dst = LOAD_RM32(modrm);
2029 				src = FETCH32();
2030 				dst = ADD32(dst, src);
2031 				STORE_RM32(modrm, dst);
2032 				CYCLES(CYCLES_ALU_REG_REG);
2033 			} else {
2034 				ea = GetEA(modrm);
2035 				dst = READ32(ea);
2036 				src = FETCH32();
2037 				dst = ADD32(dst, src);
2038 				WRITE32(ea, dst);
2039 				CYCLES(CYCLES_ALU_REG_MEM);
2040 			}
2041 			break;
2042 		case 1:		// OR Rm32, i32
2043 			if( modrm >= 0xc0 ) {
2044 				dst = LOAD_RM32(modrm);
2045 				src = FETCH32();
2046 				dst = OR32(dst, src);
2047 				STORE_RM32(modrm, dst);
2048 				CYCLES(CYCLES_ALU_REG_REG);
2049 			} else {
2050 				ea = GetEA(modrm);
2051 				dst = READ32(ea);
2052 				src = FETCH32();
2053 				dst = OR32(dst, src);
2054 				WRITE32(ea, dst);
2055 				CYCLES(CYCLES_ALU_REG_MEM);
2056 			}
2057 			break;
2058 		case 2:		// ADC Rm32, i32
2059 			if( modrm >= 0xc0 ) {
2060 				dst = LOAD_RM32(modrm);
2061 				src = FETCH32();
2062 				src = ADD32(src, I.CF);
2063 				dst = ADD32(dst, src);
2064 				STORE_RM32(modrm, dst);
2065 				CYCLES(CYCLES_ALU_REG_REG);
2066 			} else {
2067 				ea = GetEA(modrm);
2068 				dst = READ32(ea);
2069 				src = FETCH32();
2070 				src = ADD32(src, I.CF);
2071 				dst = ADD32(dst, src);
2072 				WRITE32(ea, dst);
2073 				CYCLES(CYCLES_ALU_REG_MEM);
2074 			}
2075 			break;
2076 		case 3:		// SBB Rm32, i32
2077 			if( modrm >= 0xc0 ) {
2078 				dst = LOAD_RM32(modrm);
2079 				src = FETCH32() + I.CF;
2080 				dst = SUB32(dst, src);
2081 				STORE_RM32(modrm, dst);
2082 				CYCLES(CYCLES_ALU_REG_REG);
2083 			} else {
2084 				ea = GetEA(modrm);
2085 				dst = READ32(ea);
2086 				src = FETCH32() + I.CF;
2087 				dst = SUB32(dst, src);
2088 				WRITE32(ea, dst);
2089 				CYCLES(CYCLES_ALU_REG_MEM);
2090 			}
2091 			break;
2092 		case 4:		// AND Rm32, i32
2093 			if( modrm >= 0xc0 ) {
2094 				dst = LOAD_RM32(modrm);
2095 				src = FETCH32();
2096 				dst = AND32(dst, src);
2097 				STORE_RM32(modrm, dst);
2098 				CYCLES(CYCLES_ALU_REG_REG);
2099 			} else {
2100 				ea = GetEA(modrm);
2101 				dst = READ32(ea);
2102 				src = FETCH32();
2103 				dst = AND32(dst, src);
2104 				WRITE32(ea, dst);
2105 				CYCLES(CYCLES_ALU_REG_MEM);
2106 			}
2107 			break;
2108 		case 5:		// SUB Rm32, i32
2109 			if( modrm >= 0xc0 ) {
2110 				dst = LOAD_RM32(modrm);
2111 				src = FETCH32();
2112 				dst = SUB32(dst, src);
2113 				STORE_RM32(modrm, dst);
2114 				CYCLES(CYCLES_ALU_REG_REG);
2115 			} else {
2116 				ea = GetEA(modrm);
2117 				dst = READ32(ea);
2118 				src = FETCH32();
2119 				dst = SUB32(dst, src);
2120 				WRITE32(ea, dst);
2121 				CYCLES(CYCLES_ALU_REG_MEM);
2122 			}
2123 			break;
2124 		case 6:		// XOR Rm32, i32
2125 			if( modrm >= 0xc0 ) {
2126 				dst = LOAD_RM32(modrm);
2127 				src = FETCH32();
2128 				dst = XOR32(dst, src);
2129 				STORE_RM32(modrm, dst);
2130 				CYCLES(CYCLES_ALU_REG_REG);
2131 			} else {
2132 				ea = GetEA(modrm);
2133 				dst = READ32(ea);
2134 				src = FETCH32();
2135 				dst = XOR32(dst, src);
2136 				WRITE32(ea, dst);
2137 				CYCLES(CYCLES_ALU_REG_MEM);
2138 			}
2139 			break;
2140 		case 7:		// CMP Rm32, i32
2141 			if( modrm >= 0xc0 ) {
2142 				dst = LOAD_RM32(modrm);
2143 				src = FETCH32();
2144 				SUB32(dst, src);
2145 				CYCLES(CYCLES_CMP_REG_REG);
2146 			} else {
2147 				ea = GetEA(modrm);
2148 				dst = READ32(ea);
2149 				src = FETCH32();
2150 				SUB32(dst, src);
2151 				CYCLES(CYCLES_CMP_REG_MEM);
2152 			}
2153 			break;
2154 	}
2155 }
2156 
I386OP(group83_32)2157 static void I386OP(group83_32)(void)		// Opcode 0x83
2158 {
2159 	UINT32 ea;
2160 	UINT32 src, dst;
2161 	UINT8 modrm = FETCH();
2162 
2163 	switch( (modrm >> 3) & 0x7 )
2164 	{
2165 		case 0:		// ADD Rm32, i32
2166 			if( modrm >= 0xc0 ) {
2167 				dst = LOAD_RM32(modrm);
2168 				src = (UINT32)(INT32)(INT8)FETCH();
2169 				dst = ADD32(dst, src);
2170 				STORE_RM32(modrm, dst);
2171 				CYCLES(CYCLES_ALU_REG_REG);
2172 			} else {
2173 				ea = GetEA(modrm);
2174 				dst = READ32(ea);
2175 				src = (UINT32)(INT32)(INT8)FETCH();
2176 				dst = ADD32(dst, src);
2177 				WRITE32(ea, dst);
2178 				CYCLES(CYCLES_ALU_REG_MEM);
2179 			}
2180 			break;
2181 		case 1:		// OR Rm32, i32
2182 			if( modrm >= 0xc0 ) {
2183 				dst = LOAD_RM32(modrm);
2184 				src = (UINT32)(INT32)(INT8)FETCH();
2185 				dst = OR32(dst, src);
2186 				STORE_RM32(modrm, dst);
2187 				CYCLES(CYCLES_ALU_REG_REG);
2188 			} else {
2189 				ea = GetEA(modrm);
2190 				dst = READ32(ea);
2191 				src = (UINT32)(INT32)(INT8)FETCH();
2192 				dst = OR32(dst, src);
2193 				WRITE32(ea, dst);
2194 				CYCLES(CYCLES_ALU_REG_MEM);
2195 			}
2196 			break;
2197 		case 2:		// ADC Rm32, i32
2198 			if( modrm >= 0xc0 ) {
2199 				dst = LOAD_RM32(modrm);
2200 				src = (UINT32)(INT32)(INT8)FETCH();
2201 				src = ADD32(src, I.CF);
2202 				dst = ADD32(dst, src);
2203 				STORE_RM32(modrm, dst);
2204 				CYCLES(CYCLES_ALU_REG_REG);
2205 			} else {
2206 				ea = GetEA(modrm);
2207 				dst = READ32(ea);
2208 				src = (UINT32)(INT32)(INT8)FETCH();
2209 				src = ADD32(src, I.CF);
2210 				dst = ADD32(dst, src);
2211 				WRITE32(ea, dst);
2212 				CYCLES(CYCLES_ALU_REG_MEM);
2213 			}
2214 			break;
2215 		case 3:		// SBB Rm32, i32
2216 			if( modrm >= 0xc0 ) {
2217 				dst = LOAD_RM32(modrm);
2218 				src = ((UINT32)(INT32)(INT8)FETCH()) + I.CF;
2219 				dst = SUB32(dst, src);
2220 				STORE_RM32(modrm, dst);
2221 				CYCLES(CYCLES_ALU_REG_REG);
2222 			} else {
2223 				ea = GetEA(modrm);
2224 				dst = READ32(ea);
2225 				src = ((UINT32)(INT32)(INT8)FETCH()) + I.CF;
2226 				dst = SUB32(dst, src);
2227 				WRITE32(ea, dst);
2228 				CYCLES(CYCLES_ALU_REG_MEM);
2229 			}
2230 			break;
2231 		case 4:		// AND Rm32, i32
2232 			if( modrm >= 0xc0 ) {
2233 				dst = LOAD_RM32(modrm);
2234 				src = (UINT32)(INT32)(INT8)FETCH();
2235 				dst = AND32(dst, src);
2236 				STORE_RM32(modrm, dst);
2237 				CYCLES(CYCLES_ALU_REG_REG);
2238 			} else {
2239 				ea = GetEA(modrm);
2240 				dst = READ32(ea);
2241 				src = (UINT32)(INT32)(INT8)FETCH();
2242 				dst = AND32(dst, src);
2243 				WRITE32(ea, dst);
2244 				CYCLES(CYCLES_ALU_REG_MEM);
2245 			}
2246 			break;
2247 		case 5:		// SUB Rm32, i32
2248 			if( modrm >= 0xc0 ) {
2249 				dst = LOAD_RM32(modrm);
2250 				src = (UINT32)(INT32)(INT8)FETCH();
2251 				dst = SUB32(dst, src);
2252 				STORE_RM32(modrm, dst);
2253 				CYCLES(CYCLES_ALU_REG_REG);
2254 			} else {
2255 				ea = GetEA(modrm);
2256 				dst = READ32(ea);
2257 				src = (UINT32)(INT32)(INT8)FETCH();
2258 				dst = SUB32(dst, src);
2259 				WRITE32(ea, dst);
2260 				CYCLES(CYCLES_ALU_REG_MEM);
2261 			}
2262 			break;
2263 		case 6:		// XOR Rm32, i32
2264 			if( modrm >= 0xc0 ) {
2265 				dst = LOAD_RM32(modrm);
2266 				src = (UINT32)(INT32)(INT8)FETCH();
2267 				dst = XOR32(dst, src);
2268 				STORE_RM32(modrm, dst);
2269 				CYCLES(CYCLES_ALU_REG_REG);
2270 			} else {
2271 				ea = GetEA(modrm);
2272 				dst = READ32(ea);
2273 				src = (UINT32)(INT32)(INT8)FETCH();
2274 				dst = XOR32(dst, src);
2275 				WRITE32(ea, dst);
2276 				CYCLES(CYCLES_ALU_REG_MEM);
2277 			}
2278 			break;
2279 		case 7:		// CMP Rm32, i32
2280 			if( modrm >= 0xc0 ) {
2281 				dst = LOAD_RM32(modrm);
2282 				src = (UINT32)(INT32)(INT8)FETCH();
2283 				SUB32(dst, src);
2284 				CYCLES(CYCLES_CMP_REG_REG);
2285 			} else {
2286 				ea = GetEA(modrm);
2287 				dst = READ32(ea);
2288 				src = (UINT32)(INT32)(INT8)FETCH();
2289 				SUB32(dst, src);
2290 				CYCLES(CYCLES_CMP_REG_MEM);
2291 			}
2292 			break;
2293 	}
2294 }
2295 
I386OP(groupC1_32)2296 static void I386OP(groupC1_32)(void)		// Opcode 0xc1
2297 {
2298 	UINT32 dst;
2299 	UINT8 modrm = FETCH();
2300 	UINT8 shift;
2301 
2302 	if( modrm >= 0xc0 ) {
2303 		dst = LOAD_RM32(modrm);
2304 		shift = FETCH() & 0x1f;
2305 		dst = i386_shift_rotate32(modrm, dst, shift);
2306 		STORE_RM32(modrm, dst);
2307 	} else {
2308 		UINT32 ea = GetEA(modrm);
2309 		dst = READ32(ea);
2310 		shift = FETCH() & 0x1f;
2311 		dst = i386_shift_rotate32(modrm, dst, shift);
2312 		WRITE32(ea, dst);
2313 	}
2314 }
2315 
I386OP(groupD1_32)2316 static void I386OP(groupD1_32)(void)		// Opcode 0xd1
2317 {
2318 	UINT32 dst;
2319 	UINT8 modrm = FETCH();
2320 
2321 	if( modrm >= 0xc0 ) {
2322 		dst = LOAD_RM32(modrm);
2323 		dst = i386_shift_rotate32(modrm, dst, 1);
2324 		STORE_RM32(modrm, dst);
2325 	} else {
2326 		UINT32 ea = GetEA(modrm);
2327 		dst = READ32(ea);
2328 		dst = i386_shift_rotate32(modrm, dst, 1);
2329 		WRITE32(ea, dst);
2330 	}
2331 }
2332 
I386OP(groupD3_32)2333 static void I386OP(groupD3_32)(void)		// Opcode 0xd3
2334 {
2335 	UINT32 dst;
2336 	UINT8 modrm = FETCH();
2337 
2338 	if( modrm >= 0xc0 ) {
2339 		dst = LOAD_RM32(modrm);
2340 		dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2341 		STORE_RM32(modrm, dst);
2342 	} else {
2343 		UINT32 ea = GetEA(modrm);
2344 		dst = READ32(ea);
2345 		dst = i386_shift_rotate32(modrm, dst, REG8(CL));
2346 		WRITE32(ea, dst);
2347 	}
2348 }
2349 
I386OP(groupF7_32)2350 static void I386OP(groupF7_32)(void)		// Opcode 0xf7
2351 {
2352 	UINT8 modrm = FETCH();
2353 
2354 	switch( (modrm >> 3) & 0x7 )
2355 	{
2356 		case 0:			/* TEST Rm32, i32 */
2357 			if( modrm >= 0xc0 ) {
2358 				UINT32 dst = LOAD_RM32(modrm);
2359 				UINT32 src = FETCH32();
2360 				dst &= src;
2361 				I.CF = I.OF = I.AF = 0;
2362 				SetSZPF32(dst);
2363 				CYCLES(CYCLES_TEST_IMM_REG);
2364 			} else {
2365 				UINT32 ea = GetEA(modrm);
2366 				UINT32 dst = READ32(ea);
2367 				UINT32 src = FETCH32();
2368 				dst &= src;
2369 				I.CF = I.OF = I.AF = 0;
2370 				SetSZPF32(dst);
2371 				CYCLES(CYCLES_TEST_IMM_MEM);
2372 			}
2373 			break;
2374 		case 2:			/* NOT Rm32 */
2375 			if( modrm >= 0xc0 ) {
2376 				UINT32 dst = LOAD_RM32(modrm);
2377 				dst = ~dst;
2378 				STORE_RM32(modrm, dst);
2379 				CYCLES(CYCLES_NOT_REG);
2380 			} else {
2381 				UINT32 ea = GetEA(modrm);
2382 				UINT32 dst = READ32(ea);
2383 				dst = ~dst;
2384 				WRITE32(ea, dst);
2385 				CYCLES(CYCLES_NOT_MEM);
2386 			}
2387 			break;
2388 		case 3:			/* NEG Rm32 */
2389 			if( modrm >= 0xc0 ) {
2390 				UINT32 dst = LOAD_RM32(modrm);
2391 				dst = SUB32( 0, dst );
2392 				STORE_RM32(modrm, dst);
2393 				CYCLES(CYCLES_NEG_REG);
2394 			} else {
2395 				UINT32 ea = GetEA(modrm);
2396 				UINT32 dst = READ32(ea);
2397 				dst = SUB32( 0, dst );
2398 				WRITE32(ea, dst);
2399 				CYCLES(CYCLES_NEG_MEM);
2400 			}
2401 			break;
2402 		case 4:			/* MUL EAX, Rm32 */
2403 			{
2404 				UINT64 result;
2405 				UINT32 src, dst;
2406 				if( modrm >= 0xc0 ) {
2407 					src = LOAD_RM32(modrm);
2408 					CYCLES(CYCLES_MUL32_ACC_REG);		/* TODO: Correct multiply timing */
2409 				} else {
2410 					UINT32 ea = GetEA(modrm);
2411 					src = READ32(ea);
2412 					CYCLES(CYCLES_MUL32_ACC_MEM);		/* TODO: Correct multiply timing */
2413 				}
2414 
2415 				dst = REG32(EAX);
2416 				result = (UINT64)src * (UINT64)dst;
2417 				REG32(EDX) = (UINT32)(result >> 32);
2418 				REG32(EAX) = (UINT32)result;
2419 
2420 				I.CF = I.OF = (REG32(EDX) != 0);
2421 			}
2422 			break;
2423 		case 5:			/* IMUL EAX, Rm32 */
2424 			{
2425 				INT64 result;
2426 				INT64 src, dst;
2427 				if( modrm >= 0xc0 ) {
2428 					src = (INT64)(INT32)LOAD_RM32(modrm);
2429 					CYCLES(CYCLES_IMUL32_ACC_REG);		/* TODO: Correct multiply timing */
2430 				} else {
2431 					UINT32 ea = GetEA(modrm);
2432 					src = (INT64)(INT32)READ32(ea);
2433 					CYCLES(CYCLES_IMUL32_ACC_MEM);		/* TODO: Correct multiply timing */
2434 				}
2435 
2436 				dst = (INT64)(INT32)REG32(EAX);
2437 				result = src * dst;
2438 
2439 				REG32(EDX) = (UINT32)(result >> 32);
2440 				REG32(EAX) = (UINT32)result;
2441 
2442 				I.CF = I.OF = !(result == (INT64)(INT32)result);
2443 			}
2444 			break;
2445 		case 6:			/* DIV EAX, Rm32 */
2446 			{
2447 				UINT64 quotient, remainder, result;
2448 				UINT32 src;
2449 				if( modrm >= 0xc0 ) {
2450 					src = LOAD_RM32(modrm);
2451 					CYCLES(CYCLES_DIV32_ACC_REG);
2452 				} else {
2453 					UINT32 ea = GetEA(modrm);
2454 					src = READ32(ea);
2455 					CYCLES(CYCLES_DIV32_ACC_MEM);
2456 				}
2457 
2458 				quotient = ((UINT64)(REG32(EDX)) << 32) | (UINT64)(REG32(EAX));
2459 				if( src ) {
2460 					remainder = quotient % (UINT64)src;
2461 					result = quotient / (UINT64)src;
2462 					if( result > 0xffffffff ) {
2463 						/* TODO: Divide error */
2464 					} else {
2465 						REG32(EDX) = (UINT32)remainder;
2466 						REG32(EAX) = (UINT32)result;
2467 					}
2468 				} else {
2469 					/* TODO: Divide by zero */
2470 				}
2471 			}
2472 			break;
2473 		case 7:			/* IDIV EAX, Rm32 */
2474 			{
2475 				INT64 quotient, remainder, result;
2476 				UINT32 src;
2477 				if( modrm >= 0xc0 ) {
2478 					src = LOAD_RM32(modrm);
2479 					CYCLES(CYCLES_IDIV32_ACC_REG);
2480 				} else {
2481 					UINT32 ea = GetEA(modrm);
2482 					src = READ32(ea);
2483 					CYCLES(CYCLES_IDIV32_ACC_MEM);
2484 				}
2485 
2486 				quotient = (((INT64)REG32(EDX)) << 32) | ((UINT64)REG32(EAX));
2487 				if( src ) {
2488 					remainder = quotient % (INT64)(INT32)src;
2489 					result = quotient / (INT64)(INT32)src;
2490 					if( result > 0xffffffff ) {
2491 						/* TODO: Divide error */
2492 					} else {
2493 						REG32(EDX) = (UINT32)remainder;
2494 						REG32(EAX) = (UINT32)result;
2495 					}
2496 				} else {
2497 					/* TODO: Divide by zero */
2498 				}
2499 			}
2500 			break;
2501 	}
2502 }
2503 
I386OP(groupFF_32)2504 static void I386OP(groupFF_32)(void)		// Opcode 0xff
2505 {
2506 	UINT8 modrm = FETCH();
2507 
2508 	switch( (modrm >> 3) & 0x7 )
2509 	{
2510 		case 0:			/* INC Rm32 */
2511 			if( modrm >= 0xc0 ) {
2512 				UINT32 dst = LOAD_RM32(modrm);
2513 				dst = INC32(dst);
2514 				STORE_RM32(modrm, dst);
2515 				CYCLES(CYCLES_INC_REG);
2516 			} else {
2517 				UINT32 ea = GetEA(modrm);
2518 				UINT32 dst = READ32(ea);
2519 				dst = INC32(dst);
2520 				WRITE32(ea, dst);
2521 				CYCLES(CYCLES_INC_MEM);
2522 			}
2523 			break;
2524 		case 1:			/* DEC Rm32 */
2525 			if( modrm >= 0xc0 ) {
2526 				UINT32 dst = LOAD_RM32(modrm);
2527 				dst = DEC32(dst);
2528 				STORE_RM32(modrm, dst);
2529 				CYCLES(CYCLES_DEC_REG);
2530 			} else {
2531 				UINT32 ea = GetEA(modrm);
2532 				UINT32 dst = READ32(ea);
2533 				dst = DEC32(dst);
2534 				WRITE32(ea, dst);
2535 				CYCLES(CYCLES_DEC_MEM);
2536 			}
2537 			break;
2538 		case 2:			/* CALL Rm32 */
2539 			{
2540 				UINT32 address;
2541 				if( modrm >= 0xc0 ) {
2542 					address = LOAD_RM32(modrm);
2543 					CYCLES(CYCLES_CALL_REG);		/* TODO: Timing = 7 + m */
2544 				} else {
2545 					UINT32 ea = GetEA(modrm);
2546 					address = READ32(ea);
2547 					CYCLES(CYCLES_CALL_MEM);		/* TODO: Timing = 10 + m */
2548 				}
2549 				PUSH32( I.eip );
2550 				I.eip = address;
2551 				CHANGE_PC(I.eip);
2552 			}
2553 			break;
2554 		case 3:			/* CALL FAR Rm32 */
2555 			{
2556 				UINT16 selector = 0;
2557 				UINT32 address = 0;
2558 				if( modrm >= 0xc0 ) {
2559 				//	osd_die("NYI");
2560 				} else {
2561 					UINT32 ea = GetEA(modrm);
2562 					address = READ32(ea + 0);
2563 					selector = READ16(ea + 4);
2564 					CYCLES(CYCLES_CALL_MEM_INTERSEG);		/* TODO: Timing = 10 + m */
2565 				}
2566 				PUSH32( I.sreg[CS].selector );
2567 				PUSH32( I.eip );
2568 				I.sreg[CS].selector = selector;
2569 				I.performed_intersegment_jump = 1;
2570 				i386_load_segment_descriptor( CS );
2571 				I.eip = address;
2572 				CHANGE_PC(I.eip);
2573 			}
2574 			break;
2575 		case 4:			/* JMP Rm32 */
2576 			{
2577 				UINT32 address;
2578 				if( modrm >= 0xc0 ) {
2579 					address = LOAD_RM32(modrm);
2580 					CYCLES(CYCLES_JMP_REG);		/* TODO: Timing = 7 + m */
2581 				} else {
2582 					UINT32 ea = GetEA(modrm);
2583 					address = READ32(ea);
2584 					CYCLES(CYCLES_JMP_MEM);		/* TODO: Timing = 10 + m */
2585 				}
2586 				I.eip = address;
2587 				CHANGE_PC(I.eip);
2588 			}
2589 			break;
2590 		case 5:			/* JMP FAR Rm32 */
2591 			{
2592 				UINT16 selector = 0;
2593 				UINT32 address = 0;
2594 				if( modrm >= 0xc0 ) {
2595 				//	osd_die("NYI");
2596 				} else {
2597 					UINT32 ea = GetEA(modrm);
2598 					address = READ32(ea + 0);
2599 					selector = READ16(ea + 4);
2600 					CYCLES(CYCLES_JMP_MEM_INTERSEG);		/* TODO: Timing = 10 + m */
2601 				}
2602 				I.sreg[CS].selector = selector;
2603 				I.performed_intersegment_jump = 1;
2604 				i386_load_segment_descriptor( CS );
2605 				I.eip = address;
2606 				CHANGE_PC(I.eip);
2607 			}
2608 			break;
2609 		case 6:			/* PUSH Rm32 */
2610 			{
2611 				UINT32 value;
2612 				if( modrm >= 0xc0 ) {
2613 					value = LOAD_RM32(modrm);
2614 				} else {
2615 					UINT32 ea = GetEA(modrm);
2616 					value = READ32(ea);
2617 				}
2618 				PUSH32(value);
2619 				CYCLES(CYCLES_PUSH_RM);
2620 			}
2621 			break;
2622 		default:
2623 		//	osd_die("i386: groupFF_32 /%d unimplemented at %08X\n", (modrm >> 3) & 0x7, I.pc-2);
2624 			break;
2625 	}
2626 }
2627 
I386OP(group0F00_32)2628 static void I386OP(group0F00_32)(void)			// Opcode 0x0f 00
2629 {
2630 	UINT32 address, ea;
2631 	UINT8 modrm = FETCH();
2632 
2633 	switch( (modrm >> 3) & 0x7 )
2634 	{
2635 		case 2:			/* LLDT */
2636 			if ( PROTECTED_MODE && !V8086_MODE )
2637 			{
2638 				if( modrm >= 0xc0 ) {
2639 					address = LOAD_RM32(modrm);
2640 					ea = i386_translate( CS, address );
2641 					CYCLES(CYCLES_LLDT_REG);
2642 				} else {
2643 					ea = GetEA(modrm);
2644 					CYCLES(CYCLES_LLDT_MEM);
2645 				}
2646 				I.ldtr.segment = READ32(ea);
2647 			}
2648 			else
2649 			{
2650 				i386_trap(6, 0);
2651 			}
2652 			break;
2653 
2654 		case 3:			/* LTR */
2655 			if ( PROTECTED_MODE && !V8086_MODE )
2656 			{
2657 				if( modrm >= 0xc0 ) {
2658 					address = LOAD_RM32(modrm);
2659 					ea = i386_translate( CS, address );
2660 					CYCLES(CYCLES_LTR_REG);
2661 				} else {
2662 					ea = GetEA(modrm);
2663 					CYCLES(CYCLES_LTR_MEM);
2664 				}
2665 				I.task.segment = READ32(ea);
2666 			}
2667 			else
2668 			{
2669 				i386_trap(6, 0);
2670 			}
2671 			break;
2672 
2673 		default:
2674 		//	osd_die("i386: group0F00_32 /%d unimplemented\n", (modrm >> 3) & 0x7);
2675 			break;
2676 	}
2677 }
2678 
I386OP(group0F01_32)2679 static void I386OP(group0F01_32)(void)		// Opcode 0x0f 01
2680 {
2681 	UINT8 modrm = FETCH();
2682 	UINT32 address, ea;
2683 
2684 	switch( (modrm >> 3) & 0x7 )
2685 	{
2686 		case 0:			/* SGDT */
2687 			{
2688 				if( modrm >= 0xc0 ) {
2689 					address = LOAD_RM32(modrm);
2690 					ea = i386_translate( CS, address );
2691 				} else {
2692 					ea = GetEA(modrm);
2693 				}
2694 				WRITE16(ea, I.gdtr.limit);
2695 				WRITE32(ea + 2, I.gdtr.base);
2696 				CYCLES(CYCLES_SGDT);
2697 				break;
2698 			}
2699 		case 1:			/* SIDT */
2700 			{
2701 				if (modrm >= 0xc0)
2702 				{
2703 					address = LOAD_RM32(modrm);
2704 					ea = i386_translate( CS, address );
2705 				}
2706 				else
2707 				{
2708 					ea = GetEA(modrm);
2709 				}
2710 				WRITE16(ea, I.idtr.limit);
2711 				WRITE32(ea + 2, I.idtr.base);
2712 				CYCLES(CYCLES_SIDT);
2713 				break;
2714 			}
2715 		case 2:			/* LGDT */
2716 			{
2717 				if( modrm >= 0xc0 ) {
2718 					address = LOAD_RM32(modrm);
2719 					ea = i386_translate( CS, address );
2720 				} else {
2721 					ea = GetEA(modrm);
2722 				}
2723 				I.gdtr.limit = READ16(ea);
2724 				I.gdtr.base = READ32(ea + 2);
2725 				CYCLES(CYCLES_LGDT);
2726 				break;
2727 			}
2728 		case 3:			/* LIDT */
2729 			{
2730 				if( modrm >= 0xc0 ) {
2731 					address = LOAD_RM32(modrm);
2732 					ea = i386_translate( CS, address );
2733 				} else {
2734 					ea = GetEA(modrm);
2735 				}
2736 				I.idtr.limit = READ16(ea);
2737 				I.idtr.base = READ32(ea + 2);
2738 				CYCLES(CYCLES_LIDT);
2739 				break;
2740 			}
2741 		default:
2742 		//	osd_die("i386: unimplemented opcode 0x0f 01 /%d at %08X\n", (modrm >> 3) & 0x7, I.eip - 2);
2743 			break;
2744 	}
2745 }
2746 
I386OP(group0FBA_32)2747 static void I386OP(group0FBA_32)(void)		// Opcode 0x0f ba
2748 {
2749 	UINT8 modrm = FETCH();
2750 
2751 	switch( (modrm >> 3) & 0x7 )
2752 	{
2753 		case 4:			/* BT Rm32, i8 */
2754 			if( modrm >= 0xc0 ) {
2755 				UINT32 dst = LOAD_RM32(modrm);
2756 				UINT8 bit = FETCH();
2757 
2758 				if( dst & (1 << bit) )
2759 					I.CF = 1;
2760 				else
2761 					I.CF = 0;
2762 
2763 				CYCLES(CYCLES_BT_IMM_REG);
2764 			} else {
2765 				UINT32 ea = GetEA(modrm);
2766 				UINT32 dst = READ32(ea);
2767 				UINT8 bit = FETCH();
2768 
2769 				if( dst & (1 << bit) )
2770 					I.CF = 1;
2771 				else
2772 					I.CF = 0;
2773 
2774 				CYCLES(CYCLES_BT_IMM_MEM);
2775 			}
2776 			break;
2777 		case 5:			/* BTS Rm32, i8 */
2778 			if( modrm >= 0xc0 ) {
2779 				UINT32 dst = LOAD_RM32(modrm);
2780 				UINT8 bit = FETCH();
2781 
2782 				if( dst & (1 << bit) )
2783 					I.CF = 1;
2784 				else
2785 					I.CF = 0;
2786 				dst |= (1 << bit);
2787 
2788 				STORE_RM32(modrm, dst);
2789 				CYCLES(CYCLES_BTS_IMM_REG);
2790 			} else {
2791 				UINT32 ea = GetEA(modrm);
2792 				UINT32 dst = READ32(ea);
2793 				UINT8 bit = FETCH();
2794 
2795 				if( dst & (1 << bit) )
2796 					I.CF = 1;
2797 				else
2798 					I.CF = 0;
2799 				dst |= (1 << bit);
2800 
2801 				WRITE32(ea, dst);
2802 				CYCLES(CYCLES_BTS_IMM_MEM);
2803 			}
2804 			break;
2805 		case 6:			/* BTR Rm32, i8 */
2806 			if( modrm >= 0xc0 ) {
2807 				UINT32 dst = LOAD_RM32(modrm);
2808 				UINT8 bit = FETCH();
2809 
2810 				if( dst & (1 << bit) )
2811 					I.CF = 1;
2812 				else
2813 					I.CF = 0;
2814 				dst &= ~(1 << bit);
2815 
2816 				STORE_RM32(modrm, dst);
2817 				CYCLES(CYCLES_BTR_IMM_REG);
2818 			} else {
2819 				UINT32 ea = GetEA(modrm);
2820 				UINT32 dst = READ32(ea);
2821 				UINT8 bit = FETCH();
2822 
2823 				if( dst & (1 << bit) )
2824 					I.CF = 1;
2825 				else
2826 					I.CF = 0;
2827 				dst &= ~(1 << bit);
2828 
2829 				WRITE32(ea, dst);
2830 				CYCLES(CYCLES_BTR_IMM_MEM);
2831 			}
2832 			break;
2833 		case 7:			/* BTC Rm32, i8 */
2834 			if( modrm >= 0xc0 ) {
2835 				UINT32 dst = LOAD_RM32(modrm);
2836 				UINT8 bit = FETCH();
2837 
2838 				if( dst & (1 << bit) )
2839 					I.CF = 1;
2840 				else
2841 					I.CF = 0;
2842 				dst ^= (1 << bit);
2843 
2844 				STORE_RM32(modrm, dst);
2845 				CYCLES(CYCLES_BTC_IMM_REG);
2846 			} else {
2847 				UINT32 ea = GetEA(modrm);
2848 				UINT32 dst = READ32(ea);
2849 				UINT8 bit = FETCH();
2850 
2851 				if( dst & (1 << bit) )
2852 					I.CF = 1;
2853 				else
2854 					I.CF = 0;
2855 				dst ^= (1 << bit);
2856 
2857 				WRITE32(ea, dst);
2858 				CYCLES(CYCLES_BTC_IMM_MEM);
2859 			}
2860 			break;
2861 		default:
2862 		//	osd_die("i386: group0FBA_32 /%d unknown\n", (modrm >> 3) & 0x7);
2863 			break;
2864 	}
2865 }
2866 
I386OP(bound_r32_m32_m32)2867 static void I386OP(bound_r32_m32_m32)(void)	// Opcode 0x62
2868 {
2869 	UINT8 modrm;
2870 	INT32 val, low, high;
2871 
2872 	modrm = FETCH();
2873 
2874 	if (modrm >= 0xc0)
2875 	{
2876 		low = high = LOAD_RM32(modrm);
2877 	}
2878 	else
2879 	{
2880 		UINT32 ea = GetEA(modrm);
2881 		low = READ32(ea + 0);
2882 		high = READ32(ea + 4);
2883 	}
2884 	val = LOAD_REG32(modrm);
2885 
2886 	if ((val < low) || (val > high))
2887 	{
2888 		CYCLES(CYCLES_BOUND_OUT_RANGE);
2889 		i386_trap(5, 0);
2890 	}
2891 	else
2892 	{
2893 		CYCLES(CYCLES_BOUND_IN_RANGE);
2894 	}
2895 }
2896 
I386OP(retf32)2897 static void I386OP(retf32)(void)			// Opcode 0xcb
2898 {
2899 	I.eip = POP32();
2900 	I.sreg[CS].selector = POP32();
2901 	i386_load_segment_descriptor( CS );
2902 	CHANGE_PC(I.eip);
2903 
2904 	CYCLES(CYCLES_RET_INTERSEG);
2905 }
2906 
I386OP(retf_i32)2907 static void I386OP(retf_i32)(void)			// Opcode 0xca
2908 {
2909 	UINT16 count = FETCH16();
2910 
2911 	I.eip = POP32();
2912 	I.sreg[CS].selector = POP32();
2913 	i386_load_segment_descriptor( CS );
2914 	CHANGE_PC(I.eip);
2915 
2916 	REG32(ESP) += count;
2917 	CYCLES(CYCLES_RET_IMM_INTERSEG);
2918 }
2919 
I386OP(xlat32)2920 static void I386OP(xlat32)(void)			// Opcode 0xd7
2921 {
2922 	UINT32 ea;
2923 	if( I.segment_prefix ) {
2924 		ea = i386_translate( I.segment_override, REG32(EBX) + REG8(AL) );
2925 	} else {
2926 		ea = i386_translate( DS, REG32(EBX) + REG8(AL) );
2927 	}
2928 	REG8(AL) = READ8(ea);
2929 	CYCLES(CYCLES_XLAT);
2930 }
2931 
I386OP(load_far_pointer32)2932 static void I386OP(load_far_pointer32)(int s)
2933 {
2934 	UINT8 modrm = FETCH();
2935 
2936 	if( modrm >= 0xc0 ) {
2937 	//	osd_die("NYI");
2938 	} else {
2939 		UINT32 ea = GetEA(modrm);
2940 		STORE_REG32(modrm, READ32(ea + 0));
2941 		I.sreg[s].selector = READ16(ea + 4);
2942 		i386_load_segment_descriptor( s );
2943 	}
2944 }
2945 
I386OP(lds32)2946 static void I386OP(lds32)(void)				// Opcode 0xc5
2947 {
2948 	I386OP(load_far_pointer32)(DS);
2949 	CYCLES(CYCLES_LDS);
2950 }
2951 
I386OP(lss32)2952 static void I386OP(lss32)(void)				// Opcode 0x0f 0xb2
2953 {
2954 	I386OP(load_far_pointer32)(SS);
2955 	CYCLES(CYCLES_LSS);
2956 }
2957 
I386OP(les32)2958 static void I386OP(les32)(void)				// Opcode 0xc4
2959 {
2960 	I386OP(load_far_pointer16)(ES);
2961 	CYCLES(CYCLES_LES);
2962 }
2963 
I386OP(lfs32)2964 static void I386OP(lfs32)(void)				// Opcode 0x0f 0xb4
2965 {
2966 	I386OP(load_far_pointer16)(FS);
2967 	CYCLES(CYCLES_LFS);
2968 }
2969 
I386OP(lgs32)2970 static void I386OP(lgs32)(void)				// Opcode 0x0f 0xb5
2971 {
2972 	I386OP(load_far_pointer32)(GS);
2973 	CYCLES(CYCLES_LGS);
2974 }
2975