DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* Do the actual opcode */ 00020 switch (inst.code.op) { 00021 case t_ADDb: case t_ADDw: case t_ADDd: 00022 lf_var1d=inst_op1_d; 00023 lf_var2d=inst_op2_d; 00024 inst_op1_d=lf_resd=lf_var1d + lf_var2d; 00025 lflags.type=inst.code.op; 00026 break; 00027 case t_CMPb: case t_CMPw: case t_CMPd: 00028 case t_SUBb: case t_SUBw: case t_SUBd: 00029 lf_var1d=inst_op1_d; 00030 lf_var2d=inst_op2_d; 00031 inst_op1_d=lf_resd=lf_var1d - lf_var2d; 00032 lflags.type=inst.code.op; 00033 break; 00034 case t_ORb: case t_ORw: case t_ORd: 00035 lf_var1d=inst_op1_d; 00036 lf_var2d=inst_op2_d; 00037 inst_op1_d=lf_resd=lf_var1d | lf_var2d; 00038 lflags.type=inst.code.op; 00039 break; 00040 case t_XORb: case t_XORw: case t_XORd: 00041 lf_var1d=inst_op1_d; 00042 lf_var2d=inst_op2_d; 00043 inst_op1_d=lf_resd=lf_var1d ^ lf_var2d; 00044 lflags.type=inst.code.op; 00045 break; 00046 case t_TESTb: case t_TESTw: case t_TESTd: 00047 case t_ANDb: case t_ANDw: case t_ANDd: 00048 lf_var1d=inst_op1_d; 00049 lf_var2d=inst_op2_d; 00050 inst_op1_d=lf_resd=lf_var1d & lf_var2d; 00051 lflags.type=inst.code.op; 00052 break; 00053 case t_ADCb: case t_ADCw: case t_ADCd: 00054 lflags.oldcf=(get_CF()!=0); 00055 lf_var1d=inst_op1_d; 00056 lf_var2d=inst_op2_d; 00057 inst_op1_d=lf_resd=(Bit32u)(lf_var1d + lf_var2d + lflags.oldcf); 00058 lflags.type=inst.code.op; 00059 break; 00060 case t_SBBb: case t_SBBw: case t_SBBd: 00061 lflags.oldcf=(get_CF()!=0); 00062 lf_var1d=inst_op1_d; 00063 lf_var2d=inst_op2_d; 00064 inst_op1_d=lf_resd=(Bit32u)(lf_var1d - lf_var2d - lflags.oldcf); 00065 lflags.type=inst.code.op; 00066 break; 00067 case t_INCb: case t_INCw: case t_INCd: 00068 LoadCF; 00069 lf_var1d=inst_op1_d; 00070 inst_op1_d=lf_resd=inst_op1_d+1; 00071 lflags.type=inst.code.op; 00072 break; 00073 case t_DECb: case t_DECw: case t_DECd: 00074 LoadCF; 00075 lf_var1d=inst_op1_d; 00076 inst_op1_d=lf_resd=inst_op1_d-1; 00077 lflags.type=inst.code.op; 00078 break; 00079 /* Using the instructions.h defines */ 00080 case t_ROLb: 00081 ROLB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00082 break; 00083 case t_ROLw: 00084 ROLW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00085 break; 00086 case t_ROLd: 00087 ROLD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00088 break; 00089 00090 case t_RORb: 00091 RORB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00092 break; 00093 case t_RORw: 00094 RORW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00095 break; 00096 case t_RORd: 00097 RORD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00098 break; 00099 00100 case t_RCLb: 00101 RCLB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00102 break; 00103 case t_RCLw: 00104 RCLW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00105 break; 00106 case t_RCLd: 00107 RCLD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00108 break; 00109 00110 case t_RCRb: 00111 RCRB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00112 break; 00113 case t_RCRw: 00114 RCRW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00115 break; 00116 case t_RCRd: 00117 RCRD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00118 break; 00119 00120 case t_SHLb: 00121 SHLB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00122 break; 00123 case t_SHLw: 00124 SHLW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00125 break; 00126 case t_SHLd: 00127 SHLD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00128 break; 00129 00130 case t_SHRb: 00131 SHRB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00132 break; 00133 case t_SHRw: 00134 SHRW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00135 break; 00136 case t_SHRd: 00137 SHRD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00138 break; 00139 00140 case t_SARb: 00141 SARB(inst_op1_b,inst_op2_b,LoadD,SaveD); 00142 break; 00143 case t_SARw: 00144 SARW(inst_op1_w,inst_op2_b,LoadD,SaveD); 00145 break; 00146 case t_SARd: 00147 SARD(inst_op1_d,inst_op2_b,LoadD,SaveD); 00148 break; 00149 00150 case O_DSHLw: 00151 { 00152 DSHLW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); 00153 break; 00154 } 00155 case O_DSHRw: 00156 { 00157 DSHRW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); 00158 break; 00159 } 00160 case O_DSHLd: 00161 { 00162 DSHLD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); 00163 break; 00164 } 00165 case O_DSHRd: 00166 { 00167 DSHRD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); 00168 break; 00169 } 00170 00171 case t_NEGb: 00172 lf_var1b=inst_op1_b; 00173 inst_op1_b=lf_resb=0-inst_op1_b; 00174 lflags.type=t_NEGb; 00175 break; 00176 case t_NEGw: 00177 lf_var1w=inst_op1_w; 00178 inst_op1_w=lf_resw=0-inst_op1_w; 00179 lflags.type=t_NEGw; 00180 break; 00181 case t_NEGd: 00182 lf_var1d=inst_op1_d; 00183 inst_op1_d=lf_resd=0-inst_op1_d; 00184 lflags.type=t_NEGd; 00185 break; 00186 00187 case O_NOT: 00188 inst_op1_d=~inst_op1_d; 00189 break; 00190 00191 /* Special instructions */ 00192 case O_IMULRw: 00193 DIMULW(inst_op1_ws,inst_op1_ws,inst_op2_ws,LoadD,SaveD); 00194 break; 00195 case O_IMULRd: 00196 DIMULD(inst_op1_ds,inst_op1_ds,inst_op2_ds,LoadD,SaveD); 00197 break; 00198 case O_MULb: 00199 MULB(inst_op1_b,LoadD,0); 00200 goto nextopcode; 00201 case O_MULw: 00202 MULW(inst_op1_w,LoadD,0); 00203 goto nextopcode; 00204 case O_MULd: 00205 MULD(inst_op1_d,LoadD,0); 00206 goto nextopcode; 00207 case O_IMULb: 00208 IMULB(inst_op1_b,LoadD,0); 00209 goto nextopcode; 00210 case O_IMULw: 00211 IMULW(inst_op1_w,LoadD,0); 00212 goto nextopcode; 00213 case O_IMULd: 00214 IMULD(inst_op1_d,LoadD,0); 00215 goto nextopcode; 00216 case O_DIVb: 00217 DIVB(inst_op1_b,LoadD,0); 00218 goto nextopcode; 00219 case O_DIVw: 00220 DIVW(inst_op1_w,LoadD,0); 00221 goto nextopcode; 00222 case O_DIVd: 00223 DIVD(inst_op1_d,LoadD,0); 00224 goto nextopcode; 00225 case O_IDIVb: 00226 IDIVB(inst_op1_b,LoadD,0); 00227 goto nextopcode; 00228 case O_IDIVw: 00229 IDIVW(inst_op1_w,LoadD,0); 00230 goto nextopcode; 00231 case O_IDIVd: 00232 IDIVD(inst_op1_d,LoadD,0); 00233 goto nextopcode; 00234 case O_AAM: 00235 AAM(inst_op1_b); 00236 goto nextopcode; 00237 case O_AAD: 00238 AAD(inst_op1_b); 00239 goto nextopcode; 00240 00241 case O_C_O: inst.cond=TFLG_O; break; 00242 case O_C_NO: inst.cond=TFLG_NO; break; 00243 case O_C_B: inst.cond=TFLG_B; break; 00244 case O_C_NB: inst.cond=TFLG_NB; break; 00245 case O_C_Z: inst.cond=TFLG_Z; break; 00246 case O_C_NZ: inst.cond=TFLG_NZ; break; 00247 case O_C_BE: inst.cond=TFLG_BE; break; 00248 case O_C_NBE: inst.cond=TFLG_NBE; break; 00249 case O_C_S: inst.cond=TFLG_S; break; 00250 case O_C_NS: inst.cond=TFLG_NS; break; 00251 case O_C_P: inst.cond=TFLG_P; break; 00252 case O_C_NP: inst.cond=TFLG_NP; break; 00253 case O_C_L: inst.cond=TFLG_L; break; 00254 case O_C_NL: inst.cond=TFLG_NL; break; 00255 case O_C_LE: inst.cond=TFLG_LE; break; 00256 case O_C_NLE: inst.cond=TFLG_NLE; break; 00257 00258 case O_ALOP: 00259 reg_al=LoadMb(inst.rm_eaa); 00260 goto nextopcode; 00261 case O_AXOP: 00262 reg_ax=LoadMw(inst.rm_eaa); 00263 goto nextopcode; 00264 case O_EAXOP: 00265 reg_eax=LoadMd(inst.rm_eaa); 00266 goto nextopcode; 00267 case O_OPAL: 00268 SaveMb(inst.rm_eaa,reg_al); 00269 goto nextopcode; 00270 case O_OPAX: 00271 SaveMw(inst.rm_eaa,reg_ax); 00272 goto nextopcode; 00273 case O_OPEAX: 00274 SaveMd(inst.rm_eaa,reg_eax); 00275 goto nextopcode; 00276 case O_SEGDS: 00277 inst.code.extra=ds; 00278 break; 00279 case O_SEGES: 00280 inst.code.extra=es; 00281 break; 00282 case O_SEGFS: 00283 inst.code.extra=fs; 00284 break; 00285 case O_SEGGS: 00286 inst.code.extra=gs; 00287 break; 00288 case O_SEGSS: 00289 inst.code.extra=ss; 00290 break; 00291 00292 case O_LOOP: 00293 if (inst.prefix & PREFIX_ADDR) { 00294 if (--reg_ecx) break; 00295 } else { 00296 if (--reg_cx) break; 00297 } 00298 goto nextopcode; 00299 case O_LOOPZ: 00300 if (inst.prefix & PREFIX_ADDR) { 00301 if (--reg_ecx && get_ZF()) break; 00302 } else { 00303 if (--reg_cx && get_ZF()) break; 00304 } 00305 goto nextopcode; 00306 case O_LOOPNZ: 00307 if (inst.prefix & PREFIX_ADDR) { 00308 if (--reg_ecx && !get_ZF()) break; 00309 } else { 00310 if (--reg_cx && !get_ZF()) break; 00311 } 00312 goto nextopcode; 00313 case O_JCXZ: 00314 if (inst.prefix & PREFIX_ADDR) { 00315 if (reg_ecx) goto nextopcode; 00316 } else { 00317 if (reg_cx) goto nextopcode; 00318 } 00319 break; 00320 case O_XCHG_AX: 00321 { 00322 Bit16u temp=reg_ax; 00323 reg_ax=inst_op1_w; 00324 inst_op1_w=temp; 00325 break; 00326 } 00327 case O_XCHG_EAX: 00328 { 00329 Bit32u temp=reg_eax; 00330 reg_eax=inst_op1_d; 00331 inst_op1_d=temp; 00332 break; 00333 } 00334 case O_CALLNw: 00335 SaveIP(); 00336 Push_16(reg_ip); 00337 break; 00338 case O_CALLNd: 00339 SaveIP(); 00340 Push_32(reg_eip); 00341 break; 00342 case O_CALLFw: 00343 FillFlags(); 00344 CPU_CALL(false,inst_op2_d,inst_op1_d,GetIP()); 00345 continue; 00346 case O_CALLFd: 00347 FillFlags(); 00348 CPU_CALL(true,inst_op2_d,inst_op1_d,GetIP()); 00349 continue; 00350 case O_JMPFw: 00351 FillFlags(); 00352 CPU_JMP(false,inst_op2_d,inst_op1_d,GetIP()); 00353 continue; 00354 case O_JMPFd: 00355 FillFlags(); 00356 CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP()); 00357 continue; 00358 case O_INT: 00359 #if C_DEBUG 00360 FillFlags(); 00361 if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) 00362 return (Bits)debugCallback; 00363 else if (DEBUG_IntBreakpoint(inst_op1_b)) 00364 return (Bits)debugCallback; 00365 #endif 00366 CPU_SW_Interrupt(inst_op1_b,GetIP()); 00367 continue; 00368 case O_INb: 00369 if (CPU_IO_Exception(inst_op1_d,1)) RunException(); 00370 reg_al=IO_ReadB(inst_op1_d); 00371 goto nextopcode; 00372 case O_INw: 00373 if (CPU_IO_Exception(inst_op1_d,2)) RunException(); 00374 reg_ax=IO_ReadW(inst_op1_d); 00375 goto nextopcode; 00376 case O_INd: 00377 if (CPU_IO_Exception(inst_op1_d,4)) RunException(); 00378 reg_eax=IO_ReadD(inst_op1_d); 00379 goto nextopcode; 00380 case O_OUTb: 00381 if (CPU_IO_Exception(inst_op1_d,1)) RunException(); 00382 IO_WriteB(inst_op1_d,reg_al); 00383 goto nextopcode; 00384 case O_OUTw: 00385 if (CPU_IO_Exception(inst_op1_d,2)) RunException(); 00386 IO_WriteW(inst_op1_d,reg_ax); 00387 goto nextopcode; 00388 case O_OUTd: 00389 if (CPU_IO_Exception(inst_op1_d,4)) RunException(); 00390 IO_WriteD(inst_op1_d,reg_eax); 00391 goto nextopcode; 00392 case O_CBACK: 00393 FillFlags();SaveIP(); 00394 return (Bits)inst_op1_d; 00395 case O_GRP6w: 00396 case O_GRP6d: 00397 if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; 00398 switch (inst.rm_index) { 00399 case 0x00: /* SLDT */ 00400 inst_op1_d=(Bit32u)CPU_SLDT(); 00401 break; 00402 case 0x01: /* STR */ 00403 inst_op1_d=(Bit32u)CPU_STR(); 00404 break; 00405 case 0x02: /* LLDT */ 00406 if (cpu.cpl) EXCEPTION(EXCEPTION_GP); 00407 if (CPU_LLDT(inst_op1_d)) RunException(); 00408 goto nextopcode; /* Else value will saved */ 00409 case 0x03: /* LTR */ 00410 if (cpu.cpl) EXCEPTION(EXCEPTION_GP); 00411 if (CPU_LTR(inst_op1_d)) RunException(); 00412 goto nextopcode; /* Else value will saved */ 00413 case 0x04: /* VERR */ 00414 CPU_VERR(inst_op1_d); 00415 goto nextopcode; /* Else value will saved */ 00416 case 0x05: /* VERW */ 00417 CPU_VERW(inst_op1_d); 00418 goto nextopcode; /* Else value will saved */ 00419 default: 00420 LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %lx",(unsigned long)inst.rm_index); 00421 goto illegalopcode; 00422 } 00423 break; 00424 case O_GRP7w: 00425 case O_GRP7d: 00426 switch (inst.rm_index) { 00427 case 0: /* SGDT */ 00428 SaveMw(inst.rm_eaa,(Bit16u)CPU_SGDT_limit()); 00429 SaveMd(inst.rm_eaa+2,(Bit32u)CPU_SGDT_base()); 00430 goto nextopcode; 00431 case 1: /* SIDT */ 00432 SaveMw(inst.rm_eaa,(Bit16u)CPU_SIDT_limit()); 00433 SaveMd(inst.rm_eaa+2,(Bit32u)CPU_SIDT_base()); 00434 goto nextopcode; 00435 case 2: /* LGDT */ 00436 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); 00437 CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); 00438 goto nextopcode; 00439 case 3: /* LIDT */ 00440 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); 00441 CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); 00442 goto nextopcode; 00443 case 4: /* SMSW */ 00444 inst_op1_d=(Bit32u)CPU_SMSW(); 00445 break; 00446 case 6: /* LMSW */ 00447 FillFlags(); 00448 if (CPU_LMSW(inst_op1_w)) RunException(); 00449 goto nextopcode; 00450 case 7: /* INVLPG */ 00451 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); 00452 FillFlags(); 00453 PAGING_ClearTLB(); 00454 goto nextopcode; 00455 default: 00456 LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %lx",(unsigned long)inst.rm_index); 00457 goto illegalopcode; 00458 } 00459 break; 00460 case O_M_CRx_Rd: 00461 if (CPU_WRITE_CRX(inst.rm_index,inst_op1_d)) RunException(); 00462 break; 00463 case O_M_Rd_CRx: 00464 if (CPU_READ_CRX(inst.rm_index,inst_op1_d)) RunException(); 00465 break; 00466 case O_M_DRx_Rd: 00467 if (CPU_WRITE_DRX(inst.rm_index,inst_op1_d)) RunException(); 00468 break; 00469 case O_M_Rd_DRx: 00470 if (CPU_READ_DRX(inst.rm_index,inst_op1_d)) RunException(); 00471 break; 00472 case O_M_TRx_Rd: 00473 if (CPU_WRITE_TRX(inst.rm_index,inst_op1_d)) RunException(); 00474 break; 00475 case O_M_Rd_TRx: 00476 if (CPU_READ_TRX(inst.rm_index,inst_op1_d)) RunException(); 00477 break; 00478 case O_LAR: 00479 { 00480 Bitu ar=inst_op2_d; 00481 CPU_LAR(inst_op1_w,ar); 00482 inst_op1_d=(Bit32u)ar; 00483 } 00484 break; 00485 case O_LSL: 00486 { 00487 Bitu limit=inst_op2_d; 00488 CPU_LSL(inst_op1_w,limit); 00489 inst_op1_d=(Bit32u)limit; 00490 } 00491 break; 00492 case O_ARPL: 00493 { 00494 Bitu new_sel=inst_op1_d; 00495 CPU_ARPL(new_sel,inst_op2_d); 00496 inst_op1_d=(Bit32u)new_sel; 00497 } 00498 break; 00499 case O_BSFw: 00500 { 00501 FillFlags(); 00502 if (!inst_op1_w) { 00503 SETFLAGBIT(ZF,true); 00504 goto nextopcode; 00505 } else { 00506 Bit8u count=0; 00507 while (1) { 00508 if (inst_op1_w & 0x1) break; 00509 count++;inst_op1_w>>=1; 00510 } 00511 inst_op1_d=count; 00512 SETFLAGBIT(ZF,false); 00513 } 00514 } 00515 break; 00516 case O_BSFd: 00517 { 00518 FillFlags(); 00519 if (!inst_op1_d) { 00520 SETFLAGBIT(ZF,true); 00521 goto nextopcode; 00522 } else { 00523 Bit8u count=0; 00524 while (1) { 00525 if (inst_op1_d & 0x1) break; 00526 count++;inst_op1_d>>=1; 00527 } 00528 inst_op1_d=count; 00529 SETFLAGBIT(ZF,false); 00530 } 00531 } 00532 break; 00533 case O_BSRw: 00534 { 00535 FillFlags(); 00536 if (!inst_op1_w) { 00537 SETFLAGBIT(ZF,true); 00538 goto nextopcode; 00539 } else { 00540 Bit8u count=15; 00541 while (1) { 00542 if (inst_op1_w & 0x8000) break; 00543 count--;inst_op1_w<<=1; 00544 } 00545 inst_op1_d=count; 00546 SETFLAGBIT(ZF,false); 00547 } 00548 } 00549 break; 00550 case O_BSRd: 00551 { 00552 FillFlags(); 00553 if (!inst_op1_d) { 00554 SETFLAGBIT(ZF,true); 00555 goto nextopcode; 00556 } else { 00557 Bit8u count=31; 00558 while (1) { 00559 if (inst_op1_d & 0x80000000) break; 00560 count--;inst_op1_d<<=1; 00561 } 00562 inst_op1_d=count; 00563 SETFLAGBIT(ZF,false); 00564 } 00565 } 00566 break; 00567 case O_BTw: 00568 FillFlags(); 00569 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 15u)))); 00570 break; 00571 case O_BTSw: 00572 FillFlags(); 00573 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 15u)))); 00574 inst_op1_d|=(1u << (inst_op2_d & 15u)); 00575 break; 00576 case O_BTCw: 00577 FillFlags(); 00578 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 15u)))); 00579 inst_op1_d^=(1u << (inst_op2_d & 15u)); 00580 break; 00581 case O_BTRw: 00582 FillFlags(); 00583 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 15u)))); 00584 inst_op1_d&=~(1u << (inst_op2_d & 15u)); 00585 break; 00586 case O_BTd: 00587 FillFlags(); 00588 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 31u)))); 00589 break; 00590 case O_BTSd: 00591 FillFlags(); 00592 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 31u)))); 00593 inst_op1_d|=(1u << (inst_op2_d & 31u)); 00594 break; 00595 case O_BTCd: 00596 FillFlags(); 00597 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 31)))); 00598 inst_op1_d^=(1u << (inst_op2_d & 31u)); 00599 break; 00600 case O_BTRd: 00601 FillFlags(); 00602 SETFLAGBIT(CF,(inst_op1_d & (1u << (inst_op2_d & 31u)))); 00603 inst_op1_d&=~(1u << (inst_op2_d & 31u)); 00604 break; 00605 case O_BSWAPw: 00606 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegalopcode; 00607 BSWAPW(inst_op1_w); 00608 break; 00609 case O_BSWAPd: 00610 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegalopcode; 00611 BSWAPD(inst_op1_d); 00612 break; 00613 case O_CMPXCHG: 00614 if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEW) goto illegalopcode; 00615 FillFlags(); 00616 if (inst_op1_d==reg_eax) { 00617 inst_op1_d=reg_32(inst.rm_index); 00618 if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf 00619 SETFLAGBIT(ZF,1); 00620 } else { 00621 if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf 00622 reg_eax=inst_op1_d; 00623 SETFLAGBIT(ZF,0); 00624 } 00625 break; 00626 case O_FPU: 00627 #if C_FPU 00628 switch (((inst.rm>=0xc0) << 3) | inst.code.save) { 00629 case 0x00: FPU_ESC0_EA(inst.rm,inst.rm_eaa);break; 00630 case 0x01: FPU_ESC1_EA(inst.rm,inst.rm_eaa);break; 00631 case 0x02: FPU_ESC2_EA(inst.rm,inst.rm_eaa);break; 00632 case 0x03: FPU_ESC3_EA(inst.rm,inst.rm_eaa);break; 00633 case 0x04: FPU_ESC4_EA(inst.rm,inst.rm_eaa);break; 00634 case 0x05: FPU_ESC5_EA(inst.rm,inst.rm_eaa);break; 00635 case 0x06: FPU_ESC6_EA(inst.rm,inst.rm_eaa);break; 00636 case 0x07: FPU_ESC7_EA(inst.rm,inst.rm_eaa);break; 00637 00638 case 0x08: FPU_ESC0_Normal(inst.rm);break; 00639 case 0x09: FPU_ESC1_Normal(inst.rm);break; 00640 case 0x0a: FPU_ESC2_Normal(inst.rm);break; 00641 case 0x0b: FPU_ESC3_Normal(inst.rm);break; 00642 case 0x0c: FPU_ESC4_Normal(inst.rm);break; 00643 case 0x0d: FPU_ESC5_Normal(inst.rm);break; 00644 case 0x0e: FPU_ESC6_Normal(inst.rm);break; 00645 case 0x0f: FPU_ESC7_Normal(inst.rm);break; 00646 } 00647 goto nextopcode; 00648 #else 00649 LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save); 00650 goto nextopcode; 00651 #endif 00652 case O_BOUNDw: 00653 { 00654 Bit16s bound_min, bound_max; 00655 bound_min=(Bit16s)LoadMw(inst.rm_eaa); 00656 bound_max=(Bit16s)LoadMw(inst.rm_eaa+2); 00657 if ( (((Bit16s)inst_op1_w) < bound_min) || (((Bit16s)inst_op1_w) > bound_max) ) { 00658 EXCEPTION(5); 00659 } 00660 } 00661 break; 00662 case 0: 00663 break; 00664 default: 00665 LOG(LOG_CPU,LOG_ERROR)("OP:Unhandled code %d entry %lx",inst.code.op,(unsigned long)inst.entry); 00666 00667 }