DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_normal/prefix_0f.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         CASE_0F_W(0x00)                                                                                         /* GRP 6 Exxx */
00020                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00021                 {
00022                         if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
00023                         GetRM;Bitu which=(rm>>3)&7;
00024                         switch (which) {
00025                         case 0x00:      /* SLDT */
00026                         case 0x01:      /* STR */
00027                                 {
00028                                         Bitu saveval;
00029                                         if (!which) saveval=CPU_SLDT();
00030                                         else saveval=CPU_STR();
00031                                         if (rm >= 0xc0) {GetEArw;*earw=(Bit16u)saveval;}
00032                                         else {GetEAa;SaveMw(eaa,(Bit16u)saveval);}
00033                                 }
00034                                 break;
00035                         case 0x02:case 0x03:case 0x04:case 0x05:
00036                                 {
00037                                         Bitu loadval;
00038                                         if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
00039                                         else {GetEAa;loadval=LoadMw(eaa);}
00040                                         switch (which) {
00041                                         case 0x02:
00042                                                 if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
00043                                                 if (CPU_LLDT(loadval)) RUNEXCEPTION();
00044                                                 break;
00045                                         case 0x03:
00046                                                 if (cpu.cpl) EXCEPTION(EXCEPTION_GP);
00047                                                 if (CPU_LTR(loadval)) RUNEXCEPTION();
00048                                                 break;
00049                                         case 0x04:
00050                                                 CPU_VERR(loadval);
00051                                                 break;
00052                                         case 0x05:
00053                                                 CPU_VERW(loadval);
00054                                                 break;
00055                                         }
00056                                 }
00057                                 break;
00058                         default:
00059                                 goto illegal_opcode;
00060                         }
00061                 }
00062                 break;
00063         CASE_0F_W(0x01)                                                                                         /* Group 7 Ew */
00064                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00065                 {
00066                         GetRM;Bitu which=(rm>>3)&7;
00067                         if (rm < 0xc0)  { //First ones all use EA
00068                                 GetEAa;Bitu limit;
00069                                 switch (which) {
00070                                         /* NTS: The 286 is documented to write 0xFF in the most significant byte of the 6-byte field,
00071                                          *      while 386 and later is documented to write 0x00 (or the MSB of the base if 32-bit form).
00072                                          *      Some programs, including Microsoft Windows 3.0, execute SGDT and then compare the most
00073                                          *      significant byte against 0xFF. It does NOT use the standard Intel detection process. */
00074                                 case 0x00:                                                                              /* SGDT */
00075                                         SaveMw(eaa,(Bit16u)CPU_SGDT_limit());
00076                                         SaveMd(eaa+2,(Bit32u)(CPU_SGDT_base()|(CPU_ArchitectureType<CPU_ARCHTYPE_386?0xFF000000UL:0)));
00077                                         break;
00078                                         /* NTS: Same comments for SIDT as SGDT */
00079                                 case 0x01:                                                                              /* SIDT */
00080                                         SaveMw(eaa,(Bit16u)CPU_SIDT_limit());
00081                                         SaveMd(eaa+2,(Bit32u)(CPU_SIDT_base()|(CPU_ArchitectureType<CPU_ARCHTYPE_386?0xFF000000UL:0)));
00082                                         break;
00083                                 case 0x02:                                                                              /* LGDT */
00084                                         if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00085                                         CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
00086                                         break;
00087                                 case 0x03:                                                                              /* LIDT */
00088                                         if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00089                                         CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
00090                                         break;
00091                                 case 0x04:                                                                              /* SMSW */
00092                                         SaveMw(eaa,(Bit16u)CPU_SMSW());
00093                                         break;
00094                                 case 0x06:                                                                              /* LMSW */
00095                                         limit=LoadMw(eaa);
00096                                         if (CPU_LMSW(limit)) RUNEXCEPTION();
00097                                         break;
00098                                 case 0x07:                                                                              /* INVLPG */
00099                                         if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00100                                         if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00101                                         PAGING_ClearTLB();
00102                                         break;
00103                                 }
00104                         } else {
00105                                 GetEArw;
00106                                 switch (which) {
00107                                 case 0x02:                                                                              /* LGDT */
00108                                         if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00109                                         goto illegal_opcode;
00110                                 case 0x03:                                                                              /* LIDT */
00111                                         if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00112                                         goto illegal_opcode;
00113                                 case 0x04:                                                                              /* SMSW */
00114                                         *earw=(Bit16u)CPU_SMSW();
00115                                         break;
00116                                 case 0x06:                                                                              /* LMSW */
00117                                         if (CPU_LMSW(*earw)) RUNEXCEPTION();
00118                                         break;
00119                                 default:
00120                                         goto illegal_opcode;
00121                                 }
00122                         }
00123                 }
00124                 break;
00125         CASE_0F_W(0x02)                                                                                         /* LAR Gw,Ew */
00126                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00127                 {
00128                         if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
00129                         GetRMrw;Bitu ar=*rmrw;
00130                         if (rm >= 0xc0) {
00131                                 GetEArw;CPU_LAR(*earw,ar);
00132                         } else {
00133                                 GetEAa;CPU_LAR(LoadMw(eaa),ar);
00134                         }
00135                         *rmrw=(Bit16u)ar;
00136                 }
00137                 break;
00138         CASE_0F_W(0x03)                                                                                         /* LSL Gw,Ew */
00139                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00140                 {
00141                         if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
00142                         GetRMrw;Bitu limit=*rmrw;
00143                         if (rm >= 0xc0) {
00144                                 GetEArw;CPU_LSL(*earw,limit);
00145                         } else {
00146                                 GetEAa;CPU_LSL(LoadMw(eaa),limit);
00147                         }
00148                         *rmrw=(Bit16u)limit;
00149                 }
00150                 break;
00151         CASE_0F_B(0x06)                                                                                         /* CLTS */
00152                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00153                 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00154                 cpu.cr0&=(~CR0_TASKSWITCH);
00155                 break;
00156         CASE_0F_B(0x08)                                                                                         /* INVD */
00157         CASE_0F_B(0x09)                                                                                         /* WBINVD */
00158                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00159                 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
00160                 break;
00161         CASE_0F_B(0x20)                                                                                         /* MOV Rd.CRx */
00162                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00163                 {
00164                         GetRM;
00165                         Bitu which=(rm >> 3) & 7;
00166                         if (rm < 0xc0 ) {
00167                                 rm |= 0xc0;
00168                                 LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",(int)which);
00169                         }
00170                         GetEArd;
00171                         Bit32u crx_value;
00172                         if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION();
00173                         *eard=crx_value;
00174                 }
00175                 break;
00176         CASE_0F_B(0x21)                                                                                         /* MOV Rd,DRx */
00177                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00178                 {
00179                         GetRM;
00180                         Bitu which=(rm >> 3) & 7;
00181                         if (rm < 0xc0 ) {
00182                                 rm |= 0xc0;
00183                                 LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR%u with non-register",(int)which);
00184                         }
00185                         GetEArd;
00186                         Bit32u drx_value;
00187                         if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION();
00188                         *eard=drx_value;
00189                 }
00190                 break;
00191         CASE_0F_B(0x22)                                                                                         /* MOV CRx,Rd */
00192                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00193                 {
00194                         GetRM;
00195                         Bitu which=(rm >> 3) & 7;
00196                         if (rm < 0xc0 ) {
00197                                 rm |= 0xc0;
00198                                 LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",(int)which);
00199                         }
00200                         GetEArd;
00201                         if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION();
00202                 }
00203                 break;
00204         CASE_0F_B(0x23)                                                                                         /* MOV DRx,Rd */
00205                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00206                 {
00207                         GetRM;
00208                         Bitu which=(rm >> 3) & 7;
00209                         if (rm < 0xc0 ) {
00210                                 rm |= 0xc0;
00211                                 LOG(LOG_CPU,LOG_ERROR)("MOV DR%u,XXX with non-register",(int)which);
00212                         }
00213                         GetEArd;
00214                         if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION();
00215                 }
00216                 break;
00217         CASE_0F_B(0x24)                                                                                         /* MOV Rd,TRx */
00218                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00219                 {
00220                         GetRM;
00221                         Bitu which=(rm >> 3) & 7;
00222                         if (rm < 0xc0 ) {
00223                                 rm |= 0xc0;
00224                                 LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR%u with non-register",(int)which);
00225                         }
00226                         GetEArd;
00227                         Bit32u trx_value;
00228                         if (CPU_READ_TRX(which,trx_value)) RUNEXCEPTION();
00229                         *eard=trx_value;
00230                 }
00231                 break;
00232         CASE_0F_B(0x26)                                                                                         /* MOV TRx,Rd */
00233                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00234                 {
00235                         GetRM;
00236                         Bitu which=(rm >> 3) & 7;
00237                         if (rm < 0xc0 ) {
00238                                 rm |= 0xc0;
00239                                 LOG(LOG_CPU,LOG_ERROR)("MOV TR%u,XXX with non-register",(int)which);
00240                         }
00241                         GetEArd;
00242                         if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION();
00243                 }
00244                 break;
00245         CASE_0F_B(0x30)                                                                                         /* WRMSR */
00246                 {
00247                         if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegal_opcode;
00248                         if (!CPU_WRMSR()) goto illegal_opcode;
00249                 }
00250                 break;
00251         CASE_0F_B(0x31)                                                                                         /* RDTSC */
00252                 {
00253                         if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegal_opcode;
00254                         /* Use a fixed number when in auto cycles mode as else the reported value changes constantly */
00255                         Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double) (CPU_CycleAutoAdjust?70000:CPU_CycleMax));
00256                         reg_edx=(Bit32u)(tsc>>32);
00257                         reg_eax=(Bit32u)(tsc&0xffffffff);
00258                 }
00259                 break;
00260 
00261         // Pentium Pro Conditional Moves
00262         CASE_0F_W(0x40)                                                                                         /* CMOVO */
00263                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00264                 MoveCond16(TFLG_O); break;
00265         CASE_0F_W(0x41)                                                                                         /* CMOVNO */
00266                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00267                 MoveCond16(TFLG_NO); break;
00268         CASE_0F_W(0x42)                                                                                         /* CMOVB */
00269                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00270                 MoveCond16(TFLG_B); break;
00271         CASE_0F_W(0x43)                                                                                         /* CMOVNB */
00272                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00273                 MoveCond16(TFLG_NB); break;
00274         CASE_0F_W(0x44)                                                                                         /* CMOVZ */
00275                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00276                 MoveCond16(TFLG_Z); break;
00277         CASE_0F_W(0x45)                                                                                         /* CMOVNZ */
00278                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00279                 MoveCond16(TFLG_NZ); break;
00280         CASE_0F_W(0x46)                                                                                         /* CMOVBE */
00281                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00282                 MoveCond16(TFLG_BE); break;
00283         CASE_0F_W(0x47)                                                                                         /* CMOVNBE */
00284                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00285                 MoveCond16(TFLG_NBE); break;
00286         CASE_0F_W(0x48)                                                                                         /* CMOVS */
00287                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00288                 MoveCond16(TFLG_S); break;
00289         CASE_0F_W(0x49)                                                                                         /* CMOVNS */
00290                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00291                 MoveCond16(TFLG_NS); break;
00292         CASE_0F_W(0x4A)                                                                                         /* CMOVP */
00293                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00294                 MoveCond16(TFLG_P); break;
00295         CASE_0F_W(0x4B)                                                                                         /* CMOVNP */
00296                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00297                 MoveCond16(TFLG_NP); break;
00298         CASE_0F_W(0x4C)                                                                                         /* CMOVL */
00299                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00300                 MoveCond16(TFLG_L); break;
00301         CASE_0F_W(0x4D)                                                                                         /* CMOVNL */
00302                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00303                 MoveCond16(TFLG_NL); break;
00304         CASE_0F_W(0x4E)                                                                                         /* CMOVLE */
00305                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00306                 MoveCond16(TFLG_LE); break;
00307         CASE_0F_W(0x4F)                                                                                         /* CMOVNLE */
00308                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PPROSLOW) goto illegal_opcode;
00309                 MoveCond16(TFLG_NLE); break;
00310 
00311         CASE_0F_B(0x32)                                                                                         /* RDMSR */
00312                 {
00313                         if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegal_opcode;
00314                         if (!CPU_RDMSR()) goto illegal_opcode;
00315                 }
00316                 break;
00317 #if CPU_CORE >= CPU_ARCHTYPE_386
00318         CASE_0F_W(0x80)                                                                                         /* JO */
00319                 JumpCond16_w(TFLG_O);break;
00320         CASE_0F_W(0x81)                                                                                         /* JNO */
00321                 JumpCond16_w(TFLG_NO);break;
00322         CASE_0F_W(0x82)                                                                                         /* JB */
00323                 JumpCond16_w(TFLG_B);break;
00324         CASE_0F_W(0x83)                                                                                         /* JNB */
00325                 JumpCond16_w(TFLG_NB);break;
00326         CASE_0F_W(0x84)                                                                                         /* JZ */
00327                 JumpCond16_w(TFLG_Z);break;
00328         CASE_0F_W(0x85)                                                                                         /* JNZ */
00329                 JumpCond16_w(TFLG_NZ);break;
00330         CASE_0F_W(0x86)                                                                                         /* JBE */
00331                 JumpCond16_w(TFLG_BE);break;
00332         CASE_0F_W(0x87)                                                                                         /* JNBE */
00333                 JumpCond16_w(TFLG_NBE);break;
00334         CASE_0F_W(0x88)                                                                                         /* JS */
00335                 JumpCond16_w(TFLG_S);break;
00336         CASE_0F_W(0x89)                                                                                         /* JNS */
00337                 JumpCond16_w(TFLG_NS);break;
00338         CASE_0F_W(0x8a)                                                                                         /* JP */
00339                 JumpCond16_w(TFLG_P);break;
00340         CASE_0F_W(0x8b)                                                                                         /* JNP */
00341                 JumpCond16_w(TFLG_NP);break;
00342         CASE_0F_W(0x8c)                                                                                         /* JL */
00343                 JumpCond16_w(TFLG_L);break;
00344         CASE_0F_W(0x8d)                                                                                         /* JNL */
00345                 JumpCond16_w(TFLG_NL);break;
00346         CASE_0F_W(0x8e)                                                                                         /* JLE */
00347                 JumpCond16_w(TFLG_LE);break;
00348         CASE_0F_W(0x8f)                                                                                         /* JNLE */
00349                 JumpCond16_w(TFLG_NLE);break;
00350         CASE_0F_B(0x90)                                                                                         /* SETO */
00351                 SETcc(TFLG_O);break;
00352         CASE_0F_B(0x91)                                                                                         /* SETNO */
00353                 SETcc(TFLG_NO);break;
00354         CASE_0F_B(0x92)                                                                                         /* SETB */
00355                 SETcc(TFLG_B);break;
00356         CASE_0F_B(0x93)                                                                                         /* SETNB */
00357                 SETcc(TFLG_NB);break;
00358         CASE_0F_B(0x94)                                                                                         /* SETZ */
00359                 SETcc(TFLG_Z);break;
00360         CASE_0F_B(0x95)                                                                                         /* SETNZ */
00361                 SETcc(TFLG_NZ); break;
00362         CASE_0F_B(0x96)                                                                                         /* SETBE */
00363                 SETcc(TFLG_BE);break;
00364         CASE_0F_B(0x97)                                                                                         /* SETNBE */
00365                 SETcc(TFLG_NBE);break;
00366         CASE_0F_B(0x98)                                                                                         /* SETS */
00367                 SETcc(TFLG_S);break;
00368         CASE_0F_B(0x99)                                                                                         /* SETNS */
00369                 SETcc(TFLG_NS);break;
00370         CASE_0F_B(0x9a)                                                                                         /* SETP */
00371                 SETcc(TFLG_P);break;
00372         CASE_0F_B(0x9b)                                                                                         /* SETNP */
00373                 SETcc(TFLG_NP);break;
00374         CASE_0F_B(0x9c)                                                                                         /* SETL */
00375                 SETcc(TFLG_L);break;
00376         CASE_0F_B(0x9d)                                                                                         /* SETNL */
00377                 SETcc(TFLG_NL);break;
00378         CASE_0F_B(0x9e)                                                                                         /* SETLE */
00379                 SETcc(TFLG_LE);break;
00380         CASE_0F_B(0x9f)                                                                                         /* SETNLE */
00381                 SETcc(TFLG_NLE);break;
00382 #endif
00383         CASE_0F_W(0xa0)                                                                                         /* PUSH FS */           
00384                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00385                 Push_16(SegValue(fs));break;
00386         CASE_0F_W(0xa1)                                                                                         /* POP FS */    
00387                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00388                 if (CPU_PopSeg(fs,false)) RUNEXCEPTION();
00389                 break;
00390         CASE_0F_B(0xa2)                                                                                         /* CPUID */
00391                 if (!CPU_CPUID()) goto illegal_opcode;
00392                 break;
00393         CASE_0F_W(0xa3)                                                                                         /* BT Ew,Gw */
00394                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00395                 {
00396                         FillFlags();GetRMrw;
00397                         Bit16u mask=1u << (*rmrw & 15u);
00398                         if (rm >= 0xc0 ) {
00399                                 GetEArw;
00400                                 SETFLAGBIT(CF,(*earw & mask));
00401                         } else {
00402                                 GetEAa;eaa+=(PhysPt)((((Bit16s)*rmrw)>>4)*2);
00403                                 Bit16u old=LoadMw(eaa);
00404                                 SETFLAGBIT(CF,(old & mask));
00405                         }
00406                         break;
00407                 }
00408         CASE_0F_W(0xa4)                                                                                         /* SHLD Ew,Gw,Ib */
00409                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00410                 RMEwGwOp3(DSHLW,Fetchb());
00411                 break;
00412         CASE_0F_W(0xa5)                                                                                         /* SHLD Ew,Gw,CL */
00413                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00414                 RMEwGwOp3(DSHLW,reg_cl);
00415                 break;
00416         CASE_0F_W(0xa8)                                                                                         /* PUSH GS */           
00417                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00418                 Push_16(SegValue(gs));break;
00419         CASE_0F_W(0xa9)                                                                                         /* POP GS */            
00420                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00421                 if (CPU_PopSeg(gs,false)) RUNEXCEPTION();
00422                 break;
00423         CASE_0F_W(0xab)                                                                                         /* BTS Ew,Gw */
00424                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00425                 {
00426                         FillFlags();GetRMrw;
00427                         Bit16u mask=1u << (*rmrw & 15u);
00428                         if (rm >= 0xc0 ) {
00429                                 GetEArw;
00430                                 SETFLAGBIT(CF,(*earw & mask));
00431                                 *earw|=mask;
00432                         } else {
00433                                 GetEAa;eaa+=(PhysPt)((((Bit16s)*rmrw)>>4)*2);
00434                                 Bit16u old=LoadMw(eaa);
00435                                 SETFLAGBIT(CF,(old & mask));
00436                                 SaveMw(eaa,old | mask);
00437                         }
00438                         break;
00439                 }
00440         CASE_0F_W(0xac)                                                                                         /* SHRD Ew,Gw,Ib */
00441                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00442                 RMEwGwOp3(DSHRW,Fetchb());
00443                 break;
00444         CASE_0F_W(0xad)                                                                                         /* SHRD Ew,Gw,CL */
00445                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00446                 RMEwGwOp3(DSHRW,reg_cl);
00447                 break;
00448         CASE_0F_W(0xaf)                                                                                         /* IMUL Gw,Ew */
00449                 RMGwEwOp3(DIMULW,*rmrw);
00450                 break;
00451         CASE_0F_B(0xb0)                                                                                 /* cmpxchg Eb,Gb */
00452                 {
00453                         if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00454                         FillFlags();
00455                         GetRMrb;
00456                         if (rm >= 0xc0 ) {
00457                                 GetEArb;
00458                                 if (reg_al == *earb) {
00459                                         *earb=*rmrb;
00460                                         SETFLAGBIT(ZF,1);
00461                                 } else {
00462                                         reg_al = *earb;
00463                                         SETFLAGBIT(ZF,0);
00464                                 }
00465                         } else {
00466                                 GetEAa;
00467                                 Bit8u val = LoadMb(eaa);
00468                                 if (reg_al == val) { 
00469                                         SaveMb(eaa,*rmrb);
00470                                         SETFLAGBIT(ZF,1);
00471                                 } else {
00472                                         SaveMb(eaa,val);        // cmpxchg always issues a write
00473                                         reg_al = val;
00474                                         SETFLAGBIT(ZF,0);
00475                                 }
00476                         }
00477                         break;
00478                 }
00479         CASE_0F_W(0xb1)                                                                         /* cmpxchg Ew,Gw */
00480                 {
00481                         if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00482                         FillFlags();
00483                         GetRMrw;
00484                         if (rm >= 0xc0 ) {
00485                                 GetEArw;
00486                                 if(reg_ax == *earw) { 
00487                                         *earw = *rmrw;
00488                                         SETFLAGBIT(ZF,1);
00489                                 } else {
00490                                         reg_ax = *earw;
00491                                         SETFLAGBIT(ZF,0);
00492                                 }
00493                         } else {
00494                                 GetEAa;
00495                                 Bit16u val = LoadMw(eaa);
00496                                 if(reg_ax == val) { 
00497                                         SaveMw(eaa,*rmrw);
00498                                         SETFLAGBIT(ZF,1);
00499                                 } else {
00500                                         SaveMw(eaa,val);        // cmpxchg always issues a write
00501                                         reg_ax = val;
00502                                         SETFLAGBIT(ZF,0);
00503                                 }
00504                         }
00505                         break;
00506                 }
00507 
00508         CASE_0F_W(0xb2)                                                                                         /* LSS Ew */
00509                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00510                 {       
00511                         GetRMrw;
00512                         if (rm >= 0xc0) goto illegal_opcode;
00513                         GetEAa;
00514                         if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION();
00515                         *rmrw=LoadMw(eaa);
00516                         break;
00517                 }
00518         CASE_0F_W(0xb3)                                                                                         /* BTR Ew,Gw */
00519                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00520                 {
00521                         FillFlags();GetRMrw;
00522                         Bit16u mask=1u << (*rmrw & 15u);
00523                         if (rm >= 0xc0 ) {
00524                                 GetEArw;
00525                                 SETFLAGBIT(CF,(*earw & mask));
00526                                 *earw&= ~mask;
00527                         } else {
00528                                 GetEAa;eaa+=(PhysPt)((((Bit16s)*rmrw)>>4)*2);
00529                                 Bit16u old=LoadMw(eaa);
00530                                 SETFLAGBIT(CF,(old & mask));
00531                                 SaveMw(eaa,old & ~mask);
00532                         }
00533                         break;
00534                 }
00535         CASE_0F_W(0xb4)                                                                                         /* LFS Ew */
00536                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00537                 {       
00538                         GetRMrw;
00539                         if (rm >= 0xc0) goto illegal_opcode;
00540                         GetEAa;
00541                         if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION();
00542                         *rmrw=LoadMw(eaa);
00543                         break;
00544                 }
00545         CASE_0F_W(0xb5)                                                                                         /* LGS Ew */
00546                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00547                 {       
00548                         GetRMrw;
00549                         if (rm >= 0xc0) goto illegal_opcode;
00550                         GetEAa;
00551                         if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION();
00552                         *rmrw=LoadMw(eaa);
00553                         break;
00554                 }
00555         CASE_0F_W(0xb6)                                                                                         /* MOVZX Gw,Eb */
00556                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00557                 {
00558                         GetRMrw;                                                                                                                        
00559                         if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
00560                         else {GetEAa;*rmrw=LoadMb(eaa);}
00561                         break;
00562                 }
00563         CASE_0F_W(0xb7)                                                                                         /* MOVZX Gw,Ew */
00564         CASE_0F_W(0xbf)                                                                                         /* MOVSX Gw,Ew */
00565                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00566                 {
00567                         GetRMrw;                                                                                                                        
00568                         if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
00569                         else {GetEAa;*rmrw=LoadMw(eaa);}
00570                         break;
00571                 }
00572         CASE_0F_W(0xba)                                                                                         /* GRP8 Ew,Ib */
00573                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00574                 {
00575                         FillFlags();GetRM;
00576                         if (rm >= 0xc0 ) {
00577                                 GetEArw;
00578                                 Bit16u mask=1 << (Fetchb() & 15);
00579                                 SETFLAGBIT(CF,(*earw & mask));
00580                                 switch (rm & 0x38) {
00581                                 case 0x20:                                                                              /* BT */
00582                                         break;
00583                                 case 0x28:                                                                              /* BTS */
00584                                         *earw|=mask;
00585                                         break;
00586                                 case 0x30:                                                                              /* BTR */
00587                                         *earw&= ~mask;
00588                                         break;
00589                                 case 0x38:                                                                              /* BTC */
00590                                         *earw^=mask;
00591                                         break;
00592                                 default:
00593                                         E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
00594                                 }
00595                         } else {
00596                                 GetEAa;Bit16u old=LoadMw(eaa);
00597                                 Bit16u mask=1 << (Fetchb() & 15);
00598                                 SETFLAGBIT(CF,(old & mask));
00599                                 switch (rm & 0x38) {
00600                                 case 0x20:                                                                              /* BT */
00601                                         break;
00602                                 case 0x28:                                                                              /* BTS */
00603                                         SaveMw(eaa,old|mask);
00604                                         break;
00605                                 case 0x30:                                                                              /* BTR */
00606                                         SaveMw(eaa,old & ~mask);
00607                                         break;
00608                                 case 0x38:                                                                              /* BTC */
00609                                         SaveMw(eaa,old ^ mask);
00610                                         break;
00611                                 default:
00612                                         E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
00613                                 }
00614                         }
00615                         break;
00616                 }
00617         CASE_0F_W(0xbb)                                                                                         /* BTC Ew,Gw */
00618                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00619                 {
00620                         FillFlags();GetRMrw;
00621                         Bit16u mask=1u << (*rmrw & 15u);
00622                         if (rm >= 0xc0 ) {
00623                                 GetEArw;
00624                                 SETFLAGBIT(CF,(*earw & mask));
00625                                 *earw^=mask;
00626                         } else {
00627                                 GetEAa;eaa+=(PhysPt)((((Bit16s)*rmrw)>>4)*2);
00628                                 Bit16u old=LoadMw(eaa);
00629                                 SETFLAGBIT(CF,(old & mask));
00630                                 SaveMw(eaa,old ^ mask);
00631                         }
00632                         break;
00633                 }
00634         CASE_0F_W(0xbc)                                                                                         /* BSF Gw,Ew */
00635                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00636                 {
00637                         GetRMrw;
00638                         Bit16u value;
00639                         if (rm >= 0xc0) { GetEArw; value=*earw; } 
00640                         else                    { GetEAa; value=LoadMw(eaa); }
00641                         if (value==0) {
00642                                 SETFLAGBIT(ZF,true);
00643                         } else {
00644                                 Bit16u result = 0;
00645                                 while ((value & 0x01)==0) { result++; value>>=1; }
00646                                 SETFLAGBIT(ZF,false);
00647                                 *rmrw = result;
00648                         }
00649                         lflags.type=t_UNKNOWN;
00650                         break;
00651                 }
00652         CASE_0F_W(0xbd)                                                                                         /* BSR Gw,Ew */
00653                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00654                 {
00655                         GetRMrw;
00656                         Bit16u value;
00657                         if (rm >= 0xc0) { GetEArw; value=*earw; } 
00658                         else                    { GetEAa; value=LoadMw(eaa); }
00659                         if (value==0) {
00660                                 SETFLAGBIT(ZF,true);
00661                         } else {
00662                                 Bit16u result = 15;     // Operandsize-1
00663                                 while ((value & 0x8000)==0) { result--; value<<=1; }
00664                                 SETFLAGBIT(ZF,false);
00665                                 *rmrw = result;
00666                         }
00667                         lflags.type=t_UNKNOWN;
00668                         break;
00669                 }
00670         CASE_0F_W(0xbe)                                                                                         /* MOVSX Gw,Eb */
00671                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00672                 {
00673                         GetRMrw;                                                                                                                        
00674                         if (rm >= 0xc0 ) {GetEArb;*rmrw=(Bit16u)(*(Bit8s *)earb);}
00675                         else {GetEAa;*rmrw=(Bit16u)LoadMbs(eaa);}
00676                         break;
00677                 }
00678         CASE_0F_B(0xc0)                                                                                         /* XADD Gb,Eb */
00679                 {
00680                         if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00681                         GetRMrb;Bit8u oldrmrb=*rmrb;
00682                         if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;}
00683                         else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);}
00684                         break;
00685                 }
00686         CASE_0F_W(0xc1)                                                                                         /* XADD Gw,Ew */
00687                 {
00688                         if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00689                         GetRMrw;Bit16u oldrmrw=*rmrw;
00690                         if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;}
00691                         else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);}
00692                         break;
00693                 }
00694     CASE_0F_W(0xc7)
00695         {
00696             extern bool enable_cmpxchg8b;
00697             void CPU_CMPXCHG8B(PhysPt eaa);
00698 
00699             if (!enable_cmpxchg8b || CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUM) goto illegal_opcode;
00700             GetRM;
00701             if (((rm >> 3) & 7) == 1) { // CMPXCHG8B /1 r/m
00702                 if (rm >= 0xc0 ) goto illegal_opcode;
00703                 GetEAa;
00704                 CPU_CMPXCHG8B(eaa);
00705             }
00706             else {
00707                 goto illegal_opcode;
00708             }
00709             break;
00710         }
00711         CASE_0F_W(0xc8)                                                                                         /* BSWAP AX */
00712                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00713                 BSWAPW(reg_ax);break;
00714         CASE_0F_W(0xc9)                                                                                         /* BSWAP CX */
00715                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00716                 BSWAPW(reg_cx);break;
00717         CASE_0F_W(0xca)                                                                                         /* BSWAP DX */
00718                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00719                 BSWAPW(reg_dx);break;
00720         CASE_0F_W(0xcb)                                                                                         /* BSWAP BX */
00721                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00722                 BSWAPW(reg_bx);break;
00723         CASE_0F_W(0xcc)                                                                                         /* BSWAP SP */
00724                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00725                 BSWAPW(reg_sp);break;
00726         CASE_0F_W(0xcd)                                                                                         /* BSWAP BP */
00727                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00728                 BSWAPW(reg_bp);break;
00729         CASE_0F_W(0xce)                                                                                         /* BSWAP SI */
00730                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00731                 BSWAPW(reg_si);break;
00732         CASE_0F_W(0xcf)                                                                                         /* BSWAP DI */
00733                 if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLD) goto illegal_opcode;
00734                 BSWAPW(reg_di);break;
00735 #if C_FPU
00736 #define CASE_0F_MMX(x) CASE_0F_W(x)
00737 #include "prefix_0f_mmx.h"
00738 #undef CASE_0F_MMX
00739 #endif