DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_full/op.h
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 }