1 // license:BSD-3-Clause
2 // copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett
3 static UINT32 I386OP(shift_rotate32)(i386_state *cpustate, UINT8 modrm, UINT32 value, UINT8 shift)
10 CYCLES_RM(cpustate,modrm, 3, 7);
11 } else if( shift == 1 ) {
12 switch( (modrm >> 3) & 0x7 )
14 case 0: /* ROL rm32, 1 */
15 cpustate->CF = (src & 0x80000000) ? 1 : 0;
16 dst = (src << 1) + cpustate->CF;
17 cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
18 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
20 case 1: /* ROR rm32, 1 */
21 cpustate->CF = (src & 0x1) ? 1 : 0;
22 dst = (cpustate->CF << 31) | (src >> 1);
23 cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
24 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
26 case 2: /* RCL rm32, 1 */
27 dst = (src << 1) + cpustate->CF;
28 cpustate->CF = (src & 0x80000000) ? 1 : 0;
29 cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
30 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
32 case 3: /* RCR rm32, 1 */
33 dst = (cpustate->CF << 31) | (src >> 1);
34 cpustate->CF = src & 0x1;
35 cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
36 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
38 case 4: /* SHL/SAL rm32, 1 */
41 cpustate->CF = (src & 0x80000000) ? 1 : 0;
42 cpustate->OF = (((cpustate->CF << 31) ^ dst) & 0x80000000) ? 1 : 0;
44 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
46 case 5: /* SHR rm32, 1 */
48 cpustate->CF = src & 0x1;
49 cpustate->OF = (src & 0x80000000) ? 1 : 0;
51 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
53 case 7: /* SAR rm32, 1 */
54 dst = (INT32)(src) >> 1;
55 cpustate->CF = src & 0x1;
58 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
64 switch( (modrm >> 3) & 0x7 )
66 case 0: /* ROL rm32, i8 */
67 dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
68 ((src & ((UINT32)0xffffffff << (32-shift))) >> (32-shift));
69 cpustate->CF = dst & 0x1;
70 cpustate->OF = (dst & 1) ^ (dst >> 31);
71 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
73 case 1: /* ROR rm32, i8 */
74 dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
75 ((src & ((UINT32)0xffffffff >> (32-shift))) << (32-shift));
76 cpustate->CF = (dst >> 31) & 0x1;
77 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
78 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
80 case 2: /* RCL rm32, i8 */
81 dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
82 ((src & ((UINT32)0xffffffff << (33-shift))) >> (33-shift)) |
83 (cpustate->CF << (shift-1));
84 cpustate->CF = (src >> (32-shift)) & 0x1;
85 cpustate->OF = cpustate->CF ^ ((dst >> 31) & 1);
86 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
88 case 3: /* RCR rm32, i8 */
89 dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
90 ((src & ((UINT32)0xffffffff >> (32-shift))) << (33-shift)) |
91 (cpustate->CF << (32-shift));
92 cpustate->CF = (src >> (shift-1)) & 0x1;
93 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
94 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
96 case 4: /* SHL/SAL rm32, i8 */
99 cpustate->CF = (src & (1 << (32-shift))) ? 1 : 0;
101 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
103 case 5: /* SHR rm32, i8 */
105 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
107 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
109 case 7: /* SAR rm32, i8 */
110 dst = (INT32)src >> shift;
111 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
113 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
123 static void I386OP(adc_rm32_r32)(i386_state *cpustate) // Opcode 0x11
126 UINT8 modrm = FETCH(cpustate);
127 if( modrm >= 0xc0 ) {
128 src = LOAD_REG32(modrm);
129 dst = LOAD_RM32(modrm);
130 dst = ADC32(cpustate, dst, src, cpustate->CF);
131 STORE_RM32(modrm, dst);
132 CYCLES(cpustate,CYCLES_ALU_REG_REG);
134 UINT32 ea = GetEA(cpustate,modrm,1,4);
135 src = LOAD_REG32(modrm);
136 dst = READ32(cpustate,ea);
137 dst = ADC32(cpustate, dst, src, cpustate->CF);
138 WRITE32(cpustate,ea, dst);
139 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
143 static void I386OP(adc_r32_rm32)(i386_state *cpustate) // Opcode 0x13
146 UINT8 modrm = FETCH(cpustate);
147 if( modrm >= 0xc0 ) {
148 src = LOAD_RM32(modrm);
149 dst = LOAD_REG32(modrm);
150 dst = ADC32(cpustate, dst, src, cpustate->CF);
151 STORE_REG32(modrm, dst);
152 CYCLES(cpustate,CYCLES_ALU_REG_REG);
154 UINT32 ea = GetEA(cpustate,modrm,0,4);
155 src = READ32(cpustate,ea);
156 dst = LOAD_REG32(modrm);
157 dst = ADC32(cpustate, dst, src, cpustate->CF);
158 STORE_REG32(modrm, dst);
159 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
163 static void I386OP(adc_eax_i32)(i386_state *cpustate) // Opcode 0x15
166 src = FETCH32(cpustate);
168 dst = ADC32(cpustate, dst, src, cpustate->CF);
170 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
173 static void I386OP(add_rm32_r32)(i386_state *cpustate) // Opcode 0x01
176 UINT8 modrm = FETCH(cpustate);
177 if( modrm >= 0xc0 ) {
178 src = LOAD_REG32(modrm);
179 dst = LOAD_RM32(modrm);
180 dst = ADD32(cpustate,dst, src);
181 STORE_RM32(modrm, dst);
182 CYCLES(cpustate,CYCLES_ALU_REG_REG);
184 UINT32 ea = GetEA(cpustate,modrm,1,4);
185 src = LOAD_REG32(modrm);
186 dst = READ32(cpustate,ea);
187 dst = ADD32(cpustate,dst, src);
188 WRITE32(cpustate,ea, dst);
189 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
193 static void I386OP(add_r32_rm32)(i386_state *cpustate) // Opcode 0x03
196 UINT8 modrm = FETCH(cpustate);
197 if( modrm >= 0xc0 ) {
198 src = LOAD_RM32(modrm);
199 dst = LOAD_REG32(modrm);
200 dst = ADD32(cpustate,dst, src);
201 STORE_REG32(modrm, dst);
202 CYCLES(cpustate,CYCLES_ALU_REG_REG);
204 UINT32 ea = GetEA(cpustate,modrm,0,4);
205 src = READ32(cpustate,ea);
206 dst = LOAD_REG32(modrm);
207 dst = ADD32(cpustate,dst, src);
208 STORE_REG32(modrm, dst);
209 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
213 static void I386OP(add_eax_i32)(i386_state *cpustate) // Opcode 0x05
216 src = FETCH32(cpustate);
218 dst = ADD32(cpustate,dst, src);
220 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
223 static void I386OP(and_rm32_r32)(i386_state *cpustate) // Opcode 0x21
226 UINT8 modrm = FETCH(cpustate);
227 if( modrm >= 0xc0 ) {
228 src = LOAD_REG32(modrm);
229 dst = LOAD_RM32(modrm);
230 dst = AND32(cpustate,dst, src);
231 STORE_RM32(modrm, dst);
232 CYCLES(cpustate,CYCLES_ALU_REG_REG);
234 UINT32 ea = GetEA(cpustate,modrm,1,4);
235 src = LOAD_REG32(modrm);
236 dst = READ32(cpustate,ea);
237 dst = AND32(cpustate,dst, src);
238 WRITE32(cpustate,ea, dst);
239 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
243 static void I386OP(and_r32_rm32)(i386_state *cpustate) // Opcode 0x23
246 UINT8 modrm = FETCH(cpustate);
247 if( modrm >= 0xc0 ) {
248 src = LOAD_RM32(modrm);
249 dst = LOAD_REG32(modrm);
250 dst = AND32(cpustate,dst, src);
251 STORE_REG32(modrm, dst);
252 CYCLES(cpustate,CYCLES_ALU_REG_REG);
254 UINT32 ea = GetEA(cpustate,modrm,0,4);
255 src = READ32(cpustate,ea);
256 dst = LOAD_REG32(modrm);
257 dst = AND32(cpustate,dst, src);
258 STORE_REG32(modrm, dst);
259 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
263 static void I386OP(and_eax_i32)(i386_state *cpustate) // Opcode 0x25
266 src = FETCH32(cpustate);
268 dst = AND32(cpustate,dst, src);
270 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
273 static void I386OP(bsf_r32_rm32)(i386_state *cpustate) // Opcode 0x0f bc
275 UINT32 src, dst, temp;
276 UINT8 modrm = FETCH(cpustate);
278 if( modrm >= 0xc0 ) {
279 src = LOAD_RM32(modrm);
281 UINT32 ea = GetEA(cpustate,modrm,0,4);
282 src = READ32(cpustate,ea);
292 while( (src & (1 << temp)) == 0 ) {
295 CYCLES(cpustate,CYCLES_BSF);
297 STORE_REG32(modrm, dst);
299 CYCLES(cpustate,CYCLES_BSF_BASE);
302 static void I386OP(bsr_r32_rm32)(i386_state *cpustate) // Opcode 0x0f bd
304 UINT32 src, dst, temp;
305 UINT8 modrm = FETCH(cpustate);
307 if( modrm >= 0xc0 ) {
308 src = LOAD_RM32(modrm);
310 UINT32 ea = GetEA(cpustate,modrm,0,4);
311 src = READ32(cpustate,ea);
321 while( (src & (1U << temp)) == 0 ) {
324 CYCLES(cpustate,CYCLES_BSR);
326 STORE_REG32(modrm, dst);
328 CYCLES(cpustate,CYCLES_BSR_BASE);
331 static void I386OP(bt_rm32_r32)(i386_state *cpustate) // Opcode 0x0f a3
333 UINT8 modrm = FETCH(cpustate);
334 if( modrm >= 0xc0 ) {
335 UINT32 dst = LOAD_RM32(modrm);
336 UINT32 bit = LOAD_REG32(modrm);
338 if( dst & (1 << bit) )
343 CYCLES(cpustate,CYCLES_BT_REG_REG);
346 UINT32 ea = GetNonTranslatedEA(cpustate,modrm,&segment);
347 UINT32 bit = LOAD_REG32(modrm);
349 ea = i386_translate(cpustate,segment,(cpustate->address_size)?ea:(ea&0xffff),0,4);
351 UINT32 dst = READ32(cpustate,ea);
353 if( dst & (1 << bit) )
358 CYCLES(cpustate,CYCLES_BT_REG_MEM);
362 static void I386OP(btc_rm32_r32)(i386_state *cpustate) // Opcode 0x0f bb
364 UINT8 modrm = FETCH(cpustate);
365 if( modrm >= 0xc0 ) {
366 UINT32 dst = LOAD_RM32(modrm);
367 UINT32 bit = LOAD_REG32(modrm);
369 if( dst & (1 << bit) )
375 STORE_RM32(modrm, dst);
376 CYCLES(cpustate,CYCLES_BTC_REG_REG);
379 UINT32 ea = GetNonTranslatedEA(cpustate,modrm,&segment);
380 UINT32 bit = LOAD_REG32(modrm);
382 ea = i386_translate(cpustate,segment,(cpustate->address_size)?ea:(ea&0xffff),1,4);
384 UINT32 dst = READ32(cpustate,ea);
386 if( dst & (1 << bit) )
392 WRITE32(cpustate,ea, dst);
393 CYCLES(cpustate,CYCLES_BTC_REG_MEM);
397 static void I386OP(btr_rm32_r32)(i386_state *cpustate) // Opcode 0x0f b3
399 UINT8 modrm = FETCH(cpustate);
400 if( modrm >= 0xc0 ) {
401 UINT32 dst = LOAD_RM32(modrm);
402 UINT32 bit = LOAD_REG32(modrm);
404 if( dst & (1 << bit) )
410 STORE_RM32(modrm, dst);
411 CYCLES(cpustate,CYCLES_BTR_REG_REG);
414 UINT32 ea = GetNonTranslatedEA(cpustate,modrm,&segment);
415 UINT32 bit = LOAD_REG32(modrm);
417 ea = i386_translate(cpustate,segment,(cpustate->address_size)?ea:(ea&0xffff),1,4);
419 UINT32 dst = READ32(cpustate,ea);
421 if( dst & (1 << bit) )
427 WRITE32(cpustate,ea, dst);
428 CYCLES(cpustate,CYCLES_BTR_REG_MEM);
432 static void I386OP(bts_rm32_r32)(i386_state *cpustate) // Opcode 0x0f ab
434 UINT8 modrm = FETCH(cpustate);
435 if( modrm >= 0xc0 ) {
436 UINT32 dst = LOAD_RM32(modrm);
437 UINT32 bit = LOAD_REG32(modrm);
439 if( dst & (1 << bit) )
445 STORE_RM32(modrm, dst);
446 CYCLES(cpustate,CYCLES_BTS_REG_REG);
449 UINT32 ea = GetNonTranslatedEA(cpustate,modrm,&segment);
450 UINT32 bit = LOAD_REG32(modrm);
452 ea = i386_translate(cpustate,segment,(cpustate->address_size)?ea:(ea&0xffff),1,4);
454 UINT32 dst = READ32(cpustate,ea);
456 if( dst & (1 << bit) )
462 WRITE32(cpustate,ea, dst);
463 CYCLES(cpustate,CYCLES_BTS_REG_MEM);
467 static void I386OP(call_abs32)(i386_state *cpustate) // Opcode 0x9a
469 UINT32 offset = FETCH32(cpustate);
470 UINT16 ptr = FETCH16(cpustate);
472 if(PROTECTED_MODE && !V8086_MODE)
474 i386_protected_mode_call(cpustate,ptr,offset,0,1);
478 PUSH32SEG(cpustate, cpustate->sreg[CS].selector );
479 PUSH32(cpustate, cpustate->eip );
480 cpustate->sreg[CS].selector = ptr;
481 cpustate->performed_intersegment_jump = 1;
482 cpustate->eip = offset;
483 i386_load_segment_descriptor(cpustate,CS);
485 CYCLES(cpustate,CYCLES_CALL_INTERSEG);
486 CHANGE_PC(cpustate,cpustate->eip);
489 static void I386OP(call_rel32)(i386_state *cpustate) // Opcode 0xe8
491 INT32 disp = FETCH32(cpustate);
492 PUSH32(cpustate, cpustate->eip );
493 cpustate->eip += disp;
494 CHANGE_PC(cpustate,cpustate->eip);
495 CYCLES(cpustate,CYCLES_CALL); /* TODO: Timing = 7 + m */
498 static void I386OP(cdq)(i386_state *cpustate) // Opcode 0x99
500 if( REG32(EAX) & 0x80000000 ) {
501 REG32(EDX) = 0xffffffff;
503 REG32(EDX) = 0x00000000;
505 CYCLES(cpustate,CYCLES_CWD);
508 static void I386OP(cmp_rm32_r32)(i386_state *cpustate) // Opcode 0x39
511 UINT8 modrm = FETCH(cpustate);
512 if( modrm >= 0xc0 ) {
513 src = LOAD_REG32(modrm);
514 dst = LOAD_RM32(modrm);
515 SUB32(cpustate,dst, src);
516 CYCLES(cpustate,CYCLES_CMP_REG_REG);
518 UINT32 ea = GetEA(cpustate,modrm,0,4);
519 src = LOAD_REG32(modrm);
520 dst = READ32(cpustate,ea);
521 SUB32(cpustate,dst, src);
522 CYCLES(cpustate,CYCLES_CMP_REG_MEM);
526 static void I386OP(cmp_r32_rm32)(i386_state *cpustate) // Opcode 0x3b
529 UINT8 modrm = FETCH(cpustate);
530 if( modrm >= 0xc0 ) {
531 src = LOAD_RM32(modrm);
532 dst = LOAD_REG32(modrm);
533 SUB32(cpustate,dst, src);
534 CYCLES(cpustate,CYCLES_CMP_REG_REG);
536 UINT32 ea = GetEA(cpustate,modrm,0,4);
537 src = READ32(cpustate,ea);
538 dst = LOAD_REG32(modrm);
539 SUB32(cpustate,dst, src);
540 CYCLES(cpustate,CYCLES_CMP_MEM_REG);
544 static void I386OP(cmp_eax_i32)(i386_state *cpustate) // Opcode 0x3d
547 src = FETCH32(cpustate);
549 SUB32(cpustate,dst, src);
550 CYCLES(cpustate,CYCLES_CMP_IMM_ACC);
553 static void I386OP(cmpsd)(i386_state *cpustate) // Opcode 0xa7
555 UINT32 eas, ead, src, dst;
556 if( cpustate->segment_prefix ) {
557 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
559 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
561 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0, 4 );
562 src = READ32(cpustate,eas);
563 dst = READ32(cpustate,ead);
564 SUB32(cpustate,src,dst);
567 CYCLES(cpustate,CYCLES_CMPS);
570 static void I386OP(cwde)(i386_state *cpustate) // Opcode 0x98
572 REG32(EAX) = (INT32)((INT16)REG16(AX));
573 CYCLES(cpustate,CYCLES_CBW);
576 static void I386OP(dec_eax)(i386_state *cpustate) // Opcode 0x48
578 REG32(EAX) = DEC32(cpustate, REG32(EAX) );
579 CYCLES(cpustate,CYCLES_DEC_REG);
582 static void I386OP(dec_ecx)(i386_state *cpustate) // Opcode 0x49
584 REG32(ECX) = DEC32(cpustate, REG32(ECX) );
585 CYCLES(cpustate,CYCLES_DEC_REG);
588 static void I386OP(dec_edx)(i386_state *cpustate) // Opcode 0x4a
590 REG32(EDX) = DEC32(cpustate, REG32(EDX) );
591 CYCLES(cpustate,CYCLES_DEC_REG);
594 static void I386OP(dec_ebx)(i386_state *cpustate) // Opcode 0x4b
596 REG32(EBX) = DEC32(cpustate, REG32(EBX) );
597 CYCLES(cpustate,CYCLES_DEC_REG);
600 static void I386OP(dec_esp)(i386_state *cpustate) // Opcode 0x4c
602 REG32(ESP) = DEC32(cpustate, REG32(ESP) );
603 CYCLES(cpustate,CYCLES_DEC_REG);
606 static void I386OP(dec_ebp)(i386_state *cpustate) // Opcode 0x4d
608 REG32(EBP) = DEC32(cpustate, REG32(EBP) );
609 CYCLES(cpustate,CYCLES_DEC_REG);
612 static void I386OP(dec_esi)(i386_state *cpustate) // Opcode 0x4e
614 REG32(ESI) = DEC32(cpustate, REG32(ESI) );
615 CYCLES(cpustate,CYCLES_DEC_REG);
618 static void I386OP(dec_edi)(i386_state *cpustate) // Opcode 0x4f
620 REG32(EDI) = DEC32(cpustate, REG32(EDI) );
621 CYCLES(cpustate,CYCLES_DEC_REG);
624 static void I386OP(imul_r32_rm32)(i386_state *cpustate) // Opcode 0x0f af
626 UINT8 modrm = FETCH(cpustate);
629 if( modrm >= 0xc0 ) {
630 src = (INT64)(INT32)LOAD_RM32(modrm);
631 CYCLES(cpustate,CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */
633 UINT32 ea = GetEA(cpustate,modrm,0,4);
634 src = (INT64)(INT32)READ32(cpustate,ea);
635 CYCLES(cpustate,CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */
638 dst = (INT64)(INT32)LOAD_REG32(modrm);
641 STORE_REG32(modrm, (UINT32)result);
643 cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
646 static void I386OP(imul_r32_rm32_i32)(i386_state *cpustate) // Opcode 0x69
648 UINT8 modrm = FETCH(cpustate);
651 if( modrm >= 0xc0 ) {
652 dst = (INT64)(INT32)LOAD_RM32(modrm);
653 CYCLES(cpustate,CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */
655 UINT32 ea = GetEA(cpustate,modrm,0,4);
656 dst = (INT64)(INT32)READ32(cpustate,ea);
657 CYCLES(cpustate,CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */
660 src = (INT64)(INT32)FETCH32(cpustate);
663 STORE_REG32(modrm, (UINT32)result);
665 cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
668 static void I386OP(imul_r32_rm32_i8)(i386_state *cpustate) // Opcode 0x6b
670 UINT8 modrm = FETCH(cpustate);
673 if( modrm >= 0xc0 ) {
674 dst = (INT64)(INT32)LOAD_RM32(modrm);
675 CYCLES(cpustate,CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */
677 UINT32 ea = GetEA(cpustate,modrm,0,4);
678 dst = (INT64)(INT32)READ32(cpustate,ea);
679 CYCLES(cpustate,CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */
682 src = (INT64)(INT8)FETCH(cpustate);
685 STORE_REG32(modrm, (UINT32)result);
687 cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
690 static void I386OP(in_eax_i8)(i386_state *cpustate) // Opcode 0xe5
692 UINT16 port = FETCH(cpustate);
693 UINT32 data = READPORT32(cpustate, port);
695 CYCLES(cpustate,CYCLES_IN_VAR);
698 static void I386OP(in_eax_dx)(i386_state *cpustate) // Opcode 0xed
700 UINT16 port = REG16(DX);
701 UINT32 data = READPORT32(cpustate, port);
703 CYCLES(cpustate,CYCLES_IN);
706 static void I386OP(inc_eax)(i386_state *cpustate) // Opcode 0x40
708 REG32(EAX) = INC32(cpustate, REG32(EAX) );
709 CYCLES(cpustate,CYCLES_INC_REG);
712 static void I386OP(inc_ecx)(i386_state *cpustate) // Opcode 0x41
714 REG32(ECX) = INC32(cpustate, REG32(ECX) );
715 CYCLES(cpustate,CYCLES_INC_REG);
718 static void I386OP(inc_edx)(i386_state *cpustate) // Opcode 0x42
720 REG32(EDX) = INC32(cpustate, REG32(EDX) );
721 CYCLES(cpustate,CYCLES_INC_REG);
724 static void I386OP(inc_ebx)(i386_state *cpustate) // Opcode 0x43
726 REG32(EBX) = INC32(cpustate, REG32(EBX) );
727 CYCLES(cpustate,CYCLES_INC_REG);
730 static void I386OP(inc_esp)(i386_state *cpustate) // Opcode 0x44
732 REG32(ESP) = INC32(cpustate, REG32(ESP) );
733 CYCLES(cpustate,CYCLES_INC_REG);
736 static void I386OP(inc_ebp)(i386_state *cpustate) // Opcode 0x45
738 REG32(EBP) = INC32(cpustate, REG32(EBP) );
739 CYCLES(cpustate,CYCLES_INC_REG);
742 static void I386OP(inc_esi)(i386_state *cpustate) // Opcode 0x46
744 REG32(ESI) = INC32(cpustate, REG32(ESI) );
745 CYCLES(cpustate,CYCLES_INC_REG);
748 static void I386OP(inc_edi)(i386_state *cpustate) // Opcode 0x47
750 REG32(EDI) = INC32(cpustate, REG32(EDI) );
751 CYCLES(cpustate,CYCLES_INC_REG);
754 static void I386OP(iret32)(i386_state *cpustate) // Opcode 0xcf
758 i386_protected_mode_iret(cpustate,1);
762 /* TODO: #SS(0) exception */
763 /* TODO: #GP(0) exception */
764 cpustate->eip = POP32(cpustate);
765 cpustate->sreg[CS].selector = POP32(cpustate) & 0xffff;
766 set_flags(cpustate, POP32(cpustate) );
767 i386_load_segment_descriptor(cpustate,CS);
768 CHANGE_PC(cpustate,cpustate->eip);
770 CYCLES(cpustate,CYCLES_IRET);
773 static void I386OP(ja_rel32)(i386_state *cpustate) // Opcode 0x0f 87
775 INT32 disp = FETCH32(cpustate);
776 if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
777 cpustate->eip += disp;
778 CHANGE_PC(cpustate,cpustate->eip);
779 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
781 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
785 static void I386OP(jbe_rel32)(i386_state *cpustate) // Opcode 0x0f 86
787 INT32 disp = FETCH32(cpustate);
788 if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
789 cpustate->eip += disp;
790 CHANGE_PC(cpustate,cpustate->eip);
791 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
793 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
797 static void I386OP(jc_rel32)(i386_state *cpustate) // Opcode 0x0f 82
799 INT32 disp = FETCH32(cpustate);
800 if( cpustate->CF != 0 ) {
801 cpustate->eip += disp;
802 CHANGE_PC(cpustate,cpustate->eip);
803 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
805 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
809 static void I386OP(jg_rel32)(i386_state *cpustate) // Opcode 0x0f 8f
811 INT32 disp = FETCH32(cpustate);
812 if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
813 cpustate->eip += disp;
814 CHANGE_PC(cpustate,cpustate->eip);
815 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
817 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
821 static void I386OP(jge_rel32)(i386_state *cpustate) // Opcode 0x0f 8d
823 INT32 disp = FETCH32(cpustate);
824 if(cpustate->SF == cpustate->OF) {
825 cpustate->eip += disp;
826 CHANGE_PC(cpustate,cpustate->eip);
827 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
829 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
833 static void I386OP(jl_rel32)(i386_state *cpustate) // Opcode 0x0f 8c
835 INT32 disp = FETCH32(cpustate);
836 if( (cpustate->SF != cpustate->OF) ) {
837 cpustate->eip += disp;
838 CHANGE_PC(cpustate,cpustate->eip);
839 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
841 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
845 static void I386OP(jle_rel32)(i386_state *cpustate) // Opcode 0x0f 8e
847 INT32 disp = FETCH32(cpustate);
848 if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
849 cpustate->eip += disp;
850 CHANGE_PC(cpustate,cpustate->eip);
851 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
853 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
857 static void I386OP(jnc_rel32)(i386_state *cpustate) // Opcode 0x0f 83
859 INT32 disp = FETCH32(cpustate);
860 if( cpustate->CF == 0 ) {
861 cpustate->eip += disp;
862 CHANGE_PC(cpustate,cpustate->eip);
863 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
865 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
869 static void I386OP(jno_rel32)(i386_state *cpustate) // Opcode 0x0f 81
871 INT32 disp = FETCH32(cpustate);
872 if( cpustate->OF == 0 ) {
873 cpustate->eip += disp;
874 CHANGE_PC(cpustate,cpustate->eip);
875 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
877 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
881 static void I386OP(jnp_rel32)(i386_state *cpustate) // Opcode 0x0f 8b
883 INT32 disp = FETCH32(cpustate);
884 if( cpustate->PF == 0 ) {
885 cpustate->eip += disp;
886 CHANGE_PC(cpustate,cpustate->eip);
887 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
889 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
893 static void I386OP(jns_rel32)(i386_state *cpustate) // Opcode 0x0f 89
895 INT32 disp = FETCH32(cpustate);
896 if( cpustate->SF == 0 ) {
897 cpustate->eip += disp;
898 CHANGE_PC(cpustate,cpustate->eip);
899 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
901 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
905 static void I386OP(jnz_rel32)(i386_state *cpustate) // Opcode 0x0f 85
907 INT32 disp = FETCH32(cpustate);
908 if( cpustate->ZF == 0 ) {
909 cpustate->eip += disp;
910 CHANGE_PC(cpustate,cpustate->eip);
911 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
913 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
917 static void I386OP(jo_rel32)(i386_state *cpustate) // Opcode 0x0f 80
919 INT32 disp = FETCH32(cpustate);
920 if( cpustate->OF != 0 ) {
921 cpustate->eip += disp;
922 CHANGE_PC(cpustate,cpustate->eip);
923 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
925 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
929 static void I386OP(jp_rel32)(i386_state *cpustate) // Opcode 0x0f 8a
931 INT32 disp = FETCH32(cpustate);
932 if( cpustate->PF != 0 ) {
933 cpustate->eip += disp;
934 CHANGE_PC(cpustate,cpustate->eip);
935 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
937 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
941 static void I386OP(js_rel32)(i386_state *cpustate) // Opcode 0x0f 88
943 INT32 disp = FETCH32(cpustate);
944 if( cpustate->SF != 0 ) {
945 cpustate->eip += disp;
946 CHANGE_PC(cpustate,cpustate->eip);
947 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
949 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
953 static void I386OP(jz_rel32)(i386_state *cpustate) // Opcode 0x0f 84
955 INT32 disp = FETCH32(cpustate);
956 if( cpustate->ZF != 0 ) {
957 cpustate->eip += disp;
958 CHANGE_PC(cpustate,cpustate->eip);
959 CYCLES(cpustate,CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
961 CYCLES(cpustate,CYCLES_JCC_FULL_DISP_NOBRANCH);
965 static void I386OP(jcxz32)(i386_state *cpustate) // Opcode 0xe3
967 INT8 disp = FETCH(cpustate);
968 int val = (cpustate->address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
970 cpustate->eip += disp;
971 CHANGE_PC(cpustate,cpustate->eip);
972 CYCLES(cpustate,CYCLES_JCXZ); /* TODO: Timing = 9 + m */
974 CYCLES(cpustate,CYCLES_JCXZ_NOBRANCH);
978 static void I386OP(jmp_rel32)(i386_state *cpustate) // Opcode 0xe9
980 UINT32 disp = FETCH32(cpustate);
981 /* TODO: Segment limit */
982 cpustate->eip += disp;
983 CHANGE_PC(cpustate,cpustate->eip);
984 CYCLES(cpustate,CYCLES_JMP); /* TODO: Timing = 7 + m */
987 static void I386OP(jmp_abs32)(i386_state *cpustate) // Opcode 0xea
989 UINT32 address = FETCH32(cpustate);
990 UINT16 segment = FETCH16(cpustate);
992 if( PROTECTED_MODE && !V8086_MODE)
994 i386_protected_mode_jump(cpustate,segment,address,0,1);
998 cpustate->eip = address;
999 cpustate->sreg[CS].selector = segment;
1000 cpustate->performed_intersegment_jump = 1;
1001 i386_load_segment_descriptor(cpustate,CS);
1002 CHANGE_PC(cpustate,cpustate->eip);
1004 CYCLES(cpustate,CYCLES_JMP_INTERSEG);
1007 static void I386OP(lea32)(i386_state *cpustate) // Opcode 0x8d
1009 UINT8 modrm = FETCH(cpustate);
1010 UINT32 ea = GetNonTranslatedEA(cpustate,modrm,NULL);
1011 if (!cpustate->address_size)
1015 STORE_REG32(modrm, ea);
1016 CYCLES(cpustate,CYCLES_LEA);
1019 static void I386OP(enter32)(i386_state *cpustate) // Opcode 0xc8
1021 UINT16 framesize = FETCH16(cpustate);
1022 UINT8 level = FETCH(cpustate) % 32;
1025 PUSH32(cpustate,REG32(EBP));
1027 frameptr = REG16(SP);
1029 frameptr = REG32(ESP);
1033 for(x=1;x<level-1;x++)
1036 PUSH32(cpustate,READ32(cpustate,REG32(EBP)));
1038 PUSH32(cpustate,frameptr);
1040 REG32(EBP) = frameptr;
1042 REG16(SP) -= framesize;
1044 REG32(ESP) -= framesize;
1045 CYCLES(cpustate,CYCLES_ENTER);
1048 static void I386OP(leave32)(i386_state *cpustate) // Opcode 0xc9
1051 REG16(SP) = REG16(BP);
1053 REG32(ESP) = REG32(EBP);
1054 REG32(EBP) = POP32(cpustate);
1055 CYCLES(cpustate,CYCLES_LEAVE);
1058 static void I386OP(lodsd)(i386_state *cpustate) // Opcode 0xad
1061 if( cpustate->segment_prefix ) {
1062 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
1064 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
1066 REG32(EAX) = READ32(cpustate,eas);
1067 BUMP_SI(cpustate,4);
1068 CYCLES(cpustate,CYCLES_LODS);
1071 static void I386OP(loop32)(i386_state *cpustate) // Opcode 0xe2
1073 INT8 disp = FETCH(cpustate);
1074 INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
1076 cpustate->eip += disp;
1077 CHANGE_PC(cpustate,cpustate->eip);
1079 CYCLES(cpustate,CYCLES_LOOP); /* TODO: Timing = 11 + m */
1082 static void I386OP(loopne32)(i386_state *cpustate) // Opcode 0xe0
1084 INT8 disp = FETCH(cpustate);
1085 INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
1086 if( reg != 0 && cpustate->ZF == 0 ) {
1087 cpustate->eip += disp;
1088 CHANGE_PC(cpustate,cpustate->eip);
1090 CYCLES(cpustate,CYCLES_LOOPNZ); /* TODO: Timing = 11 + m */
1093 static void I386OP(loopz32)(i386_state *cpustate) // Opcode 0xe1
1095 INT8 disp = FETCH(cpustate);
1096 INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
1097 if( reg != 0 && cpustate->ZF != 0 ) {
1098 cpustate->eip += disp;
1099 CHANGE_PC(cpustate,cpustate->eip);
1101 CYCLES(cpustate,CYCLES_LOOPZ); /* TODO: Timing = 11 + m */
1104 static void I386OP(mov_rm32_r32)(i386_state *cpustate) // Opcode 0x89
1107 UINT8 modrm = FETCH(cpustate);
1108 if( modrm >= 0xc0 ) {
1109 src = LOAD_REG32(modrm);
1110 STORE_RM32(modrm, src);
1111 CYCLES(cpustate,CYCLES_MOV_REG_REG);
1113 UINT32 ea = GetEA(cpustate,modrm,1,4);
1114 src = LOAD_REG32(modrm);
1115 WRITE32(cpustate,ea, src);
1116 CYCLES(cpustate,CYCLES_MOV_REG_MEM);
1120 static void I386OP(mov_r32_rm32)(i386_state *cpustate) // Opcode 0x8b
1123 UINT8 modrm = FETCH(cpustate);
1124 if( modrm >= 0xc0 ) {
1125 src = LOAD_RM32(modrm);
1126 STORE_REG32(modrm, src);
1127 CYCLES(cpustate,CYCLES_MOV_REG_REG);
1129 UINT32 ea = GetEA(cpustate,modrm,0,4);
1130 src = READ32(cpustate,ea);
1131 STORE_REG32(modrm, src);
1132 CYCLES(cpustate,CYCLES_MOV_MEM_REG);
1136 static void I386OP(mov_rm32_i32)(i386_state *cpustate) // Opcode 0xc7
1138 UINT8 modrm = FETCH(cpustate);
1139 if( modrm >= 0xc0 ) {
1140 UINT32 value = FETCH32(cpustate);
1141 STORE_RM32(modrm, value);
1142 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1144 UINT32 ea = GetEA(cpustate,modrm,1,4);
1145 UINT32 value = FETCH32(cpustate);
1146 WRITE32(cpustate,ea, value);
1147 CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
1151 static void I386OP(mov_eax_m32)(i386_state *cpustate) // Opcode 0xa1
1154 if( cpustate->address_size ) {
1155 offset = FETCH32(cpustate);
1157 offset = FETCH16(cpustate);
1159 if( cpustate->segment_prefix ) {
1160 ea = i386_translate(cpustate, cpustate->segment_override, offset, 0, 4 );
1162 ea = i386_translate(cpustate, DS, offset, 0, 4 );
1164 REG32(EAX) = READ32(cpustate,ea);
1165 CYCLES(cpustate,CYCLES_MOV_MEM_ACC);
1168 static void I386OP(mov_m32_eax)(i386_state *cpustate) // Opcode 0xa3
1171 if( cpustate->address_size ) {
1172 offset = FETCH32(cpustate);
1174 offset = FETCH16(cpustate);
1176 if( cpustate->segment_prefix ) {
1177 ea = i386_translate(cpustate, cpustate->segment_override, offset, 1, 4 );
1179 ea = i386_translate(cpustate, DS, offset, 1, 4 );
1181 WRITE32(cpustate, ea, REG32(EAX) );
1182 CYCLES(cpustate,CYCLES_MOV_ACC_MEM);
1185 static void I386OP(mov_eax_i32)(i386_state *cpustate) // Opcode 0xb8
1187 REG32(EAX) = FETCH32(cpustate);
1188 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1191 static void I386OP(mov_ecx_i32)(i386_state *cpustate) // Opcode 0xb9
1193 REG32(ECX) = FETCH32(cpustate);
1194 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1197 static void I386OP(mov_edx_i32)(i386_state *cpustate) // Opcode 0xba
1199 REG32(EDX) = FETCH32(cpustate);
1200 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1203 static void I386OP(mov_ebx_i32)(i386_state *cpustate) // Opcode 0xbb
1205 REG32(EBX) = FETCH32(cpustate);
1206 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1209 static void I386OP(mov_esp_i32)(i386_state *cpustate) // Opcode 0xbc
1211 REG32(ESP) = FETCH32(cpustate);
1212 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1215 static void I386OP(mov_ebp_i32)(i386_state *cpustate) // Opcode 0xbd
1217 REG32(EBP) = FETCH32(cpustate);
1218 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1221 static void I386OP(mov_esi_i32)(i386_state *cpustate) // Opcode 0xbe
1223 REG32(ESI) = FETCH32(cpustate);
1224 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1227 static void I386OP(mov_edi_i32)(i386_state *cpustate) // Opcode 0xbf
1229 REG32(EDI) = FETCH32(cpustate);
1230 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
1233 static void I386OP(movsd)(i386_state *cpustate) // Opcode 0xa5
1236 if( cpustate->segment_prefix ) {
1237 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
1239 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0, 4 );
1241 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1, 4 );
1242 v = READ32(cpustate,eas);
1243 WRITE32(cpustate,ead, v);
1244 BUMP_SI(cpustate,4);
1245 BUMP_DI(cpustate,4);
1246 CYCLES(cpustate,CYCLES_MOVS);
1249 static void I386OP(movsx_r32_rm8)(i386_state *cpustate) // Opcode 0x0f be
1251 UINT8 modrm = FETCH(cpustate);
1252 if( modrm >= 0xc0 ) {
1253 INT32 src = (INT8)LOAD_RM8(modrm);
1254 STORE_REG32(modrm, src);
1255 CYCLES(cpustate,CYCLES_MOVSX_REG_REG);
1257 UINT32 ea = GetEA(cpustate,modrm,0,1);
1258 INT32 src = (INT8)READ8(cpustate,ea);
1259 STORE_REG32(modrm, src);
1260 CYCLES(cpustate,CYCLES_MOVSX_MEM_REG);
1264 static void I386OP(movsx_r32_rm16)(i386_state *cpustate) // Opcode 0x0f bf
1266 UINT8 modrm = FETCH(cpustate);
1267 if( modrm >= 0xc0 ) {
1268 INT32 src = (INT16)LOAD_RM16(modrm);
1269 STORE_REG32(modrm, src);
1270 CYCLES(cpustate,CYCLES_MOVSX_REG_REG);
1272 UINT32 ea = GetEA(cpustate,modrm,0,2);
1273 INT32 src = (INT16)READ16(cpustate,ea);
1274 STORE_REG32(modrm, src);
1275 CYCLES(cpustate,CYCLES_MOVSX_MEM_REG);
1279 static void I386OP(movzx_r32_rm8)(i386_state *cpustate) // Opcode 0x0f b6
1281 UINT8 modrm = FETCH(cpustate);
1282 if( modrm >= 0xc0 ) {
1283 UINT32 src = (UINT8)LOAD_RM8(modrm);
1284 STORE_REG32(modrm, src);
1285 CYCLES(cpustate,CYCLES_MOVZX_REG_REG);
1287 UINT32 ea = GetEA(cpustate,modrm,0,1);
1288 UINT32 src = (UINT8)READ8(cpustate,ea);
1289 STORE_REG32(modrm, src);
1290 CYCLES(cpustate,CYCLES_MOVZX_MEM_REG);
1294 static void I386OP(movzx_r32_rm16)(i386_state *cpustate) // Opcode 0x0f b7
1296 UINT8 modrm = FETCH(cpustate);
1297 if( modrm >= 0xc0 ) {
1298 UINT32 src = (UINT16)LOAD_RM16(modrm);
1299 STORE_REG32(modrm, src);
1300 CYCLES(cpustate,CYCLES_MOVZX_REG_REG);
1302 UINT32 ea = GetEA(cpustate,modrm,0,2);
1303 UINT32 src = (UINT16)READ16(cpustate,ea);
1304 STORE_REG32(modrm, src);
1305 CYCLES(cpustate,CYCLES_MOVZX_MEM_REG);
1309 static void I386OP(or_rm32_r32)(i386_state *cpustate) // Opcode 0x09
1312 UINT8 modrm = FETCH(cpustate);
1313 if( modrm >= 0xc0 ) {
1314 src = LOAD_REG32(modrm);
1315 dst = LOAD_RM32(modrm);
1316 dst = OR32(cpustate,dst, src);
1317 STORE_RM32(modrm, dst);
1318 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1320 UINT32 ea = GetEA(cpustate,modrm,1,4);
1321 src = LOAD_REG32(modrm);
1322 dst = READ32(cpustate,ea);
1323 dst = OR32(cpustate,dst, src);
1324 WRITE32(cpustate,ea, dst);
1325 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1329 static void I386OP(or_r32_rm32)(i386_state *cpustate) // Opcode 0x0b
1332 UINT8 modrm = FETCH(cpustate);
1333 if( modrm >= 0xc0 ) {
1334 src = LOAD_RM32(modrm);
1335 dst = LOAD_REG32(modrm);
1336 dst = OR32(cpustate,dst, src);
1337 STORE_REG32(modrm, dst);
1338 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1340 UINT32 ea = GetEA(cpustate,modrm,0,4);
1341 src = READ32(cpustate,ea);
1342 dst = LOAD_REG32(modrm);
1343 dst = OR32(cpustate,dst, src);
1344 STORE_REG32(modrm, dst);
1345 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
1349 static void I386OP(or_eax_i32)(i386_state *cpustate) // Opcode 0x0d
1352 src = FETCH32(cpustate);
1354 dst = OR32(cpustate,dst, src);
1356 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1359 static void I386OP(out_eax_i8)(i386_state *cpustate) // Opcode 0xe7
1361 UINT16 port = FETCH(cpustate);
1362 UINT32 data = REG32(EAX);
1363 WRITEPORT32(cpustate, port, data);
1364 CYCLES(cpustate,CYCLES_OUT_VAR);
1367 static void I386OP(out_eax_dx)(i386_state *cpustate) // Opcode 0xef
1369 UINT16 port = REG16(DX);
1370 UINT32 data = REG32(EAX);
1371 WRITEPORT32(cpustate, port, data);
1372 CYCLES(cpustate,CYCLES_OUT);
1375 static void I386OP(pop_eax)(i386_state *cpustate) // Opcode 0x58
1377 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1378 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1379 REG32(EAX) = POP32(cpustate);
1382 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1385 static void I386OP(pop_ecx)(i386_state *cpustate) // Opcode 0x59
1387 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1388 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1389 REG32(ECX) = POP32(cpustate);
1392 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1395 static void I386OP(pop_edx)(i386_state *cpustate) // Opcode 0x5a
1397 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1398 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1399 REG32(EDX) = POP32(cpustate);
1402 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1405 static void I386OP(pop_ebx)(i386_state *cpustate) // Opcode 0x5b
1407 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1408 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1409 REG32(EBX) = POP32(cpustate);
1412 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1415 static void I386OP(pop_esp)(i386_state *cpustate) // Opcode 0x5c
1417 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1418 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1419 REG32(ESP) = POP32(cpustate);
1422 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1425 static void I386OP(pop_ebp)(i386_state *cpustate) // Opcode 0x5d
1427 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1428 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1429 REG32(EBP) = POP32(cpustate);
1432 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1435 static void I386OP(pop_esi)(i386_state *cpustate) // Opcode 0x5e
1437 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1438 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1439 REG32(ESI) = POP32(cpustate);
1442 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1445 static void I386OP(pop_edi)(i386_state *cpustate) // Opcode 0x5f
1447 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1448 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1449 REG32(EDI) = POP32(cpustate);
1452 CYCLES(cpustate,CYCLES_POP_REG_SHORT);
1455 static bool I386OP(pop_seg32)(i386_state *cpustate, int segment)
1457 UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1460 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1462 ea = i386_translate(cpustate, SS, offset, 0, 4);
1463 value = READ32(cpustate, ea);
1464 i386_sreg_load(cpustate,value, segment, &fault);
1465 if(fault) return false;
1467 REG32(ESP) = offset + 4;
1469 REG16(SP) = offset + 4;
1474 i386_trap_with_error(cpustate,FAULT_SS,0,0,0);
1477 CYCLES(cpustate,CYCLES_POP_SREG);
1481 static void I386OP(pop_ds32)(i386_state *cpustate) // Opcode 0x1f
1483 I386OP(pop_seg32)(cpustate, DS);
1486 static void I386OP(pop_es32)(i386_state *cpustate) // Opcode 0x07
1488 I386OP(pop_seg32)(cpustate, ES);
1491 static void I386OP(pop_fs32)(i386_state *cpustate) // Opcode 0x0f a1
1493 I386OP(pop_seg32)(cpustate, FS);
1496 static void I386OP(pop_gs32)(i386_state *cpustate) // Opcode 0x0f a9
1498 I386OP(pop_seg32)(cpustate, GS);
1501 static void I386OP(pop_ss32)(i386_state *cpustate) // Opcode 0x17
1503 if(!I386OP(pop_seg32)(cpustate, SS)) return;
1504 if(cpustate->IF != 0) // if external interrupts are enabled
1506 cpustate->IF = 0; // reset IF for the next instruction
1507 cpustate->delayed_interrupt_enable = 1;
1511 static void I386OP(pop_rm32)(i386_state *cpustate) // Opcode 0x8f
1513 UINT8 modrm = FETCH(cpustate);
1515 UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1516 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1518 // be careful here, if the write references the esp register
1519 // it expects the post-pop value but esp must be wound back
1520 // if the write faults
1521 UINT32 temp_sp = REG32(ESP);
1522 value = POP32(cpustate);
1524 if( modrm >= 0xc0 ) {
1525 STORE_RM32(modrm, value);
1527 ea = GetEA(cpustate,modrm,1,4);
1530 WRITE32(cpustate,ea, value);
1534 REG32(ESP) = temp_sp;
1541 CYCLES(cpustate,CYCLES_POP_RM);
1544 static void I386OP(popad)(i386_state *cpustate) // Opcode 0x61
1546 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1547 if(i386_limit_check(cpustate,SS,offset,32) == 0)
1549 REG32(EDI) = POP32(cpustate);
1550 REG32(ESI) = POP32(cpustate);
1551 REG32(EBP) = POP32(cpustate);
1553 REG32(EBX) = POP32(cpustate);
1554 REG32(EDX) = POP32(cpustate);
1555 REG32(ECX) = POP32(cpustate);
1556 REG32(EAX) = POP32(cpustate);
1560 CYCLES(cpustate,CYCLES_POPA);
1563 static void I386OP(popfd)(i386_state *cpustate) // Opcode 0x9d
1566 UINT32 current = get_flags(cpustate);
1567 UINT8 IOPL = (current >> 12) & 0x03;
1568 UINT32 mask = 0x00257fd5; // VM, VIP and VIF cannot be set by POPF/POPFD
1569 UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1571 // IOPL can only change if CPL is 0
1572 if(cpustate->CPL != 0)
1573 mask &= ~0x00003000;
1575 // IF can only change if CPL is at least as privileged as IOPL
1576 if(cpustate->CPL > IOPL)
1577 mask &= ~0x00000200;
1583 logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc);
1584 FAULT(FAULT_GP,0) // #GP(0)
1586 mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode
1589 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1591 value = POP32(cpustate);
1592 value &= ~0x00010000; // RF will always return zero
1593 set_flags(cpustate,(current & ~mask) | (value & mask)); // mask out reserved bits
1597 CYCLES(cpustate,CYCLES_POPF);
1600 static void I386OP(push_eax)(i386_state *cpustate) // Opcode 0x50
1604 offset = REG32(ESP) - 4;
1606 offset = (REG16(SP) - 4) & 0xffff;
1607 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1608 PUSH32(cpustate, REG32(EAX) );
1611 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1614 static void I386OP(push_ecx)(i386_state *cpustate) // Opcode 0x51
1618 offset = REG32(ESP) - 4;
1620 offset = (REG16(SP) - 4) & 0xffff;
1621 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1622 PUSH32(cpustate, REG32(ECX) );
1625 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1628 static void I386OP(push_edx)(i386_state *cpustate) // Opcode 0x52
1632 offset = REG32(ESP) - 4;
1634 offset = (REG16(SP) - 4) & 0xffff;
1635 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1636 PUSH32(cpustate, REG32(EDX) );
1639 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1642 static void I386OP(push_ebx)(i386_state *cpustate) // Opcode 0x53
1646 offset = REG32(ESP) - 4;
1648 offset = (REG16(SP) - 4) & 0xffff;
1649 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1650 PUSH32(cpustate, REG32(EBX) );
1653 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1656 static void I386OP(push_esp)(i386_state *cpustate) // Opcode 0x54
1660 offset = REG32(ESP) - 4;
1662 offset = (REG16(SP) - 4) & 0xffff;
1663 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1664 PUSH32(cpustate, REG32(ESP) );
1667 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1670 static void I386OP(push_ebp)(i386_state *cpustate) // Opcode 0x55
1674 offset = REG32(ESP) - 4;
1676 offset = (REG16(SP) - 4) & 0xffff;
1677 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1678 PUSH32(cpustate, REG32(EBP) );
1681 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1684 static void I386OP(push_esi)(i386_state *cpustate) // Opcode 0x56
1688 offset = REG32(ESP) - 4;
1690 offset = (REG16(SP) - 4) & 0xffff;
1691 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1692 PUSH32(cpustate, REG32(ESI) );
1695 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1698 static void I386OP(push_edi)(i386_state *cpustate) // Opcode 0x57
1702 offset = REG32(ESP) - 4;
1704 offset = (REG16(SP) - 4) & 0xffff;
1705 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1706 PUSH32(cpustate, REG32(EDI) );
1709 CYCLES(cpustate,CYCLES_PUSH_REG_SHORT);
1712 static void I386OP(push_cs32)(i386_state *cpustate) // Opcode 0x0e
1716 offset = REG32(ESP) - 4;
1718 offset = (REG16(SP) - 4) & 0xffff;
1719 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1720 PUSH32SEG(cpustate, cpustate->sreg[CS].selector );
1723 CYCLES(cpustate,CYCLES_PUSH_SREG);
1726 static void I386OP(push_ds32)(i386_state *cpustate) // Opcode 0x1e
1730 offset = REG32(ESP) - 4;
1732 offset = (REG16(SP) - 4) & 0xffff;
1733 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1734 PUSH32SEG(cpustate, cpustate->sreg[DS].selector );
1737 CYCLES(cpustate,CYCLES_PUSH_SREG);
1740 static void I386OP(push_es32)(i386_state *cpustate) // Opcode 0x06
1744 offset = REG32(ESP) - 4;
1746 offset = (REG16(SP) - 4) & 0xffff;
1747 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1748 PUSH32SEG(cpustate, cpustate->sreg[ES].selector );
1751 CYCLES(cpustate,CYCLES_PUSH_SREG);
1754 static void I386OP(push_fs32)(i386_state *cpustate) // Opcode 0x0f a0
1758 offset = REG32(ESP) - 4;
1760 offset = (REG16(SP) - 4) & 0xffff;
1761 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1762 PUSH32SEG(cpustate, cpustate->sreg[FS].selector );
1765 CYCLES(cpustate,CYCLES_PUSH_SREG);
1768 static void I386OP(push_gs32)(i386_state *cpustate) // Opcode 0x0f a8
1772 offset = REG32(ESP) - 4;
1774 offset = (REG16(SP) - 4) & 0xffff;
1775 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1776 PUSH32SEG(cpustate, cpustate->sreg[GS].selector );
1779 CYCLES(cpustate,CYCLES_PUSH_SREG);
1782 static void I386OP(push_ss32)(i386_state *cpustate) // Opcode 0x16
1786 offset = REG32(ESP) - 4;
1788 offset = (REG16(SP) - 4) & 0xffff;
1789 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1790 PUSH32SEG(cpustate, cpustate->sreg[SS].selector );
1793 CYCLES(cpustate,CYCLES_PUSH_SREG);
1796 static void I386OP(push_i32)(i386_state *cpustate) // Opcode 0x68
1798 UINT32 value = FETCH32(cpustate);
1801 offset = REG32(ESP) - 4;
1803 offset = (REG16(SP) - 4) & 0xffff;
1804 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1805 PUSH32(cpustate,value);
1808 CYCLES(cpustate,CYCLES_PUSH_IMM);
1811 static void I386OP(pushad)(i386_state *cpustate) // Opcode 0x60
1813 UINT32 temp = REG32(ESP);
1816 offset = REG32(ESP) - 32;
1818 offset = (REG16(SP) - 32) & 0xffff;
1819 if(i386_limit_check(cpustate,SS,offset,32) == 0)
1821 PUSH32(cpustate, REG32(EAX) );
1822 PUSH32(cpustate, REG32(ECX) );
1823 PUSH32(cpustate, REG32(EDX) );
1824 PUSH32(cpustate, REG32(EBX) );
1825 PUSH32(cpustate, temp );
1826 PUSH32(cpustate, REG32(EBP) );
1827 PUSH32(cpustate, REG32(ESI) );
1828 PUSH32(cpustate, REG32(EDI) );
1832 CYCLES(cpustate,CYCLES_PUSHA);
1835 static void I386OP(pushfd)(i386_state *cpustate) // Opcode 0x9c
1837 if(!cpustate->IOP1 && !cpustate->IOP2 && V8086_MODE)
1841 offset = REG32(ESP) - 4;
1843 offset = (REG16(SP) - 4) & 0xffff;
1844 if(i386_limit_check(cpustate,SS,offset,4) == 0)
1845 PUSH32(cpustate, get_flags(cpustate) & 0x00fcffff );
1848 CYCLES(cpustate,CYCLES_PUSHF);
1851 static void I386OP(ret_near32_i16)(i386_state *cpustate) // Opcode 0xc2
1853 INT16 disp = FETCH16(cpustate);
1854 cpustate->eip = POP32(cpustate);
1856 CHANGE_PC(cpustate,cpustate->eip);
1857 CYCLES(cpustate,CYCLES_RET_IMM); /* TODO: Timing = 10 + m */
1860 static void I386OP(ret_near32)(i386_state *cpustate) // Opcode 0xc3
1862 cpustate->eip = POP32(cpustate);
1863 CHANGE_PC(cpustate,cpustate->eip);
1864 CYCLES(cpustate,CYCLES_RET); /* TODO: Timing = 10 + m */
1867 static void I386OP(sbb_rm32_r32)(i386_state *cpustate) // Opcode 0x19
1870 UINT8 modrm = FETCH(cpustate);
1871 if( modrm >= 0xc0 ) {
1872 src = LOAD_REG32(modrm);
1873 dst = LOAD_RM32(modrm);
1874 dst = SBB32(cpustate, dst, src, cpustate->CF);
1875 STORE_RM32(modrm, dst);
1876 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1878 UINT32 ea = GetEA(cpustate,modrm,1,4);
1879 src = LOAD_REG32(modrm);
1880 dst = READ32(cpustate,ea);
1881 dst = SBB32(cpustate, dst, src, cpustate->CF);
1882 WRITE32(cpustate,ea, dst);
1883 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1887 static void I386OP(sbb_r32_rm32)(i386_state *cpustate) // Opcode 0x1b
1890 UINT8 modrm = FETCH(cpustate);
1891 if( modrm >= 0xc0 ) {
1892 src = LOAD_RM32(modrm);
1893 dst = LOAD_REG32(modrm);
1894 dst = SBB32(cpustate, dst, src, cpustate->CF);
1895 STORE_REG32(modrm, dst);
1896 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1898 UINT32 ea = GetEA(cpustate,modrm,0,4);
1899 src = READ32(cpustate,ea);
1900 dst = LOAD_REG32(modrm);
1901 dst = SBB32(cpustate, dst, src, cpustate->CF);
1902 STORE_REG32(modrm, dst);
1903 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
1907 static void I386OP(sbb_eax_i32)(i386_state *cpustate) // Opcode 0x1d
1910 src = FETCH32(cpustate);
1912 dst = SBB32(cpustate, dst, src, cpustate->CF);
1914 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1917 static void I386OP(scasd)(i386_state *cpustate) // Opcode 0xaf
1919 UINT32 eas, src, dst;
1920 eas = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0, 4 );
1921 src = READ32(cpustate,eas);
1923 SUB32(cpustate,dst, src);
1924 BUMP_DI(cpustate,4);
1925 CYCLES(cpustate,CYCLES_SCAS);
1928 static void I386OP(shld32_i8)(i386_state *cpustate) // Opcode 0x0f a4
1930 UINT8 modrm = FETCH(cpustate);
1931 if( modrm >= 0xc0 ) {
1932 UINT32 dst = LOAD_RM32(modrm);
1933 UINT32 upper = LOAD_REG32(modrm);
1934 UINT8 shift = FETCH(cpustate);
1938 cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
1939 dst = (dst << shift) | (upper >> (32-shift));
1940 cpustate->OF = cpustate->CF ^ (dst >> 31);
1943 STORE_RM32(modrm, dst);
1944 CYCLES(cpustate,CYCLES_SHLD_REG);
1946 UINT32 ea = GetEA(cpustate,modrm,1,4);
1947 UINT32 dst = READ32(cpustate,ea);
1948 UINT32 upper = LOAD_REG32(modrm);
1949 UINT8 shift = FETCH(cpustate);
1953 cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
1954 dst = (dst << shift) | (upper >> (32-shift));
1955 cpustate->OF = cpustate->CF ^ (dst >> 31);
1958 WRITE32(cpustate,ea, dst);
1959 CYCLES(cpustate,CYCLES_SHLD_MEM);
1963 static void I386OP(shld32_cl)(i386_state *cpustate) // Opcode 0x0f a5
1965 UINT8 modrm = FETCH(cpustate);
1966 if( modrm >= 0xc0 ) {
1967 UINT32 dst = LOAD_RM32(modrm);
1968 UINT32 upper = LOAD_REG32(modrm);
1969 UINT8 shift = REG8(CL);
1973 cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
1974 dst = (dst << shift) | (upper >> (32-shift));
1975 cpustate->OF = cpustate->CF ^ (dst >> 31);
1978 STORE_RM32(modrm, dst);
1979 CYCLES(cpustate,CYCLES_SHLD_REG);
1981 UINT32 ea = GetEA(cpustate,modrm,1,4);
1982 UINT32 dst = READ32(cpustate,ea);
1983 UINT32 upper = LOAD_REG32(modrm);
1984 UINT8 shift = REG8(CL);
1988 cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
1989 dst = (dst << shift) | (upper >> (32-shift));
1990 cpustate->OF = cpustate->CF ^ (dst >> 31);
1993 WRITE32(cpustate,ea, dst);
1994 CYCLES(cpustate,CYCLES_SHLD_MEM);
1998 static void I386OP(shrd32_i8)(i386_state *cpustate) // Opcode 0x0f ac
2000 UINT8 modrm = FETCH(cpustate);
2001 if( modrm >= 0xc0 ) {
2002 UINT32 dst = LOAD_RM32(modrm);
2003 UINT32 upper = LOAD_REG32(modrm);
2004 UINT8 shift = FETCH(cpustate);
2008 cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
2009 dst = (dst >> shift) | (upper << (32-shift));
2010 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
2013 STORE_RM32(modrm, dst);
2014 CYCLES(cpustate,CYCLES_SHRD_REG);
2016 UINT32 ea = GetEA(cpustate,modrm,1,4);
2017 UINT32 dst = READ32(cpustate,ea);
2018 UINT32 upper = LOAD_REG32(modrm);
2019 UINT8 shift = FETCH(cpustate);
2023 cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
2024 dst = (dst >> shift) | (upper << (32-shift));
2025 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
2028 WRITE32(cpustate,ea, dst);
2029 CYCLES(cpustate,CYCLES_SHRD_MEM);
2033 static void I386OP(shrd32_cl)(i386_state *cpustate) // Opcode 0x0f ad
2035 UINT8 modrm = FETCH(cpustate);
2036 if( modrm >= 0xc0 ) {
2037 UINT32 dst = LOAD_RM32(modrm);
2038 UINT32 upper = LOAD_REG32(modrm);
2039 UINT8 shift = REG8(CL);
2043 cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
2044 dst = (dst >> shift) | (upper << (32-shift));
2045 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
2048 STORE_RM32(modrm, dst);
2049 CYCLES(cpustate,CYCLES_SHRD_REG);
2051 UINT32 ea = GetEA(cpustate,modrm,1,4);
2052 UINT32 dst = READ32(cpustate,ea);
2053 UINT32 upper = LOAD_REG32(modrm);
2054 UINT8 shift = REG8(CL);
2058 cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
2059 dst = (dst >> shift) | (upper << (32-shift));
2060 cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
2063 WRITE32(cpustate,ea, dst);
2064 CYCLES(cpustate,CYCLES_SHRD_MEM);
2068 static void I386OP(stosd)(i386_state *cpustate) // Opcode 0xab
2070 UINT32 eas = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1, 4 );
2071 WRITE32(cpustate,eas, REG32(EAX));
2072 BUMP_DI(cpustate,4);
2073 CYCLES(cpustate,CYCLES_STOS);
2076 static void I386OP(sub_rm32_r32)(i386_state *cpustate) // Opcode 0x29
2079 UINT8 modrm = FETCH(cpustate);
2080 if( modrm >= 0xc0 ) {
2081 src = LOAD_REG32(modrm);
2082 dst = LOAD_RM32(modrm);
2083 dst = SUB32(cpustate,dst, src);
2084 STORE_RM32(modrm, dst);
2085 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2087 UINT32 ea = GetEA(cpustate,modrm,1,4);
2088 src = LOAD_REG32(modrm);
2089 dst = READ32(cpustate,ea);
2090 dst = SUB32(cpustate,dst, src);
2091 WRITE32(cpustate,ea, dst);
2092 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2096 static void I386OP(sub_r32_rm32)(i386_state *cpustate) // Opcode 0x2b
2099 UINT8 modrm = FETCH(cpustate);
2100 if( modrm >= 0xc0 ) {
2101 src = LOAD_RM32(modrm);
2102 dst = LOAD_REG32(modrm);
2103 dst = SUB32(cpustate,dst, src);
2104 STORE_REG32(modrm, dst);
2105 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2107 UINT32 ea = GetEA(cpustate,modrm,0,4);
2108 src = READ32(cpustate,ea);
2109 dst = LOAD_REG32(modrm);
2110 dst = SUB32(cpustate,dst, src);
2111 STORE_REG32(modrm, dst);
2112 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
2116 static void I386OP(sub_eax_i32)(i386_state *cpustate) // Opcode 0x2d
2119 src = FETCH32(cpustate);
2121 dst = SUB32(cpustate,dst, src);
2123 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
2126 static void I386OP(test_eax_i32)(i386_state *cpustate) // Opcode 0xa9
2128 UINT32 src = FETCH32(cpustate);
2129 UINT32 dst = REG32(EAX);
2134 CYCLES(cpustate,CYCLES_TEST_IMM_ACC);
2137 static void I386OP(test_rm32_r32)(i386_state *cpustate) // Opcode 0x85
2140 UINT8 modrm = FETCH(cpustate);
2141 if( modrm >= 0xc0 ) {
2142 src = LOAD_REG32(modrm);
2143 dst = LOAD_RM32(modrm);
2148 CYCLES(cpustate,CYCLES_TEST_REG_REG);
2150 UINT32 ea = GetEA(cpustate,modrm,0,4);
2151 src = LOAD_REG32(modrm);
2152 dst = READ32(cpustate,ea);
2157 CYCLES(cpustate,CYCLES_TEST_REG_MEM);
2161 static void I386OP(xchg_eax_ecx)(i386_state *cpustate) // Opcode 0x91
2165 REG32(EAX) = REG32(ECX);
2167 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2170 static void I386OP(xchg_eax_edx)(i386_state *cpustate) // Opcode 0x92
2174 REG32(EAX) = REG32(EDX);
2176 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2179 static void I386OP(xchg_eax_ebx)(i386_state *cpustate) // Opcode 0x93
2183 REG32(EAX) = REG32(EBX);
2185 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2188 static void I386OP(xchg_eax_esp)(i386_state *cpustate) // Opcode 0x94
2192 REG32(EAX) = REG32(ESP);
2194 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2197 static void I386OP(xchg_eax_ebp)(i386_state *cpustate) // Opcode 0x95
2201 REG32(EAX) = REG32(EBP);
2203 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2206 static void I386OP(xchg_eax_esi)(i386_state *cpustate) // Opcode 0x96
2210 REG32(EAX) = REG32(ESI);
2212 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2215 static void I386OP(xchg_eax_edi)(i386_state *cpustate) // Opcode 0x97
2219 REG32(EAX) = REG32(EDI);
2221 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2224 static void I386OP(xchg_r32_rm32)(i386_state *cpustate) // Opcode 0x87
2226 UINT8 modrm = FETCH(cpustate);
2227 if( modrm >= 0xc0 ) {
2228 UINT32 src = LOAD_RM32(modrm);
2229 UINT32 dst = LOAD_REG32(modrm);
2230 STORE_REG32(modrm, src);
2231 STORE_RM32(modrm, dst);
2232 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
2234 UINT32 ea = GetEA(cpustate,modrm,1,4);
2235 UINT32 src = READ32(cpustate,ea);
2236 UINT32 dst = LOAD_REG32(modrm);
2237 WRITE32(cpustate,ea, dst);
2238 STORE_REG32(modrm, src);
2239 CYCLES(cpustate,CYCLES_XCHG_REG_MEM);
2243 static void I386OP(xor_rm32_r32)(i386_state *cpustate) // Opcode 0x31
2246 UINT8 modrm = FETCH(cpustate);
2247 if( modrm >= 0xc0 ) {
2248 src = LOAD_REG32(modrm);
2249 dst = LOAD_RM32(modrm);
2250 dst = XOR32(cpustate,dst, src);
2251 STORE_RM32(modrm, dst);
2252 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2254 UINT32 ea = GetEA(cpustate,modrm,1,4);
2255 src = LOAD_REG32(modrm);
2256 dst = READ32(cpustate,ea);
2257 dst = XOR32(cpustate,dst, src);
2258 WRITE32(cpustate,ea, dst);
2259 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2263 static void I386OP(xor_r32_rm32)(i386_state *cpustate) // Opcode 0x33
2266 UINT8 modrm = FETCH(cpustate);
2267 if( modrm >= 0xc0 ) {
2268 src = LOAD_RM32(modrm);
2269 dst = LOAD_REG32(modrm);
2270 dst = XOR32(cpustate,dst, src);
2271 STORE_REG32(modrm, dst);
2272 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2274 UINT32 ea = GetEA(cpustate,modrm,0,4);
2275 src = READ32(cpustate,ea);
2276 dst = LOAD_REG32(modrm);
2277 dst = XOR32(cpustate,dst, src);
2278 STORE_REG32(modrm, dst);
2279 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
2283 static void I386OP(xor_eax_i32)(i386_state *cpustate) // Opcode 0x35
2286 src = FETCH32(cpustate);
2288 dst = XOR32(cpustate,dst, src);
2290 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
2295 static void I386OP(group81_32)(i386_state *cpustate) // Opcode 0x81
2299 UINT8 modrm = FETCH(cpustate);
2301 switch( (modrm >> 3) & 0x7 )
2303 case 0: // ADD Rm32, i32
2304 if( modrm >= 0xc0 ) {
2305 dst = LOAD_RM32(modrm);
2306 src = FETCH32(cpustate);
2307 dst = ADD32(cpustate,dst, src);
2308 STORE_RM32(modrm, dst);
2309 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2311 ea = GetEA(cpustate,modrm,1,4);
2312 dst = READ32(cpustate,ea);
2313 src = FETCH32(cpustate);
2314 dst = ADD32(cpustate,dst, src);
2315 WRITE32(cpustate,ea, dst);
2316 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2319 case 1: // OR Rm32, i32
2320 if( modrm >= 0xc0 ) {
2321 dst = LOAD_RM32(modrm);
2322 src = FETCH32(cpustate);
2323 dst = OR32(cpustate,dst, src);
2324 STORE_RM32(modrm, dst);
2325 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2327 ea = GetEA(cpustate,modrm,1,4);
2328 dst = READ32(cpustate,ea);
2329 src = FETCH32(cpustate);
2330 dst = OR32(cpustate,dst, src);
2331 WRITE32(cpustate,ea, dst);
2332 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2335 case 2: // ADC Rm32, i32
2336 if( modrm >= 0xc0 ) {
2337 dst = LOAD_RM32(modrm);
2338 src = FETCH32(cpustate);
2339 dst = ADC32(cpustate, dst, src, cpustate->CF);
2340 STORE_RM32(modrm, dst);
2341 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2343 ea = GetEA(cpustate,modrm,1,4);
2344 dst = READ32(cpustate,ea);
2345 src = FETCH32(cpustate);
2346 dst = ADC32(cpustate, dst, src, cpustate->CF);
2347 WRITE32(cpustate,ea, dst);
2348 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2351 case 3: // SBB Rm32, i32
2352 if( modrm >= 0xc0 ) {
2353 dst = LOAD_RM32(modrm);
2354 src = FETCH32(cpustate);
2355 dst = SBB32(cpustate, dst, src, cpustate->CF);
2356 STORE_RM32(modrm, dst);
2357 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2359 ea = GetEA(cpustate,modrm,1,4);
2360 dst = READ32(cpustate,ea);
2361 src = FETCH32(cpustate);
2362 dst = SBB32(cpustate, dst, src, cpustate->CF);
2363 WRITE32(cpustate,ea, dst);
2364 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2367 case 4: // AND Rm32, i32
2368 if( modrm >= 0xc0 ) {
2369 dst = LOAD_RM32(modrm);
2370 src = FETCH32(cpustate);
2371 dst = AND32(cpustate,dst, src);
2372 STORE_RM32(modrm, dst);
2373 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2375 ea = GetEA(cpustate,modrm,1,4);
2376 dst = READ32(cpustate,ea);
2377 src = FETCH32(cpustate);
2378 dst = AND32(cpustate,dst, src);
2379 WRITE32(cpustate,ea, dst);
2380 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2383 case 5: // SUB Rm32, i32
2384 if( modrm >= 0xc0 ) {
2385 dst = LOAD_RM32(modrm);
2386 src = FETCH32(cpustate);
2387 dst = SUB32(cpustate,dst, src);
2388 STORE_RM32(modrm, dst);
2389 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2391 ea = GetEA(cpustate,modrm,1,4);
2392 dst = READ32(cpustate,ea);
2393 src = FETCH32(cpustate);
2394 dst = SUB32(cpustate,dst, src);
2395 WRITE32(cpustate,ea, dst);
2396 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2399 case 6: // XOR Rm32, i32
2400 if( modrm >= 0xc0 ) {
2401 dst = LOAD_RM32(modrm);
2402 src = FETCH32(cpustate);
2403 dst = XOR32(cpustate,dst, src);
2404 STORE_RM32(modrm, dst);
2405 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2407 ea = GetEA(cpustate,modrm,1,4);
2408 dst = READ32(cpustate,ea);
2409 src = FETCH32(cpustate);
2410 dst = XOR32(cpustate,dst, src);
2411 WRITE32(cpustate,ea, dst);
2412 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2415 case 7: // CMP Rm32, i32
2416 if( modrm >= 0xc0 ) {
2417 dst = LOAD_RM32(modrm);
2418 src = FETCH32(cpustate);
2419 SUB32(cpustate,dst, src);
2420 CYCLES(cpustate,CYCLES_CMP_REG_REG);
2422 ea = GetEA(cpustate,modrm,0,4);
2423 dst = READ32(cpustate,ea);
2424 src = FETCH32(cpustate);
2425 SUB32(cpustate,dst, src);
2426 CYCLES(cpustate,CYCLES_CMP_REG_MEM);
2432 static void I386OP(group83_32)(i386_state *cpustate) // Opcode 0x83
2436 UINT8 modrm = FETCH(cpustate);
2438 switch( (modrm >> 3) & 0x7 )
2440 case 0: // ADD Rm32, i32
2441 if( modrm >= 0xc0 ) {
2442 dst = LOAD_RM32(modrm);
2443 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2444 dst = ADD32(cpustate,dst, src);
2445 STORE_RM32(modrm, dst);
2446 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2448 ea = GetEA(cpustate,modrm,1,4);
2449 dst = READ32(cpustate,ea);
2450 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2451 dst = ADD32(cpustate,dst, src);
2452 WRITE32(cpustate,ea, dst);
2453 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2456 case 1: // OR Rm32, i32
2457 if( modrm >= 0xc0 ) {
2458 dst = LOAD_RM32(modrm);
2459 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2460 dst = OR32(cpustate,dst, src);
2461 STORE_RM32(modrm, dst);
2462 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2464 ea = GetEA(cpustate,modrm,1,4);
2465 dst = READ32(cpustate,ea);
2466 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2467 dst = OR32(cpustate,dst, src);
2468 WRITE32(cpustate,ea, dst);
2469 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2472 case 2: // ADC Rm32, i32
2473 if( modrm >= 0xc0 ) {
2474 dst = LOAD_RM32(modrm);
2475 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2476 dst = ADC32(cpustate, dst, src, cpustate->CF);
2477 STORE_RM32(modrm, dst);
2478 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2480 ea = GetEA(cpustate,modrm,1,4);
2481 dst = READ32(cpustate,ea);
2482 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2483 dst = ADC32(cpustate, dst, src, cpustate->CF);
2484 WRITE32(cpustate,ea, dst);
2485 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2488 case 3: // SBB Rm32, i32
2489 if( modrm >= 0xc0 ) {
2490 dst = LOAD_RM32(modrm);
2491 src = ((UINT32)(INT32)(INT8)FETCH(cpustate));
2492 dst = SBB32(cpustate, dst, src, cpustate->CF);
2493 STORE_RM32(modrm, dst);
2494 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2496 ea = GetEA(cpustate,modrm,1,4);
2497 dst = READ32(cpustate,ea);
2498 src = ((UINT32)(INT32)(INT8)FETCH(cpustate));
2499 dst = SBB32(cpustate, dst, src, cpustate->CF);
2500 WRITE32(cpustate,ea, dst);
2501 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2504 case 4: // AND Rm32, i32
2505 if( modrm >= 0xc0 ) {
2506 dst = LOAD_RM32(modrm);
2507 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2508 dst = AND32(cpustate,dst, src);
2509 STORE_RM32(modrm, dst);
2510 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2512 ea = GetEA(cpustate,modrm,1,4);
2513 dst = READ32(cpustate,ea);
2514 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2515 dst = AND32(cpustate,dst, src);
2516 WRITE32(cpustate,ea, dst);
2517 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2520 case 5: // SUB Rm32, i32
2521 if( modrm >= 0xc0 ) {
2522 dst = LOAD_RM32(modrm);
2523 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2524 dst = SUB32(cpustate,dst, src);
2525 STORE_RM32(modrm, dst);
2526 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2528 ea = GetEA(cpustate,modrm,1,4);
2529 dst = READ32(cpustate,ea);
2530 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2531 dst = SUB32(cpustate,dst, src);
2532 WRITE32(cpustate,ea, dst);
2533 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2536 case 6: // XOR Rm32, i32
2537 if( modrm >= 0xc0 ) {
2538 dst = LOAD_RM32(modrm);
2539 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2540 dst = XOR32(cpustate,dst, src);
2541 STORE_RM32(modrm, dst);
2542 CYCLES(cpustate,CYCLES_ALU_REG_REG);
2544 ea = GetEA(cpustate,modrm,1,4);
2545 dst = READ32(cpustate,ea);
2546 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2547 dst = XOR32(cpustate,dst, src);
2548 WRITE32(cpustate,ea, dst);
2549 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
2552 case 7: // CMP Rm32, i32
2553 if( modrm >= 0xc0 ) {
2554 dst = LOAD_RM32(modrm);
2555 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2556 SUB32(cpustate,dst, src);
2557 CYCLES(cpustate,CYCLES_CMP_REG_REG);
2559 ea = GetEA(cpustate,modrm,0,4);
2560 dst = READ32(cpustate,ea);
2561 src = (UINT32)(INT32)(INT8)FETCH(cpustate);
2562 SUB32(cpustate,dst, src);
2563 CYCLES(cpustate,CYCLES_CMP_REG_MEM);
2569 static void I386OP(groupC1_32)(i386_state *cpustate) // Opcode 0xc1
2572 UINT8 modrm = FETCH(cpustate);
2575 if( modrm >= 0xc0 ) {
2576 dst = LOAD_RM32(modrm);
2577 shift = FETCH(cpustate) & 0x1f;
2578 dst = i386_shift_rotate32(cpustate, modrm, dst, shift);
2579 STORE_RM32(modrm, dst);
2581 UINT32 ea = GetEA(cpustate,modrm,1,4);
2582 dst = READ32(cpustate,ea);
2583 shift = FETCH(cpustate) & 0x1f;
2584 dst = i386_shift_rotate32(cpustate, modrm, dst, shift);
2585 WRITE32(cpustate,ea, dst);
2589 static void I386OP(groupD1_32)(i386_state *cpustate) // Opcode 0xd1
2592 UINT8 modrm = FETCH(cpustate);
2594 if( modrm >= 0xc0 ) {
2595 dst = LOAD_RM32(modrm);
2596 dst = i386_shift_rotate32(cpustate, modrm, dst, 1);
2597 STORE_RM32(modrm, dst);
2599 UINT32 ea = GetEA(cpustate,modrm,1,4);
2600 dst = READ32(cpustate,ea);
2601 dst = i386_shift_rotate32(cpustate, modrm, dst, 1);
2602 WRITE32(cpustate,ea, dst);
2606 static void I386OP(groupD3_32)(i386_state *cpustate) // Opcode 0xd3
2609 UINT8 modrm = FETCH(cpustate);
2611 if( modrm >= 0xc0 ) {
2612 dst = LOAD_RM32(modrm);
2613 dst = i386_shift_rotate32(cpustate, modrm, dst, REG8(CL));
2614 STORE_RM32(modrm, dst);
2616 UINT32 ea = GetEA(cpustate,modrm,1,4);
2617 dst = READ32(cpustate,ea);
2618 dst = i386_shift_rotate32(cpustate, modrm, dst, REG8(CL));
2619 WRITE32(cpustate,ea, dst);
2623 static void I386OP(groupF7_32)(i386_state *cpustate) // Opcode 0xf7
2625 UINT8 modrm = FETCH(cpustate);
2627 switch( (modrm >> 3) & 0x7 )
2629 case 0: /* TEST Rm32, i32 */
2630 if( modrm >= 0xc0 ) {
2631 UINT32 dst = LOAD_RM32(modrm);
2632 UINT32 src = FETCH32(cpustate);
2634 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2636 CYCLES(cpustate,CYCLES_TEST_IMM_REG);
2638 UINT32 ea = GetEA(cpustate,modrm,0,4);
2639 UINT32 dst = READ32(cpustate,ea);
2640 UINT32 src = FETCH32(cpustate);
2642 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2644 CYCLES(cpustate,CYCLES_TEST_IMM_MEM);
2647 case 2: /* NOT Rm32 */
2648 if( modrm >= 0xc0 ) {
2649 UINT32 dst = LOAD_RM32(modrm);
2651 STORE_RM32(modrm, dst);
2652 CYCLES(cpustate,CYCLES_NOT_REG);
2654 UINT32 ea = GetEA(cpustate,modrm,1,4);
2655 UINT32 dst = READ32(cpustate,ea);
2657 WRITE32(cpustate,ea, dst);
2658 CYCLES(cpustate,CYCLES_NOT_MEM);
2661 case 3: /* NEG Rm32 */
2662 if( modrm >= 0xc0 ) {
2663 UINT32 dst = LOAD_RM32(modrm);
2664 dst = SUB32(cpustate, 0, dst );
2665 STORE_RM32(modrm, dst);
2666 CYCLES(cpustate,CYCLES_NEG_REG);
2668 UINT32 ea = GetEA(cpustate,modrm,1,4);
2669 UINT32 dst = READ32(cpustate,ea);
2670 dst = SUB32(cpustate, 0, dst );
2671 WRITE32(cpustate,ea, dst);
2672 CYCLES(cpustate,CYCLES_NEG_MEM);
2675 case 4: /* MUL EAX, Rm32 */
2679 if( modrm >= 0xc0 ) {
2680 src = LOAD_RM32(modrm);
2681 CYCLES(cpustate,CYCLES_MUL32_ACC_REG); /* TODO: Correct multiply timing */
2683 UINT32 ea = GetEA(cpustate,modrm,0,4);
2684 src = READ32(cpustate,ea);
2685 CYCLES(cpustate,CYCLES_MUL32_ACC_MEM); /* TODO: Correct multiply timing */
2689 result = (UINT64)src * (UINT64)dst;
2690 REG32(EDX) = (UINT32)(result >> 32);
2691 REG32(EAX) = (UINT32)result;
2693 cpustate->CF = cpustate->OF = (REG32(EDX) != 0);
2696 case 5: /* IMUL EAX, Rm32 */
2700 if( modrm >= 0xc0 ) {
2701 src = (INT64)(INT32)LOAD_RM32(modrm);
2702 CYCLES(cpustate,CYCLES_IMUL32_ACC_REG); /* TODO: Correct multiply timing */
2704 UINT32 ea = GetEA(cpustate,modrm,0,4);
2705 src = (INT64)(INT32)READ32(cpustate,ea);
2706 CYCLES(cpustate,CYCLES_IMUL32_ACC_MEM); /* TODO: Correct multiply timing */
2709 dst = (INT64)(INT32)REG32(EAX);
2712 REG32(EDX) = (UINT32)(result >> 32);
2713 REG32(EAX) = (UINT32)result;
2715 cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
2718 case 6: /* DIV EAX, Rm32 */
2720 UINT64 quotient, remainder, result;
2722 if( modrm >= 0xc0 ) {
2723 src = LOAD_RM32(modrm);
2724 CYCLES(cpustate,CYCLES_DIV32_ACC_REG);
2726 UINT32 ea = GetEA(cpustate,modrm,0,4);
2727 src = READ32(cpustate,ea);
2728 CYCLES(cpustate,CYCLES_DIV32_ACC_MEM);
2731 quotient = ((UINT64)(REG32(EDX)) << 32) | (UINT64)(REG32(EAX));
2733 remainder = quotient % (UINT64)src;
2734 result = quotient / (UINT64)src;
2735 if( result > 0xffffffff ) {
2736 /* TODO: Divide error */
2738 REG32(EDX) = (UINT32)remainder;
2739 REG32(EAX) = (UINT32)result;
2742 i386_trap(cpustate, 0, 0, 0);
2746 case 7: /* IDIV EAX, Rm32 */
2748 INT64 quotient, remainder, result;
2750 if( modrm >= 0xc0 ) {
2751 src = LOAD_RM32(modrm);
2752 CYCLES(cpustate,CYCLES_IDIV32_ACC_REG);
2754 UINT32 ea = GetEA(cpustate,modrm,0,4);
2755 src = READ32(cpustate,ea);
2756 CYCLES(cpustate,CYCLES_IDIV32_ACC_MEM);
2759 quotient = (((INT64)REG32(EDX)) << 32) | ((UINT64)REG32(EAX));
2761 remainder = quotient % (INT64)(INT32)src;
2762 result = quotient / (INT64)(INT32)src;
2763 if( result > 0xffffffff ) {
2764 /* TODO: Divide error */
2766 REG32(EDX) = (UINT32)remainder;
2767 REG32(EAX) = (UINT32)result;
2770 i386_trap(cpustate, 0, 0, 0);
2777 static void I386OP(groupFF_32)(i386_state *cpustate) // Opcode 0xff
2779 UINT8 modrm = FETCH(cpustate);
2781 switch( (modrm >> 3) & 0x7 )
2783 case 0: /* INC Rm32 */
2784 if( modrm >= 0xc0 ) {
2785 UINT32 dst = LOAD_RM32(modrm);
2786 dst = INC32(cpustate,dst);
2787 STORE_RM32(modrm, dst);
2788 CYCLES(cpustate,CYCLES_INC_REG);
2790 UINT32 ea = GetEA(cpustate,modrm,1,4);
2791 UINT32 dst = READ32(cpustate,ea);
2792 dst = INC32(cpustate,dst);
2793 WRITE32(cpustate,ea, dst);
2794 CYCLES(cpustate,CYCLES_INC_MEM);
2797 case 1: /* DEC Rm32 */
2798 if( modrm >= 0xc0 ) {
2799 UINT32 dst = LOAD_RM32(modrm);
2800 dst = DEC32(cpustate,dst);
2801 STORE_RM32(modrm, dst);
2802 CYCLES(cpustate,CYCLES_DEC_REG);
2804 UINT32 ea = GetEA(cpustate,modrm,1,4);
2805 UINT32 dst = READ32(cpustate,ea);
2806 dst = DEC32(cpustate,dst);
2807 WRITE32(cpustate,ea, dst);
2808 CYCLES(cpustate,CYCLES_DEC_MEM);
2811 case 2: /* CALL Rm32 */
2814 if( modrm >= 0xc0 ) {
2815 address = LOAD_RM32(modrm);
2816 CYCLES(cpustate,CYCLES_CALL_REG); /* TODO: Timing = 7 + m */
2818 UINT32 ea = GetEA(cpustate,modrm,0,4);
2819 address = READ32(cpustate,ea);
2820 CYCLES(cpustate,CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */
2822 PUSH32(cpustate, cpustate->eip );
2823 cpustate->eip = address;
2824 CHANGE_PC(cpustate,cpustate->eip);
2827 case 3: /* CALL FAR Rm32 */
2834 report_invalid_modrm(cpustate, "groupFF_32", modrm);
2838 UINT32 ea = GetEA(cpustate,modrm,0,6);
2839 address = READ32(cpustate,ea + 0);
2840 selector = READ16(cpustate,ea + 4);
2841 CYCLES(cpustate,CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */
2842 if(PROTECTED_MODE && !V8086_MODE)
2844 i386_protected_mode_call(cpustate,selector,address,1,1);
2848 PUSH32SEG(cpustate, cpustate->sreg[CS].selector );
2849 PUSH32(cpustate, cpustate->eip );
2850 cpustate->sreg[CS].selector = selector;
2851 cpustate->performed_intersegment_jump = 1;
2852 i386_load_segment_descriptor(cpustate, CS );
2853 cpustate->eip = address;
2854 CHANGE_PC(cpustate,cpustate->eip);
2859 case 4: /* JMP Rm32 */
2862 if( modrm >= 0xc0 ) {
2863 address = LOAD_RM32(modrm);
2864 CYCLES(cpustate,CYCLES_JMP_REG); /* TODO: Timing = 7 + m */
2866 UINT32 ea = GetEA(cpustate,modrm,0,4);
2867 address = READ32(cpustate,ea);
2868 CYCLES(cpustate,CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */
2870 cpustate->eip = address;
2871 CHANGE_PC(cpustate,cpustate->eip);
2874 case 5: /* JMP FAR Rm32 */
2881 report_invalid_modrm(cpustate, "groupFF_32", modrm);
2885 UINT32 ea = GetEA(cpustate,modrm,0,6);
2886 address = READ32(cpustate,ea + 0);
2887 selector = READ16(cpustate,ea + 4);
2888 CYCLES(cpustate,CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */
2889 if(PROTECTED_MODE && !V8086_MODE)
2891 i386_protected_mode_jump(cpustate,selector,address,1,1);
2895 cpustate->sreg[CS].selector = selector;
2896 cpustate->performed_intersegment_jump = 1;
2897 i386_load_segment_descriptor(cpustate, CS );
2898 cpustate->eip = address;
2899 CHANGE_PC(cpustate,cpustate->eip);
2904 case 6: /* PUSH Rm32 */
2907 if( modrm >= 0xc0 ) {
2908 value = LOAD_RM32(modrm);
2910 UINT32 ea = GetEA(cpustate,modrm,0,4);
2911 value = READ32(cpustate,ea);
2913 PUSH32(cpustate,value);
2914 CYCLES(cpustate,CYCLES_PUSH_RM);
2918 report_invalid_modrm(cpustate, "groupFF_32", modrm);
2923 static void I386OP(group0F00_32)(i386_state *cpustate) // Opcode 0x0f 00
2926 UINT8 modrm = FETCH(cpustate);
2930 switch( (modrm >> 3) & 0x7 )
2933 if ( PROTECTED_MODE && !V8086_MODE )
2935 if( modrm >= 0xc0 ) {
2936 STORE_RM32(modrm, cpustate->ldtr.segment);
2937 CYCLES(cpustate,CYCLES_SLDT_REG);
2939 ea = GetEA(cpustate,modrm,1,2);
2940 WRITE16(cpustate, ea, cpustate->ldtr.segment);
2941 CYCLES(cpustate,CYCLES_SLDT_MEM);
2946 i386_trap(cpustate,6, 0, 0);
2950 if ( PROTECTED_MODE && !V8086_MODE )
2952 if( modrm >= 0xc0 ) {
2953 STORE_RM32(modrm, cpustate->task.segment);
2954 CYCLES(cpustate,CYCLES_STR_REG);
2956 ea = GetEA(cpustate,modrm,1,2);
2957 WRITE16(cpustate, ea, cpustate->task.segment);
2958 CYCLES(cpustate,CYCLES_STR_MEM);
2963 i386_trap(cpustate,6, 0, 0);
2967 if ( PROTECTED_MODE && !V8086_MODE )
2971 if( modrm >= 0xc0 ) {
2972 address = LOAD_RM32(modrm);
2973 cpustate->ldtr.segment = address;
2974 CYCLES(cpustate,CYCLES_LLDT_REG);
2976 ea = GetEA(cpustate,modrm,0,4);
2977 cpustate->ldtr.segment = READ32(cpustate,ea);
2978 CYCLES(cpustate,CYCLES_LLDT_MEM);
2980 memset(&seg, 0, sizeof(seg));
2981 seg.selector = cpustate->ldtr.segment;
2982 i386_load_protected_mode_segment(cpustate,&seg,NULL);
2983 cpustate->ldtr.limit = seg.limit;
2984 cpustate->ldtr.base = seg.base;
2985 cpustate->ldtr.flags = seg.flags;
2989 i386_trap(cpustate,6, 0, 0);
2994 if ( PROTECTED_MODE && !V8086_MODE )
2998 if( modrm >= 0xc0 ) {
2999 address = LOAD_RM32(modrm);
3000 cpustate->task.segment = address;
3001 CYCLES(cpustate,CYCLES_LTR_REG);
3003 ea = GetEA(cpustate,modrm,0,4);
3004 cpustate->task.segment = READ32(cpustate,ea);
3005 CYCLES(cpustate,CYCLES_LTR_MEM);
3007 memset(&seg, 0, sizeof(seg));
3008 seg.selector = cpustate->task.segment;
3009 i386_load_protected_mode_segment(cpustate,&seg,NULL);
3011 UINT32 addr = ((seg.selector & 4) ? cpustate->ldtr.base : cpustate->gdtr.base) + (seg.selector & ~7) + 5;
3012 i386_translate_address(cpustate, TRANSLATE_READ, &addr, NULL);
3013 cpustate->program->write_data8(addr, (seg.flags & 0xff) | 2);
3015 cpustate->task.limit = seg.limit;
3016 cpustate->task.base = seg.base;
3017 cpustate->task.flags = seg.flags | 2;
3021 i386_trap(cpustate,6, 0, 0);
3026 if ( PROTECTED_MODE && !V8086_MODE )
3028 if( modrm >= 0xc0 ) {
3029 address = LOAD_RM32(modrm);
3030 CYCLES(cpustate,CYCLES_VERR_REG);
3032 ea = GetEA(cpustate,modrm,0,4);
3033 address = READ32(cpustate,ea);
3034 CYCLES(cpustate,CYCLES_VERR_MEM);
3036 memset(&seg, 0, sizeof(seg));
3037 seg.selector = address;
3038 result = i386_load_protected_mode_segment(cpustate,&seg,NULL);
3039 // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3040 if(!(seg.flags & 0x10))
3042 // check that the segment is readable
3043 if(seg.flags & 0x10) // is code or data segment
3045 if(seg.flags & 0x08) // is code segment, so check if it's readable
3047 if(!(seg.flags & 0x02))
3052 { // check if conforming, these are always readable, regardless of privilege
3053 if(!(seg.flags & 0x04))
3055 // if not conforming, then we must check privilege levels (TODO: current privilege level check)
3056 if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3062 // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3067 i386_trap(cpustate,6, 0, 0);
3068 logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
3073 if ( PROTECTED_MODE && !V8086_MODE )
3075 if( modrm >= 0xc0 ) {
3076 address = LOAD_RM16(modrm);
3077 CYCLES(cpustate,CYCLES_VERW_REG);
3079 ea = GetEA(cpustate,modrm,0,2);
3080 address = READ16(cpustate,ea);
3081 CYCLES(cpustate,CYCLES_VERW_MEM);
3083 memset(&seg, 0, sizeof(seg));
3084 seg.selector = address;
3085 result = i386_load_protected_mode_segment(cpustate,&seg,NULL);
3086 // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3087 if(!(seg.flags & 0x10))
3089 // check that the segment is writable
3090 if(seg.flags & 0x10) // is code or data segment
3092 if(seg.flags & 0x08) // is code segment (and thus, not writable)
3097 { // is data segment
3098 if(!(seg.flags & 0x02))
3102 // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3103 if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3109 i386_trap(cpustate,6, 0, 0);
3110 logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3115 report_invalid_modrm(cpustate, "group0F00_32", modrm);
3120 static void I386OP(group0F01_32)(i386_state *cpustate) // Opcode 0x0f 01
3122 UINT8 modrm = FETCH(cpustate);
3125 switch( (modrm >> 3) & 0x7 )
3129 if( modrm >= 0xc0 ) {
3130 address = LOAD_RM32(modrm);
3131 ea = i386_translate(cpustate, CS, address, 1, 6 );
3133 ea = GetEA(cpustate,modrm,1,6);
3135 WRITE16(cpustate,ea, cpustate->gdtr.limit);
3136 WRITE32(cpustate,ea + 2, cpustate->gdtr.base);
3137 CYCLES(cpustate,CYCLES_SGDT);
3144 address = LOAD_RM32(modrm);
3145 ea = i386_translate(cpustate, CS, address, 1, 6 );
3149 ea = GetEA(cpustate,modrm,1,6);
3151 WRITE16(cpustate,ea, cpustate->idtr.limit);
3152 WRITE32(cpustate,ea + 2, cpustate->idtr.base);
3153 CYCLES(cpustate,CYCLES_SIDT);
3158 if(PROTECTED_MODE && cpustate->CPL)
3160 if( modrm >= 0xc0 ) {
3161 address = LOAD_RM32(modrm);
3162 ea = i386_translate(cpustate, CS, address, 0, 6 );
3164 ea = GetEA(cpustate,modrm,0,6);
3166 cpustate->gdtr.limit = READ16(cpustate,ea);
3167 cpustate->gdtr.base = READ32(cpustate,ea + 2);
3168 CYCLES(cpustate,CYCLES_LGDT);
3173 if(PROTECTED_MODE && cpustate->CPL)
3175 if( modrm >= 0xc0 ) {
3176 address = LOAD_RM32(modrm);
3177 ea = i386_translate(cpustate, CS, address, 0, 6 );
3179 ea = GetEA(cpustate,modrm,0,6);
3181 cpustate->idtr.limit = READ16(cpustate,ea);
3182 cpustate->idtr.base = READ32(cpustate,ea + 2);
3183 CYCLES(cpustate,CYCLES_LIDT);
3188 if( modrm >= 0xc0 ) {
3189 // smsw stores all of cr0 into register
3190 STORE_RM32(modrm, cpustate->cr[0]);
3191 CYCLES(cpustate,CYCLES_SMSW_REG);
3193 /* always 16-bit memory operand */
3194 ea = GetEA(cpustate,modrm,1,2);
3195 WRITE16(cpustate,ea, cpustate->cr[0]);
3196 CYCLES(cpustate,CYCLES_SMSW_MEM);
3202 if(PROTECTED_MODE && cpustate->CPL)
3205 if( modrm >= 0xc0 ) {
3206 b = LOAD_RM16(modrm);
3207 CYCLES(cpustate,CYCLES_LMSW_REG);
3209 ea = GetEA(cpustate,modrm,0,2);
3210 CYCLES(cpustate,CYCLES_LMSW_MEM);
3211 b = READ16(cpustate,ea);
3214 b |= 0x0001; // cannot return to real mode using this instruction.
3215 cpustate->cr[0] &= ~0x0000000f;
3216 cpustate->cr[0] |= b & 0x0000000f;
3220 report_invalid_modrm(cpustate, "group0F01_32", modrm);
3225 static void I386OP(group0FBA_32)(i386_state *cpustate) // Opcode 0x0f ba
3227 UINT8 modrm = FETCH(cpustate);
3229 switch( (modrm >> 3) & 0x7 )
3231 case 4: /* BT Rm32, i8 */
3232 if( modrm >= 0xc0 ) {
3233 UINT32 dst = LOAD_RM32(modrm);
3234 UINT8 bit = FETCH(cpustate);
3236 if( dst & (1 << bit) )
3241 CYCLES(cpustate,CYCLES_BT_IMM_REG);
3243 UINT32 ea = GetEA(cpustate,modrm,0,4);
3244 UINT32 dst = READ32(cpustate,ea);
3245 UINT8 bit = FETCH(cpustate);
3247 if( dst & (1 << bit) )
3252 CYCLES(cpustate,CYCLES_BT_IMM_MEM);
3255 case 5: /* BTS Rm32, i8 */
3256 if( modrm >= 0xc0 ) {
3257 UINT32 dst = LOAD_RM32(modrm);
3258 UINT8 bit = FETCH(cpustate);
3260 if( dst & (1 << bit) )
3266 STORE_RM32(modrm, dst);
3267 CYCLES(cpustate,CYCLES_BTS_IMM_REG);
3269 UINT32 ea = GetEA(cpustate,modrm,1,4);
3270 UINT32 dst = READ32(cpustate,ea);
3271 UINT8 bit = FETCH(cpustate);
3273 if( dst & (1 << bit) )
3279 WRITE32(cpustate,ea, dst);
3280 CYCLES(cpustate,CYCLES_BTS_IMM_MEM);
3283 case 6: /* BTR Rm32, i8 */
3284 if( modrm >= 0xc0 ) {
3285 UINT32 dst = LOAD_RM32(modrm);
3286 UINT8 bit = FETCH(cpustate);
3288 if( dst & (1 << bit) )
3294 STORE_RM32(modrm, dst);
3295 CYCLES(cpustate,CYCLES_BTR_IMM_REG);
3297 UINT32 ea = GetEA(cpustate,modrm,1,4);
3298 UINT32 dst = READ32(cpustate,ea);
3299 UINT8 bit = FETCH(cpustate);
3301 if( dst & (1 << bit) )
3307 WRITE32(cpustate,ea, dst);
3308 CYCLES(cpustate,CYCLES_BTR_IMM_MEM);
3311 case 7: /* BTC Rm32, i8 */
3312 if( modrm >= 0xc0 ) {
3313 UINT32 dst = LOAD_RM32(modrm);
3314 UINT8 bit = FETCH(cpustate);
3316 if( dst & (1 << bit) )
3322 STORE_RM32(modrm, dst);
3323 CYCLES(cpustate,CYCLES_BTC_IMM_REG);
3325 UINT32 ea = GetEA(cpustate,modrm,1,4);
3326 UINT32 dst = READ32(cpustate,ea);
3327 UINT8 bit = FETCH(cpustate);
3329 if( dst & (1 << bit) )
3335 WRITE32(cpustate,ea, dst);
3336 CYCLES(cpustate,CYCLES_BTC_IMM_MEM);
3340 report_invalid_modrm(cpustate, "group0FBA_32", modrm);
3345 static void I386OP(lar_r32_rm32)(i386_state *cpustate) // Opcode 0x0f 0x02
3347 UINT8 modrm = FETCH(cpustate);
3351 if(PROTECTED_MODE && !V8086_MODE)
3353 memset(&seg,0,sizeof(seg));
3356 seg.selector = LOAD_RM32(modrm);
3357 CYCLES(cpustate,CYCLES_LAR_REG);
3361 UINT32 ea = GetEA(cpustate,modrm,0,4);
3362 seg.selector = READ32(cpustate,ea);
3363 CYCLES(cpustate,CYCLES_LAR_MEM);
3365 if(seg.selector == 0)
3367 SetZF(0); // not a valid segment
3372 if(!i386_load_protected_mode_segment(cpustate,&seg,&desc))
3377 UINT8 DPL = (seg.flags >> 5) & 3;
3378 if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3383 if(!(seg.flags & 0x10)) // special segment
3385 // check for invalid segment types
3386 type = seg.flags & 0x000f;
3387 if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3389 SetZF(0); // invalid segment type
3393 STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3399 STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
3407 i386_trap(cpustate,6,0, 0);
3408 logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3412 static void I386OP(lsl_r32_rm32)(i386_state *cpustate) // Opcode 0x0f 0x03
3414 UINT8 modrm = FETCH(cpustate);
3418 if(PROTECTED_MODE && !V8086_MODE)
3420 memset(&seg, 0, sizeof(seg));
3423 seg.selector = LOAD_RM32(modrm);
3427 UINT32 ea = GetEA(cpustate,modrm,0,4);
3428 seg.selector = READ32(cpustate,ea);
3430 if(seg.selector == 0)
3432 SetZF(0); // not a valid segment
3437 if(!i386_load_protected_mode_segment(cpustate,&seg,NULL))
3442 UINT8 DPL = (seg.flags >> 5) & 3;
3443 if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3448 type = seg.flags & 0x1f;
3466 STORE_REG32(modrm,limit);
3472 i386_trap(cpustate,6, 0, 0);
3475 static void I386OP(bound_r32_m32_m32)(i386_state *cpustate) // Opcode 0x62
3478 INT32 val, low, high;
3480 modrm = FETCH(cpustate);
3484 low = high = LOAD_RM32(modrm);
3488 UINT32 ea = GetEA(cpustate,modrm,0,8);
3489 low = READ32(cpustate,ea + 0);
3490 high = READ32(cpustate,ea + 4);
3492 val = LOAD_REG32(modrm);
3494 if ((val < low) || (val > high))
3496 CYCLES(cpustate,CYCLES_BOUND_OUT_RANGE);
3497 i386_trap(cpustate,5, 0, 0);
3501 CYCLES(cpustate,CYCLES_BOUND_IN_RANGE);
3505 static void I386OP(retf32)(i386_state *cpustate) // Opcode 0xcb
3507 if(PROTECTED_MODE && !V8086_MODE)
3509 i386_protected_mode_retf(cpustate,0,1);
3513 cpustate->eip = POP32(cpustate);
3514 cpustate->sreg[CS].selector = POP32(cpustate);
3515 i386_load_segment_descriptor(cpustate, CS );
3516 CHANGE_PC(cpustate,cpustate->eip);
3519 CYCLES(cpustate,CYCLES_RET_INTERSEG);
3522 static void I386OP(retf_i32)(i386_state *cpustate) // Opcode 0xca
3524 UINT16 count = FETCH16(cpustate);
3526 if(PROTECTED_MODE && !V8086_MODE)
3528 i386_protected_mode_retf(cpustate,count,1);
3532 cpustate->eip = POP32(cpustate);
3533 cpustate->sreg[CS].selector = POP32(cpustate);
3534 i386_load_segment_descriptor(cpustate, CS );
3535 CHANGE_PC(cpustate,cpustate->eip);
3536 REG32(ESP) += count;
3539 CYCLES(cpustate,CYCLES_RET_IMM_INTERSEG);
3542 static void I386OP(load_far_pointer32)(i386_state *cpustate, int s)
3544 UINT8 modrm = FETCH(cpustate);
3547 if( modrm >= 0xc0 ) {
3548 report_invalid_modrm(cpustate, "load_far_pointer32", modrm);
3550 UINT32 ea = GetEA(cpustate,modrm,0,6);
3551 STORE_REG32(modrm, READ32(cpustate,ea + 0));
3552 selector = READ16(cpustate,ea + 4);
3553 i386_sreg_load(cpustate,selector,s,NULL);
3557 static void I386OP(lds32)(i386_state *cpustate) // Opcode 0xc5
3559 I386OP(load_far_pointer32)(cpustate, DS);
3560 CYCLES(cpustate,CYCLES_LDS);
3563 static void I386OP(lss32)(i386_state *cpustate) // Opcode 0x0f 0xb2
3565 I386OP(load_far_pointer32)(cpustate, SS);
3566 CYCLES(cpustate,CYCLES_LSS);
3569 static void I386OP(les32)(i386_state *cpustate) // Opcode 0xc4
3571 I386OP(load_far_pointer32)(cpustate, ES);
3572 CYCLES(cpustate,CYCLES_LES);
3575 static void I386OP(lfs32)(i386_state *cpustate) // Opcode 0x0f 0xb4
3577 I386OP(load_far_pointer32)(cpustate, FS);
3578 CYCLES(cpustate,CYCLES_LFS);
3581 static void I386OP(lgs32)(i386_state *cpustate) // Opcode 0x0f 0xb5
3583 I386OP(load_far_pointer32)(cpustate, GS);
3584 CYCLES(cpustate,CYCLES_LGS);