DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_normal/prefix_0f_mmx.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 /* State Management */
00020         CASE_0F_MMX(0x77)                                                                                               /* EMMS */
00021         {
00022                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00023                 setFPUTagEmpty();
00024                 break;
00025         }
00026 
00027 
00028 /* Data Movement */
00029         CASE_0F_MMX(0x6e)                                                                                               /* MOVD Pq,Ed */
00030         {
00031                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00032                 GetRM;
00033                 MMX_reg* rmrq=lookupRMregMM[rm];
00034                 if (rm>=0xc0) {
00035                         GetEArd;
00036                         rmrq->ud.d0=*(Bit32u*)eard;
00037                         rmrq->ud.d1=0;
00038                 } else {
00039                         GetEAa;
00040                         rmrq->ud.d0=LoadMd(eaa);
00041                         rmrq->ud.d1=0;
00042                 }
00043                 break;
00044         }
00045         CASE_0F_MMX(0x7e)                                                                                               /* MOVD Ed,Pq */
00046         {
00047                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00048                 GetRM;
00049                 MMX_reg* rmrq=lookupRMregMM[rm];
00050                 if (rm>=0xc0) {
00051                         GetEArd;
00052                         *(Bit32u*)eard=rmrq->ud.d0;
00053                 } else {
00054                         GetEAa;
00055                         SaveMd(eaa,rmrq->ud.d0);
00056                 }
00057                 break;
00058         }
00059 
00060         CASE_0F_MMX(0x6f)                                                                                               /* MOVQ Pq,Qq */
00061         {
00062                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00063                 GetRM;
00064                 MMX_reg* dest=lookupRMregMM[rm];
00065                 if (rm>=0xc0) {
00066                         MMX_reg* src=reg_mmx[rm&7];
00067                         dest->q = src->q;
00068                 } else {
00069                         GetEAa;
00070                         dest->q=LoadMq(eaa);
00071                 }
00072                 break;
00073         }
00074         CASE_0F_MMX(0x7f)                                                                                               /* MOVQ Qq,Pq */
00075         {
00076                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00077                 GetRM;
00078                 MMX_reg* dest=lookupRMregMM[rm];
00079                 if (rm>=0xc0) {
00080                         MMX_reg* src=reg_mmx[rm&7];
00081                         src->q = dest->q;
00082                 } else {
00083                         GetEAa;
00084                         SaveMq(eaa,dest->q);
00085                 }
00086                 break;
00087         }
00088 
00089 /* Boolean Logic */
00090         CASE_0F_MMX(0xef)                                                                                               /* PXOR Pq,Qq */
00091         {
00092                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00093                 GetRM;
00094                 MMX_reg* dest=lookupRMregMM[rm];
00095                 if (rm>=0xc0) {
00096                         MMX_reg* src=reg_mmx[rm&7];
00097                         dest->q ^= src->q;
00098                 } else {
00099                         GetEAa;
00100                         dest->q ^= LoadMq(eaa);
00101                 }
00102                 break;
00103         }
00104 
00105         CASE_0F_MMX(0xeb)                                                                                               /* POR Pq,Qq */
00106         {
00107                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00108                 GetRM;
00109                 MMX_reg* dest=lookupRMregMM[rm];
00110                 if (rm>=0xc0) {
00111                         MMX_reg* src=reg_mmx[rm&7];
00112                         dest->q |= src->q;
00113                 } else {
00114                         GetEAa;
00115                         dest->q |= LoadMq(eaa);
00116                 }
00117                 break;
00118         }
00119         CASE_0F_MMX(0xdb)                                                                                               /* PAND Pq,Qq */
00120         {
00121                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00122                 GetRM;
00123                 MMX_reg* dest=lookupRMregMM[rm];
00124                 if (rm>=0xc0) {
00125                         MMX_reg* src=reg_mmx[rm&7];
00126                         dest->q &= src->q;
00127                 } else {
00128                         GetEAa;
00129                         dest->q &= LoadMq(eaa);
00130                 }
00131                 break;
00132         }
00133         CASE_0F_MMX(0xdf)                                                                                               /* PANDN Pq,Qq */
00134         {
00135                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00136                 GetRM;
00137                 MMX_reg* dest=lookupRMregMM[rm];
00138                 if (rm>=0xc0) {
00139                         MMX_reg* src=reg_mmx[rm&7];
00140                         dest->q = ~dest->q & src->q;
00141                 } else {
00142                         GetEAa;
00143                         dest->q = ~dest->q & LoadMq(eaa);
00144                 }
00145                 break;
00146         }
00147 
00148 /* Shift */
00149         CASE_0F_MMX(0xf1)                                                                                               /* PSLLW Pq,Qq */
00150         {
00151                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00152                 GetRM;
00153                 MMX_reg* dest=lookupRMregMM[rm];
00154                 MMX_reg src;
00155                 if (rm>=0xc0) {
00156                         src.q=reg_mmx[rm&7]->q;
00157                 } else {
00158                         GetEAa;
00159                         src.q=LoadMq(eaa);
00160                 }
00161                 if (src.ub.b0 > 15) dest->q = 0;
00162                 else {
00163                         dest->uw.w0 <<= src.ub.b0;
00164                         dest->uw.w1 <<= src.ub.b0;
00165                         dest->uw.w2 <<= src.ub.b0;
00166                         dest->uw.w3 <<= src.ub.b0;
00167                 }
00168                 break;
00169         }
00170         CASE_0F_MMX(0xd1)                                                                                               /* PSRLW Pq,Qq */
00171         {
00172                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00173                 GetRM;
00174                 MMX_reg* dest=lookupRMregMM[rm];
00175                 MMX_reg src;
00176                 if (rm>=0xc0) {
00177                         src.q=reg_mmx[rm&7]->q;
00178                 } else {
00179                         GetEAa;
00180                         src.q=LoadMq(eaa);
00181                 }
00182                 if (src.ub.b0 > 15) dest->q = 0;
00183                 else {
00184                         dest->uw.w0 >>= src.ub.b0;
00185                         dest->uw.w1 >>= src.ub.b0;
00186                         dest->uw.w2 >>= src.ub.b0;
00187                         dest->uw.w3 >>= src.ub.b0;
00188                 }
00189                 break;
00190         }
00191         CASE_0F_MMX(0xe1)                                                                                               /* PSRAW Pq,Qq */
00192         {
00193                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00194                 GetRM;
00195                 MMX_reg* dest=lookupRMregMM[rm];
00196                 MMX_reg src;
00197                 MMX_reg tmp;
00198                 tmp.q = dest->q;
00199                 if (rm>=0xc0) {
00200                         src.q=reg_mmx[rm&7]->q;
00201                 } else {
00202                         GetEAa;
00203                         src.q=LoadMq(eaa);
00204                 }
00205                 if (!src.q) break;
00206                 if (src.ub.b0 > 15) {
00207                         dest->uw.w0 = (tmp.uw.w0&0x8000)?0xffff:0;
00208                         dest->uw.w1 = (tmp.uw.w1&0x8000)?0xffff:0;
00209                         dest->uw.w2 = (tmp.uw.w2&0x8000)?0xffff:0;
00210                         dest->uw.w3 = (tmp.uw.w3&0x8000)?0xffff:0;
00211                 } else {
00212                         dest->uw.w0 >>= src.ub.b0;
00213                         dest->uw.w1 >>= src.ub.b0;
00214                         dest->uw.w2 >>= src.ub.b0;
00215                         dest->uw.w3 >>= src.ub.b0;
00216                         if (tmp.uw.w0&0x8000) dest->uw.w0 |= (0xffff << (16 - src.ub.b0));
00217                         if (tmp.uw.w1&0x8000) dest->uw.w1 |= (0xffff << (16 - src.ub.b0));
00218                         if (tmp.uw.w2&0x8000) dest->uw.w2 |= (0xffff << (16 - src.ub.b0));
00219                         if (tmp.uw.w3&0x8000) dest->uw.w3 |= (0xffff << (16 - src.ub.b0));
00220                 }
00221                 break;
00222         }
00223         CASE_0F_MMX(0x71)                                                                                               /* PSLLW/PSRLW/PSRAW Pq,Ib */
00224         {
00225                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00226                 GetRM;
00227                 Bit8u op=(rm>>3)&7;
00228                 Bit8u shift=Fetchb();
00229                 MMX_reg* dest=reg_mmx[rm&7];
00230                 switch (op) {
00231                         case 0x06:      /*PSLLW*/
00232                                 if (shift > 15) dest->q = 0;
00233                                 else {
00234                                         dest->uw.w0 <<= shift;
00235                                         dest->uw.w1 <<= shift;
00236                                         dest->uw.w2 <<= shift;
00237                                         dest->uw.w3 <<= shift;
00238                                 }
00239                                 break;
00240                         case 0x02:  /*PSRLW*/
00241                                 if (shift > 15) dest->q = 0;
00242                                 else {
00243                                         dest->uw.w0 >>= shift;
00244                                         dest->uw.w1 >>= shift;
00245                                         dest->uw.w2 >>= shift;
00246                                         dest->uw.w3 >>= shift;
00247                                 }
00248                                 break;
00249                         case 0x04:  /*PSRAW*/
00250                                 MMX_reg tmp;
00251                                 if (!shift) break;
00252                                 tmp.q = dest->q;
00253                                 if (shift > 15) {
00254                                         dest->uw.w0 = (tmp.uw.w0&0x8000)?0xffff:0;
00255                                         dest->uw.w1 = (tmp.uw.w1&0x8000)?0xffff:0;
00256                                         dest->uw.w2 = (tmp.uw.w2&0x8000)?0xffff:0;
00257                                         dest->uw.w3 = (tmp.uw.w3&0x8000)?0xffff:0;
00258                                 } else {
00259                                         dest->uw.w0 >>= shift;
00260                                         dest->uw.w1 >>= shift;
00261                                         dest->uw.w2 >>= shift;
00262                                         dest->uw.w3 >>= shift;
00263                                         if (tmp.uw.w0&0x8000) dest->uw.w0 |= (0xffff << (16 - shift));
00264                                         if (tmp.uw.w1&0x8000) dest->uw.w1 |= (0xffff << (16 - shift));
00265                                         if (tmp.uw.w2&0x8000) dest->uw.w2 |= (0xffff << (16 - shift));
00266                                         if (tmp.uw.w3&0x8000) dest->uw.w3 |= (0xffff << (16 - shift));
00267                                 }
00268                                 break;
00269                 }
00270                 break;
00271         }
00272         CASE_0F_MMX(0xf2)                                                                                               /* PSLLD Pq,Qq */
00273         {
00274                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00275                 GetRM;
00276                 MMX_reg* dest=lookupRMregMM[rm];
00277                 MMX_reg src;
00278                 if (rm>=0xc0) {
00279                         src.q=reg_mmx[rm&7]->q;
00280                 } else {
00281                         GetEAa;
00282                         src.q=LoadMq(eaa);
00283                 }
00284                 if (src.ub.b0 > 31) dest->q = 0;
00285                 else {
00286                         dest->ud.d0 <<= src.ub.b0;
00287                         dest->ud.d1 <<= src.ub.b0;
00288                 }
00289                 break;
00290         }
00291         CASE_0F_MMX(0xd2)                                                                                               /* PSRLD Pq,Qq */
00292         {
00293                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00294                 GetRM;
00295                 MMX_reg* dest=lookupRMregMM[rm];
00296                 MMX_reg src;
00297                 if (rm>=0xc0) {
00298                         src.q=reg_mmx[rm&7]->q;
00299                 } else {
00300                         GetEAa;
00301                         src.q=LoadMq(eaa);
00302                 }
00303                 if (src.ub.b0 > 31) dest->q = 0;
00304                 else {
00305                         dest->ud.d0 >>= src.ub.b0;
00306                         dest->ud.d1 >>= src.ub.b0;
00307                 }
00308                 break;
00309         }
00310         CASE_0F_MMX(0xe2)                                                                                               /* PSRAD Pq,Qq */
00311         {
00312                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00313                 GetRM;
00314                 MMX_reg* dest=lookupRMregMM[rm];
00315                 MMX_reg src;
00316                 MMX_reg tmp;
00317                 tmp.q = dest->q;
00318                 if (rm>=0xc0) {
00319                         src.q=reg_mmx[rm&7]->q;
00320                 } else {
00321                         GetEAa;
00322                         src.q=LoadMq(eaa);
00323                 }
00324                 if (!src.q) break;
00325                 if (src.ub.b0 > 31) {
00326                         dest->ud.d0 = (tmp.ud.d0&0x80000000)?0xffffffff:0;
00327                         dest->ud.d1 = (tmp.ud.d1&0x80000000)?0xffffffff:0;
00328                 } else {
00329                         dest->ud.d0 >>= src.ub.b0;
00330                         dest->ud.d1 >>= src.ub.b0;
00331                         if (tmp.ud.d0&0x80000000) dest->ud.d0 |= (0xffffffff << (32 - src.ub.b0));
00332                         if (tmp.ud.d1&0x80000000) dest->ud.d1 |= (0xffffffff << (32 - src.ub.b0));
00333                 }
00334                 break;
00335         }
00336         CASE_0F_MMX(0x72)                                                                                               /* PSLLD/PSRLD/PSRAD Pq,Ib */
00337         {
00338                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00339                 GetRM;
00340                 Bit8u op=(rm>>3)&7;
00341                 Bit8u shift=Fetchb();
00342                 MMX_reg* dest=reg_mmx[rm&7];
00343                 switch (op) {
00344                         case 0x06:      /*PSLLD*/
00345                                 if (shift > 31) dest->q = 0;
00346                                 else {
00347                                         dest->ud.d0 <<= shift;
00348                                         dest->ud.d1 <<= shift;
00349                                 }
00350                                 break;
00351                         case 0x02:  /*PSRLD*/
00352                                 if (shift > 31) dest->q = 0;
00353                                 else {
00354                                         dest->ud.d0 >>= shift;
00355                                         dest->ud.d1 >>= shift;
00356                                 }
00357                                 break;
00358                         case 0x04:  /*PSRAD*/
00359                                 MMX_reg tmp;
00360                                 if (!shift) break;
00361                                 tmp.q = dest->q;
00362                                 if (shift > 31) { 
00363                                         dest->ud.d0 = (tmp.ud.d0&0x80000000)?0xffffffff:0;
00364                                         dest->ud.d1 = (tmp.ud.d1&0x80000000)?0xffffffff:0;
00365                                 } else {
00366                                         dest->ud.d0 >>= shift;
00367                                         dest->ud.d1 >>= shift;
00368                                         if (tmp.ud.d0&0x80000000) dest->ud.d0 |= (0xffffffff << (32 - shift));
00369                                         if (tmp.ud.d1&0x80000000) dest->ud.d1 |= (0xffffffff << (32 - shift));
00370                                 }
00371                                 break;
00372                 }
00373                 break;
00374         }
00375 
00376         CASE_0F_MMX(0xf3)                                                                                               /* PSLLQ Pq,Qq */
00377         {
00378                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00379                 GetRM;
00380                 MMX_reg* dest=lookupRMregMM[rm];
00381                 MMX_reg src;
00382                 if (rm>=0xc0) {
00383                         src.q=reg_mmx[rm&7]->q;
00384                 } else {
00385                         GetEAa;
00386                         src.q=LoadMq(eaa);
00387                 }
00388                 if (src.ub.b0 > 63) dest->q = 0;
00389                 else dest->q <<= src.ub.b0;
00390                 break;
00391         }
00392         CASE_0F_MMX(0xd3)                                                                                               /* PSRLQ Pq,Qq */
00393         {
00394                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00395                 GetRM;
00396                 MMX_reg* dest=lookupRMregMM[rm];
00397                 MMX_reg src;
00398                 if (rm>=0xc0) {
00399                         src.q=reg_mmx[rm&7]->q;
00400                 } else {
00401                         GetEAa;
00402                         src.q=LoadMq(eaa);
00403                 }
00404                 if (src.ub.b0 > 63) dest->q = 0;
00405                 else dest->q >>= src.ub.b0;
00406                 break;
00407         }
00408         CASE_0F_MMX(0x73)                                                                                               /* PSLLQ/PSRLQ Pq,Ib */
00409         {
00410                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00411                 GetRM;
00412                 Bit8u shift=Fetchb();
00413                 MMX_reg* dest=reg_mmx[rm&7];
00414                 if (shift > 63) dest->q = 0;
00415                 else {
00416                         Bit8u op=rm&0x20;
00417                         if (op) {
00418                                 dest->q <<= shift;
00419                         } else {
00420                                 dest->q >>= shift;
00421                         }
00422                 }
00423                 break;
00424         }
00425 
00426 /* Math */
00427         CASE_0F_MMX(0xFC)                                                                                               /* PADDB Pq,Qq */
00428         {
00429                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00430                 GetRM;
00431                 MMX_reg* dest=lookupRMregMM[rm];
00432                 MMX_reg src;
00433                 if (rm>=0xc0) {
00434                         src.q=reg_mmx[rm&7]->q;
00435                 } else {
00436                         GetEAa;
00437                         src.q = LoadMq(eaa);
00438                 }
00439                 dest->ub.b0 += src.ub.b0;
00440                 dest->ub.b1 += src.ub.b1;
00441                 dest->ub.b2 += src.ub.b2;
00442                 dest->ub.b3 += src.ub.b3;
00443                 dest->ub.b4 += src.ub.b4;
00444                 dest->ub.b5 += src.ub.b5;
00445                 dest->ub.b6 += src.ub.b6;
00446                 dest->ub.b7 += src.ub.b7;
00447                 break;
00448         }
00449         CASE_0F_MMX(0xFD)                                                                                               /* PADDW Pq,Qq */
00450         {
00451                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00452                 GetRM;
00453                 MMX_reg* dest=lookupRMregMM[rm];
00454                 MMX_reg src;
00455                 if (rm>=0xc0) {
00456                         src.q=reg_mmx[rm&7]->q;
00457                 } else {
00458                         GetEAa;
00459                         src.q = LoadMq(eaa);
00460                 }
00461                 dest->uw.w0 += src.uw.w0;
00462                 dest->uw.w1 += src.uw.w1;
00463                 dest->uw.w2 += src.uw.w2;
00464                 dest->uw.w3 += src.uw.w3;
00465                 break;
00466         }
00467         CASE_0F_MMX(0xFE)                                                                                               /* PADDD Pq,Qq */
00468         {
00469                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00470                 GetRM;
00471                 MMX_reg* dest=lookupRMregMM[rm];
00472                 MMX_reg src;
00473                 if (rm>=0xc0) {
00474                         src.q=reg_mmx[rm&7]->q;
00475                 } else {
00476                         GetEAa;
00477                         src.q = LoadMq(eaa);
00478                 }
00479                 dest->ud.d0 += src.ud.d0;
00480                 dest->ud.d1 += src.ud.d1;
00481                 break;
00482         }
00483         CASE_0F_MMX(0xEC)                                                                                               /* PADDSB Pq,Qq */
00484         {
00485                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00486                 GetRM;
00487                 MMX_reg* dest=lookupRMregMM[rm];
00488                 MMX_reg src;
00489                 if (rm>=0xc0) {
00490                         src.q = reg_mmx[rm&7]->q;
00491                 } else {
00492                         GetEAa;
00493                         src.q = LoadMq(eaa);
00494                 }
00495                 dest->sb.b0 = SaturateWordSToByteS((Bit16s)dest->sb.b0+(Bit16s)src.sb.b0);
00496                 dest->sb.b1 = SaturateWordSToByteS((Bit16s)dest->sb.b1+(Bit16s)src.sb.b1);
00497                 dest->sb.b2 = SaturateWordSToByteS((Bit16s)dest->sb.b2+(Bit16s)src.sb.b2);
00498                 dest->sb.b3 = SaturateWordSToByteS((Bit16s)dest->sb.b3+(Bit16s)src.sb.b3);
00499                 dest->sb.b4 = SaturateWordSToByteS((Bit16s)dest->sb.b4+(Bit16s)src.sb.b4);
00500                 dest->sb.b5 = SaturateWordSToByteS((Bit16s)dest->sb.b5+(Bit16s)src.sb.b5);
00501                 dest->sb.b6 = SaturateWordSToByteS((Bit16s)dest->sb.b6+(Bit16s)src.sb.b6);
00502                 dest->sb.b7 = SaturateWordSToByteS((Bit16s)dest->sb.b7+(Bit16s)src.sb.b7);
00503                 break;
00504         }
00505         CASE_0F_MMX(0xED)                                                                                               /* PADDSW Pq,Qq */
00506         {
00507                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00508                 GetRM;
00509                 MMX_reg* dest=lookupRMregMM[rm];
00510                 MMX_reg src;
00511                 if (rm>=0xc0) {
00512                         src.q = reg_mmx[rm&7]->q;
00513                 } else {
00514                         GetEAa;
00515                         src.q = LoadMq(eaa);
00516                 }
00517                 dest->sw.w0 = SaturateDwordSToWordS((Bit32s)dest->sw.w0+(Bit32s)src.sw.w0);
00518                 dest->sw.w1 = SaturateDwordSToWordS((Bit32s)dest->sw.w1+(Bit32s)src.sw.w1);
00519                 dest->sw.w2 = SaturateDwordSToWordS((Bit32s)dest->sw.w2+(Bit32s)src.sw.w2);
00520                 dest->sw.w3 = SaturateDwordSToWordS((Bit32s)dest->sw.w3+(Bit32s)src.sw.w3);
00521                 break;
00522         }
00523         CASE_0F_MMX(0xDC)                                                                                               /* PADDUSB Pq,Qq */
00524         {
00525                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00526                 GetRM;
00527                 MMX_reg* dest=lookupRMregMM[rm];
00528                 MMX_reg src;
00529                 if (rm>=0xc0) {
00530                         src.q = reg_mmx[rm&7]->q;
00531                 } else {
00532                         GetEAa;
00533                         src.q = LoadMq(eaa);
00534                 }
00535                 dest->ub.b0 = SaturateWordSToByteU((Bit16s)dest->ub.b0+(Bit16s)src.ub.b0);
00536                 dest->ub.b1 = SaturateWordSToByteU((Bit16s)dest->ub.b1+(Bit16s)src.ub.b1);
00537                 dest->ub.b2 = SaturateWordSToByteU((Bit16s)dest->ub.b2+(Bit16s)src.ub.b2);
00538                 dest->ub.b3 = SaturateWordSToByteU((Bit16s)dest->ub.b3+(Bit16s)src.ub.b3);
00539                 dest->ub.b4 = SaturateWordSToByteU((Bit16s)dest->ub.b4+(Bit16s)src.ub.b4);
00540                 dest->ub.b5 = SaturateWordSToByteU((Bit16s)dest->ub.b5+(Bit16s)src.ub.b5);
00541                 dest->ub.b6 = SaturateWordSToByteU((Bit16s)dest->ub.b6+(Bit16s)src.ub.b6);
00542                 dest->ub.b7 = SaturateWordSToByteU((Bit16s)dest->ub.b7+(Bit16s)src.ub.b7);
00543                 break;
00544         }
00545         CASE_0F_MMX(0xDD)                                                                                               /* PADDUSW Pq,Qq */
00546         {
00547                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00548                 GetRM;
00549                 MMX_reg* dest=lookupRMregMM[rm];
00550                 MMX_reg src;
00551                 if (rm>=0xc0) {
00552                         src.q = reg_mmx[rm&7]->q;
00553                 } else {
00554                         GetEAa;
00555                         src.q = LoadMq(eaa);
00556                 }
00557                 dest->uw.w0 = SaturateDwordSToWordU((Bit32s)dest->uw.w0+(Bit32s)src.uw.w0);
00558                 dest->uw.w1 = SaturateDwordSToWordU((Bit32s)dest->uw.w1+(Bit32s)src.uw.w1);
00559                 dest->uw.w2 = SaturateDwordSToWordU((Bit32s)dest->uw.w2+(Bit32s)src.uw.w2);
00560                 dest->uw.w3 = SaturateDwordSToWordU((Bit32s)dest->uw.w3+(Bit32s)src.uw.w3);
00561                 break;
00562         }
00563         CASE_0F_MMX(0xF8)                                                                                               /* PSUBB Pq,Qq */
00564         {
00565                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00566                 GetRM;
00567                 MMX_reg* dest=lookupRMregMM[rm];
00568                 MMX_reg src;
00569                 if (rm>=0xc0) {
00570                         src.q=reg_mmx[rm&7]->q;
00571                 } else {
00572                         GetEAa;
00573                         src.q = LoadMq(eaa);
00574                 }
00575                 dest->ub.b0 -= src.ub.b0;
00576                 dest->ub.b1 -= src.ub.b1;
00577                 dest->ub.b2 -= src.ub.b2;
00578                 dest->ub.b3 -= src.ub.b3;
00579                 dest->ub.b4 -= src.ub.b4;
00580                 dest->ub.b5 -= src.ub.b5;
00581                 dest->ub.b6 -= src.ub.b6;
00582                 dest->ub.b7 -= src.ub.b7;
00583                 break;
00584         }
00585         CASE_0F_MMX(0xF9)                                                                                               /* PSUBW Pq,Qq */
00586         {
00587                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00588                 GetRM;
00589                 MMX_reg* dest=lookupRMregMM[rm];
00590                 MMX_reg src;
00591                 if (rm>=0xc0) {
00592                         src.q=reg_mmx[rm&7]->q;
00593                 } else {
00594                         GetEAa;
00595                         src.q = LoadMq(eaa);
00596                 }
00597                 dest->uw.w0 -= src.uw.w0;
00598                 dest->uw.w1 -= src.uw.w1;
00599                 dest->uw.w2 -= src.uw.w2;
00600                 dest->uw.w3 -= src.uw.w3;
00601                 break;
00602         }
00603         CASE_0F_MMX(0xFA)                                                                                               /* PSUBD Pq,Qq */
00604         {
00605                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00606                 GetRM;
00607                 MMX_reg* dest=lookupRMregMM[rm];
00608                 MMX_reg src;
00609                 if (rm>=0xc0) {
00610                         src.q=reg_mmx[rm&7]->q;
00611                 } else {
00612                         GetEAa;
00613                         src.q = LoadMq(eaa);
00614                 }
00615                 dest->ud.d0 -= src.ud.d0;
00616                 dest->ud.d1 -= src.ud.d1;
00617                 break;
00618         }
00619         CASE_0F_MMX(0xE8)                                                                                               /* PSUBSB Pq,Qq */
00620         {
00621                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00622                 GetRM;
00623                 MMX_reg* dest=lookupRMregMM[rm];
00624                 MMX_reg src;
00625                 if (rm>=0xc0) {
00626                         src.q = reg_mmx[rm&7]->q;
00627                 } else {
00628                         GetEAa;
00629                         src.q = LoadMq(eaa);
00630                 }
00631                 dest->sb.b0 = SaturateWordSToByteS((Bit16s)dest->sb.b0-(Bit16s)src.sb.b0);
00632                 dest->sb.b1 = SaturateWordSToByteS((Bit16s)dest->sb.b1-(Bit16s)src.sb.b1);
00633                 dest->sb.b2 = SaturateWordSToByteS((Bit16s)dest->sb.b2-(Bit16s)src.sb.b2);
00634                 dest->sb.b3 = SaturateWordSToByteS((Bit16s)dest->sb.b3-(Bit16s)src.sb.b3);
00635                 dest->sb.b4 = SaturateWordSToByteS((Bit16s)dest->sb.b4-(Bit16s)src.sb.b4);
00636                 dest->sb.b5 = SaturateWordSToByteS((Bit16s)dest->sb.b5-(Bit16s)src.sb.b5);
00637                 dest->sb.b6 = SaturateWordSToByteS((Bit16s)dest->sb.b6-(Bit16s)src.sb.b6);
00638                 dest->sb.b7 = SaturateWordSToByteS((Bit16s)dest->sb.b7-(Bit16s)src.sb.b7);
00639                 break;
00640         }
00641         CASE_0F_MMX(0xE9)                                                                                               /* PSUBSW Pq,Qq */
00642         {
00643                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00644                 GetRM;
00645                 MMX_reg* dest=lookupRMregMM[rm];
00646                 MMX_reg src;
00647                 if (rm>=0xc0) {
00648                         src.q = reg_mmx[rm&7]->q;
00649                 } else {
00650                         GetEAa;
00651                         src.q = LoadMq(eaa);
00652                 }
00653                 dest->sw.w0 = SaturateDwordSToWordS((Bit32s)dest->sw.w0-(Bit32s)src.sw.w0);
00654                 dest->sw.w1 = SaturateDwordSToWordS((Bit32s)dest->sw.w1-(Bit32s)src.sw.w1);
00655                 dest->sw.w2 = SaturateDwordSToWordS((Bit32s)dest->sw.w2-(Bit32s)src.sw.w2);
00656                 dest->sw.w3 = SaturateDwordSToWordS((Bit32s)dest->sw.w3-(Bit32s)src.sw.w3);
00657                 break;
00658         }
00659         CASE_0F_MMX(0xD8)                                                                                               /* PSUBUSB Pq,Qq */
00660         {
00661                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00662                 GetRM;
00663                 MMX_reg* dest=lookupRMregMM[rm];
00664                 MMX_reg src;
00665                 MMX_reg result;
00666                 if (rm>=0xc0) {
00667                         src.q = reg_mmx[rm&7]->q;
00668                 } else {
00669                         GetEAa;
00670                         src.q = LoadMq(eaa);
00671                 }
00672                 result.q = 0;
00673                 if (dest->ub.b0>src.ub.b0) result.ub.b0 = dest->ub.b0 - src.ub.b0;
00674                 if (dest->ub.b1>src.ub.b1) result.ub.b1 = dest->ub.b1 - src.ub.b1;
00675                 if (dest->ub.b2>src.ub.b2) result.ub.b2 = dest->ub.b2 - src.ub.b2;
00676                 if (dest->ub.b3>src.ub.b3) result.ub.b3 = dest->ub.b3 - src.ub.b3;
00677                 if (dest->ub.b4>src.ub.b4) result.ub.b4 = dest->ub.b4 - src.ub.b4;
00678                 if (dest->ub.b5>src.ub.b5) result.ub.b5 = dest->ub.b5 - src.ub.b5;
00679                 if (dest->ub.b6>src.ub.b6) result.ub.b6 = dest->ub.b6 - src.ub.b6;
00680                 if (dest->ub.b7>src.ub.b7) result.ub.b7 = dest->ub.b7 - src.ub.b7;
00681                 dest->q = result.q;
00682                 break;
00683         }
00684 
00685         CASE_0F_MMX(0xD9)                                                                                               /* PSUBUSW Pq,Qq */
00686         {
00687                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00688                 GetRM;
00689                 MMX_reg* dest=lookupRMregMM[rm];
00690                 MMX_reg src;
00691                 MMX_reg result;
00692                 if (rm>=0xc0) {
00693                         src.q = reg_mmx[rm&7]->q;
00694                 } else {
00695                         GetEAa;
00696                         src.q = LoadMq(eaa);
00697                 }
00698                 result.q = 0;
00699                 if (dest->uw.w0>src.uw.w0) result.uw.w0 = dest->uw.w0 - src.uw.w0;
00700                 if (dest->uw.w1>src.uw.w1) result.uw.w1 = dest->uw.w1 - src.uw.w1;
00701                 if (dest->uw.w2>src.uw.w2) result.uw.w2 = dest->uw.w2 - src.uw.w2;
00702                 if (dest->uw.w3>src.uw.w3) result.uw.w3 = dest->uw.w3 - src.uw.w3;
00703                 dest->q = result.q;
00704                 break;
00705         }
00706         CASE_0F_MMX(0xE5)                                                                                               /* PMULHW Pq,Qq */
00707         {
00708                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00709                 GetRM;
00710                 MMX_reg* dest=lookupRMregMM[rm];
00711                 MMX_reg src;
00712                 if (rm>=0xc0) {
00713                         src.q = reg_mmx[rm&7]->q;
00714                 } else {
00715                         GetEAa;
00716                         src.q = LoadMq(eaa);
00717                 }
00718                 Bit32s product0 = (Bit32s)dest->sw.w0 * (Bit32s)src.sw.w0;
00719                 Bit32s product1 = (Bit32s)dest->sw.w1 * (Bit32s)src.sw.w1;
00720                 Bit32s product2 = (Bit32s)dest->sw.w2 * (Bit32s)src.sw.w2;
00721                 Bit32s product3 = (Bit32s)dest->sw.w3 * (Bit32s)src.sw.w3;
00722                 dest->uw.w0 = (Bit16u)(product0 >> 16);
00723                 dest->uw.w1 = (Bit16u)(product1 >> 16);
00724                 dest->uw.w2 = (Bit16u)(product2 >> 16);
00725                 dest->uw.w3 = (Bit16u)(product3 >> 16);
00726                 break;
00727         }
00728         CASE_0F_MMX(0xD5)                                                                                               /* PMULLW Pq,Qq */
00729         {
00730                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00731                 GetRM;
00732                 MMX_reg* dest=lookupRMregMM[rm];
00733                 MMX_reg src;
00734                 if (rm>=0xc0) {
00735                         src.q = reg_mmx[rm&7]->q;
00736                 } else {
00737                         GetEAa;
00738                         src.q = LoadMq(eaa);
00739                 }
00740                 Bit32u product0 = (Bit32u)dest->uw.w0 * (Bit32u)src.uw.w0;
00741                 Bit32u product1 = (Bit32u)dest->uw.w1 * (Bit32u)src.uw.w1;
00742                 Bit32u product2 = (Bit32u)dest->uw.w2 * (Bit32u)src.uw.w2;
00743                 Bit32u product3 = (Bit32u)dest->uw.w3 * (Bit32u)src.uw.w3;
00744                 dest->uw.w0 = (product0 & 0xffff);
00745                 dest->uw.w1 = (product1 & 0xffff);
00746                 dest->uw.w2 = (product2 & 0xffff);
00747                 dest->uw.w3 = (product3 & 0xffff);
00748                 break;
00749         }
00750         CASE_0F_MMX(0xF5)                                                                                               /* PMADDWD Pq,Qq */
00751         {
00752                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00753                 GetRM;
00754                 MMX_reg* dest=lookupRMregMM[rm];
00755                 MMX_reg src;
00756                 if (rm>=0xc0) {
00757                         src.q = reg_mmx[rm&7]->q;
00758                 } else {
00759                         GetEAa;
00760                         src.q = LoadMq(eaa);
00761                 }
00762                 if (dest->ud.d0 == 0x80008000 && src.ud.d0 == 0x80008000)
00763                         dest->ud.d0 = 0x80000000;
00764                 else {
00765                         Bit32s product0 = (Bit32s)dest->sw.w0 * (Bit32s)src.sw.w0;
00766                         Bit32s product1 = (Bit32s)dest->sw.w1 * (Bit32s)src.sw.w1;
00767                         dest->ud.d0 = (uint32_t)(product0 + product1);
00768                 }
00769                 if (dest->ud.d1 == 0x80008000 && src.ud.d1 == 0x80008000)
00770                         dest->ud.d1 = 0x80000000;
00771                 else {
00772                         Bit32s product2 = (Bit32s)dest->sw.w2 * (Bit32s)src.sw.w2;
00773                         Bit32s product3 = (Bit32s)dest->sw.w3 * (Bit32s)src.sw.w3;
00774                         dest->sd.d1 = (int32_t)(product2 + product3);
00775                 }
00776                 break;
00777         }
00778 
00779 /* Comparison */
00780         CASE_0F_MMX(0x74)                                                                                               /* PCMPEQB Pq,Qq */
00781         {
00782                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00783                 GetRM;
00784                 MMX_reg* dest=lookupRMregMM[rm];
00785                 MMX_reg src;
00786                 if (rm>=0xc0) {
00787                         src.q=reg_mmx[rm&7]->q;
00788                 } else {
00789                         GetEAa;
00790                         src.q = LoadMq(eaa);
00791                 }
00792                 dest->ub.b0 = dest->ub.b0==src.ub.b0?0xff:0;
00793                 dest->ub.b1 = dest->ub.b1==src.ub.b1?0xff:0;
00794                 dest->ub.b2 = dest->ub.b2==src.ub.b2?0xff:0;
00795                 dest->ub.b3 = dest->ub.b3==src.ub.b3?0xff:0;
00796                 dest->ub.b4 = dest->ub.b4==src.ub.b4?0xff:0;
00797                 dest->ub.b5 = dest->ub.b5==src.ub.b5?0xff:0;
00798                 dest->ub.b6 = dest->ub.b6==src.ub.b6?0xff:0;
00799                 dest->ub.b7 = dest->ub.b7==src.ub.b7?0xff:0;
00800                 break;
00801         }
00802         CASE_0F_MMX(0x75)                                                                                               /* PCMPEQW Pq,Qq */
00803         {
00804                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00805                 GetRM;
00806                 MMX_reg* dest=lookupRMregMM[rm];
00807                 MMX_reg src;
00808                 if (rm>=0xc0) {
00809                         src.q=reg_mmx[rm&7]->q;
00810                 } else {
00811                         GetEAa;
00812                         src.q = LoadMq(eaa);
00813                 }
00814                 dest->uw.w0 = dest->uw.w0==src.uw.w0?0xffff:0;
00815                 dest->uw.w1 = dest->uw.w1==src.uw.w1?0xffff:0;
00816                 dest->uw.w2 = dest->uw.w2==src.uw.w2?0xffff:0;
00817                 dest->uw.w3 = dest->uw.w3==src.uw.w3?0xffff:0;
00818                 break;
00819         }
00820         CASE_0F_MMX(0x76)                                                                                               /* PCMPEQD Pq,Qq */
00821         {
00822                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00823                 GetRM;
00824                 MMX_reg* dest=lookupRMregMM[rm];
00825                 MMX_reg src;
00826                 if (rm>=0xc0) {
00827                         src.q=reg_mmx[rm&7]->q;
00828                 } else {
00829                         GetEAa;
00830                         src.q = LoadMq(eaa);
00831                 }
00832                 dest->ud.d0 = dest->ud.d0==src.ud.d0?0xffffffff:0;
00833                 dest->ud.d1 = dest->ud.d1==src.ud.d1?0xffffffff:0;
00834                 break;
00835         }
00836         CASE_0F_MMX(0x64)                                                                                               /* PCMPGTB Pq,Qq */
00837         {
00838                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00839                 GetRM;
00840                 MMX_reg* dest=lookupRMregMM[rm];
00841                 MMX_reg src;
00842                 if (rm>=0xc0) {
00843                         src.q=reg_mmx[rm&7]->q;
00844                 } else {
00845                         GetEAa;
00846                         src.q = LoadMq(eaa);
00847                 }
00848                 dest->ub.b0 = dest->sb.b0>src.sb.b0?0xff:0;
00849                 dest->ub.b1 = dest->sb.b1>src.sb.b1?0xff:0;
00850                 dest->ub.b2 = dest->sb.b2>src.sb.b2?0xff:0;
00851                 dest->ub.b3 = dest->sb.b3>src.sb.b3?0xff:0;
00852                 dest->ub.b4 = dest->sb.b4>src.sb.b4?0xff:0;
00853                 dest->ub.b5 = dest->sb.b5>src.sb.b5?0xff:0;
00854                 dest->ub.b6 = dest->sb.b6>src.sb.b6?0xff:0;
00855                 dest->ub.b7 = dest->sb.b7>src.sb.b7?0xff:0;
00856                 break;
00857         }
00858         CASE_0F_MMX(0x65)                                                                                               /* PCMPGTW Pq,Qq */
00859         {
00860                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00861                 GetRM;
00862                 MMX_reg* dest=lookupRMregMM[rm];
00863                 MMX_reg src;
00864                 if (rm>=0xc0) {
00865                         src.q=reg_mmx[rm&7]->q;
00866                 } else {
00867                         GetEAa;
00868                         src.q = LoadMq(eaa);
00869                 }
00870                 dest->uw.w0 = dest->sw.w0>src.sw.w0?0xffff:0;
00871                 dest->uw.w1 = dest->sw.w1>src.sw.w1?0xffff:0;
00872                 dest->uw.w2 = dest->sw.w2>src.sw.w2?0xffff:0;
00873                 dest->uw.w3 = dest->sw.w3>src.sw.w3?0xffff:0;
00874                 break;
00875         }
00876         CASE_0F_MMX(0x66)                                                                                               /* PCMPGTD Pq,Qq */
00877         {
00878                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00879                 GetRM;
00880                 MMX_reg* dest=lookupRMregMM[rm];
00881                 MMX_reg src;
00882                 if (rm>=0xc0) {
00883                         src.q=reg_mmx[rm&7]->q;
00884                 } else {
00885                         GetEAa;
00886                         src.q = LoadMq(eaa);
00887                 }
00888                 dest->ud.d0 = dest->sd.d0>src.sd.d0?0xffffffff:0;
00889                 dest->ud.d1 = dest->sd.d1>src.sd.d1?0xffffffff:0;
00890                 break;
00891         }
00892 
00893 /* Data Packing */
00894         CASE_0F_MMX(0x63)                                                                                               /* PACKSSWB Pq,Qq */
00895         {
00896                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00897                 GetRM;
00898                 MMX_reg* dest=lookupRMregMM[rm];
00899                 MMX_reg src;
00900                 if (rm>=0xc0) {
00901                         src.q=reg_mmx[rm&7]->q;
00902                 } else {
00903                         GetEAa;
00904                         src.q = LoadMq(eaa);
00905                 }
00906                 dest->sb.b0 = SaturateWordSToByteS(dest->sw.w0);
00907                 dest->sb.b1 = SaturateWordSToByteS(dest->sw.w1);
00908                 dest->sb.b2 = SaturateWordSToByteS(dest->sw.w2);
00909                 dest->sb.b3 = SaturateWordSToByteS(dest->sw.w3);
00910                 dest->sb.b4 = SaturateWordSToByteS(src.sw.w0);
00911                 dest->sb.b5 = SaturateWordSToByteS(src.sw.w1);
00912                 dest->sb.b6 = SaturateWordSToByteS(src.sw.w2);
00913                 dest->sb.b7 = SaturateWordSToByteS(src.sw.w3);
00914                 break;
00915         }
00916         CASE_0F_MMX(0x6B)                                                                                               /* PACKSSDW Pq,Qq */
00917         {
00918                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00919                 GetRM;
00920                 MMX_reg* dest=lookupRMregMM[rm];
00921                 MMX_reg src;
00922                 if (rm>=0xc0) {
00923                         src.q=reg_mmx[rm&7]->q;
00924                 } else {
00925                         GetEAa;
00926                         src.q = LoadMq(eaa);
00927                 }
00928                 dest->sw.w0 = SaturateDwordSToWordS(dest->sd.d0);
00929                 dest->sw.w1 = SaturateDwordSToWordS(dest->sd.d1);
00930                 dest->sw.w2 = SaturateDwordSToWordS(src.sd.d0);
00931                 dest->sw.w3 = SaturateDwordSToWordS(src.sd.d1);
00932                 break;
00933         }
00934         CASE_0F_MMX(0x67)                                                                                               /* PACKUSWB Pq,Qq */
00935         {
00936                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00937                 GetRM;
00938                 MMX_reg* dest=lookupRMregMM[rm];
00939                 MMX_reg src;
00940                 if (rm>=0xc0) {
00941                         src.q=reg_mmx[rm&7]->q;
00942                 } else {
00943                         GetEAa;
00944                         src.q = LoadMq(eaa);
00945                 }
00946                 dest->ub.b0 = SaturateWordSToByteU(dest->sw.w0);
00947                 dest->ub.b1 = SaturateWordSToByteU(dest->sw.w1);
00948                 dest->ub.b2 = SaturateWordSToByteU(dest->sw.w2);
00949                 dest->ub.b3 = SaturateWordSToByteU(dest->sw.w3);
00950                 dest->ub.b4 = SaturateWordSToByteU(src.sw.w0);
00951                 dest->ub.b5 = SaturateWordSToByteU(src.sw.w1);
00952                 dest->ub.b6 = SaturateWordSToByteU(src.sw.w2);
00953                 dest->ub.b7 = SaturateWordSToByteU(src.sw.w3);
00954                 break;
00955         }
00956         CASE_0F_MMX(0x68)                                                                                               /* PUNPCKHBW Pq,Qq */
00957         {
00958                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00959                 GetRM;
00960                 MMX_reg* dest=lookupRMregMM[rm];
00961                 MMX_reg src;
00962                 if (rm>=0xc0) {
00963                         src.q=reg_mmx[rm&7]->q;
00964                 } else {
00965                         GetEAa;
00966                         src.q = LoadMq(eaa);
00967                 }
00968                 dest->ub.b0 = dest->ub.b4;
00969                 dest->ub.b1 = src.ub.b4;
00970                 dest->ub.b2 = dest->ub.b5;
00971                 dest->ub.b3 = src.ub.b5;
00972                 dest->ub.b4 = dest->ub.b6;
00973                 dest->ub.b5 = src.ub.b6;
00974                 dest->ub.b6 = dest->ub.b7;
00975                 dest->ub.b7 = src.ub.b7;
00976                 break;
00977         }
00978         CASE_0F_MMX(0x69)                                                                                               /* PUNPCKHWD Pq,Qq */
00979         {
00980                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00981                 GetRM;
00982                 MMX_reg* dest=lookupRMregMM[rm];
00983                 MMX_reg src;
00984                 if (rm>=0xc0) {
00985                         src.q=reg_mmx[rm&7]->q;
00986                 } else {
00987                         GetEAa;
00988                         src.q = LoadMq(eaa);
00989                 }
00990                 dest->uw.w0 = dest->uw.w2;
00991                 dest->uw.w1 = src.uw.w2;
00992                 dest->uw.w2 = dest->uw.w3;
00993                 dest->uw.w3 = src.uw.w3;
00994                 break;
00995         }
00996         CASE_0F_MMX(0x6A)                                                                                               /* PUNPCKHDQ Pq,Qq */
00997         {
00998                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
00999                 GetRM;
01000                 MMX_reg* dest=lookupRMregMM[rm];
01001                 MMX_reg src;
01002                 if (rm>=0xc0) {
01003                         src.q=reg_mmx[rm&7]->q;
01004                 } else {
01005                         GetEAa;
01006                         src.q = LoadMq(eaa);
01007                 }
01008                 dest->ud.d0 = dest->ud.d1;
01009                 dest->ud.d1 = src.ud.d1;
01010                 break;
01011         }
01012         CASE_0F_MMX(0x60)                                                                                               /* PUNPCKLBW Pq,Qq */
01013         {
01014                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
01015                 GetRM;
01016                 MMX_reg* dest=lookupRMregMM[rm];
01017                 MMX_reg src;
01018                 if (rm>=0xc0) {
01019                         src.q=reg_mmx[rm&7]->q;
01020                 } else {
01021                         GetEAa;
01022                         src.q = LoadMq(eaa);
01023                 }
01024                 dest->ub.b7 = src.ub.b3;
01025                 dest->ub.b6 = dest->ub.b3;
01026                 dest->ub.b5 = src.ub.b2;
01027                 dest->ub.b4 = dest->ub.b2;
01028                 dest->ub.b3 = src.ub.b1;
01029                 dest->ub.b2 = dest->ub.b1;
01030                 dest->ub.b1 = src.ub.b0;
01031                 break;
01032         }
01033         CASE_0F_MMX(0x61)                                                                                               /* PUNPCKLWD Pq,Qq */
01034         {
01035                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
01036                 GetRM;
01037                 MMX_reg* dest=lookupRMregMM[rm];
01038                 MMX_reg src;
01039                 if (rm>=0xc0) {
01040                         src.q=reg_mmx[rm&7]->q;
01041                 } else {
01042                         GetEAa;
01043                         src.q = LoadMq(eaa);
01044                 }
01045                 dest->uw.w3 = src.uw.w1;
01046                 dest->uw.w2 = dest->uw.w1;
01047                 dest->uw.w1 = src.uw.w0;
01048                 break;
01049         }
01050         CASE_0F_MMX(0x62)                                                                                               /* PUNPCKLDQ Pq,Qq */
01051         {
01052                 if (CPU_ArchitectureType<CPU_ARCHTYPE_PMMXSLOW) goto illegal_opcode;
01053                 GetRM;
01054                 MMX_reg* dest=lookupRMregMM[rm];
01055                 MMX_reg src;
01056                 if (rm>=0xc0) {
01057                         src.q=reg_mmx[rm&7]->q;
01058                 } else {
01059                         GetEAa;
01060                         src.q = LoadMq(eaa);
01061                 }
01062                 dest->ud.d1 = src.ud.d0;
01063                 break;
01064         }