DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* 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 }