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 /* Jumps */ 00020 00021 extern bool enable_fpu; 00022 00023 /* All Byte general instructions */ 00024 #define ADDB(op1,op2,load,save) \ 00025 lf_var1b=load(op1);lf_var2b=op2; \ 00026 lf_resb=lf_var1b+lf_var2b; \ 00027 save(op1,lf_resb); \ 00028 lflags.type=t_ADDb; 00029 00030 #define ADCB(op1,op2,load,save) \ 00031 lflags.oldcf=get_CF()!=0; \ 00032 lf_var1b=load(op1);lf_var2b=op2; \ 00033 lf_resb=(unsigned int)lf_var1b+(unsigned int)lf_var2b+(unsigned int)lflags.oldcf; \ 00034 save(op1,lf_resb); \ 00035 lflags.type=t_ADCb; 00036 00037 #define SBBB(op1,op2,load,save) \ 00038 lflags.oldcf=get_CF()!=0; \ 00039 lf_var1b=load(op1);lf_var2b=op2; \ 00040 lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \ 00041 save(op1,lf_resb); \ 00042 lflags.type=t_SBBb; 00043 00044 #define SUBB(op1,op2,load,save) \ 00045 lf_var1b=load(op1);lf_var2b=op2; \ 00046 lf_resb=lf_var1b-lf_var2b; \ 00047 save(op1,lf_resb); \ 00048 lflags.type=t_SUBb; 00049 00050 #define ORB(op1,op2,load,save) \ 00051 lf_var1b=load(op1);lf_var2b=op2; \ 00052 lf_resb=lf_var1b | lf_var2b; \ 00053 save(op1,lf_resb); \ 00054 lflags.type=t_ORb; 00055 00056 #define XORB(op1,op2,load,save) \ 00057 lf_var1b=load(op1);lf_var2b=op2; \ 00058 lf_resb=lf_var1b ^ lf_var2b; \ 00059 save(op1,lf_resb); \ 00060 lflags.type=t_XORb; 00061 00062 #define ANDB(op1,op2,load,save) \ 00063 lf_var1b=load(op1);lf_var2b=op2; \ 00064 lf_resb=lf_var1b & lf_var2b; \ 00065 save(op1,lf_resb); \ 00066 lflags.type=t_ANDb; 00067 00068 #define CMPB(op1,op2,load,save) \ 00069 lf_var1b=load(op1);lf_var2b=op2; \ 00070 lf_resb=lf_var1b-lf_var2b; \ 00071 lflags.type=t_CMPb; 00072 00073 #define TESTB(op1,op2,load,save) \ 00074 lf_var1b=load(op1);lf_var2b=op2; \ 00075 lf_resb=lf_var1b & lf_var2b; \ 00076 lflags.type=t_TESTb; 00077 00078 /* All Word General instructions */ 00079 00080 #define ADDW(op1,op2,load,save) \ 00081 lf_var1w=load(op1);lf_var2w=op2; \ 00082 lf_resw=lf_var1w+lf_var2w; \ 00083 save(op1,lf_resw); \ 00084 lflags.type=t_ADDw; 00085 00086 #define ADCW(op1,op2,load,save) \ 00087 lflags.oldcf=get_CF()!=0; \ 00088 lf_var1w=load(op1);lf_var2w=op2; \ 00089 lf_resw=(unsigned int)lf_var1w+(unsigned int)lf_var2w+(unsigned int)lflags.oldcf; \ 00090 save(op1,lf_resw); \ 00091 lflags.type=t_ADCw; 00092 00093 #define SBBW(op1,op2,load,save) \ 00094 lflags.oldcf=get_CF()!=0; \ 00095 lf_var1w=load(op1);lf_var2w=op2; \ 00096 lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \ 00097 save(op1,lf_resw); \ 00098 lflags.type=t_SBBw; 00099 00100 #define SUBW(op1,op2,load,save) \ 00101 lf_var1w=load(op1);lf_var2w=op2; \ 00102 lf_resw=lf_var1w-lf_var2w; \ 00103 save(op1,lf_resw); \ 00104 lflags.type=t_SUBw; 00105 00106 #define ORW(op1,op2,load,save) \ 00107 lf_var1w=load(op1);lf_var2w=op2; \ 00108 lf_resw=lf_var1w | lf_var2w; \ 00109 save(op1,lf_resw); \ 00110 lflags.type=t_ORw; 00111 00112 #define XORW(op1,op2,load,save) \ 00113 lf_var1w=load(op1);lf_var2w=op2; \ 00114 lf_resw=lf_var1w ^ lf_var2w; \ 00115 save(op1,lf_resw); \ 00116 lflags.type=t_XORw; 00117 00118 #define ANDW(op1,op2,load,save) \ 00119 lf_var1w=load(op1);lf_var2w=op2; \ 00120 lf_resw=lf_var1w & lf_var2w; \ 00121 save(op1,lf_resw); \ 00122 lflags.type=t_ANDw; 00123 00124 #define CMPW(op1,op2,load,save) \ 00125 lf_var1w=load(op1);lf_var2w=op2; \ 00126 lf_resw=lf_var1w-lf_var2w; \ 00127 lflags.type=t_CMPw; 00128 00129 #define TESTW(op1,op2,load,save) \ 00130 lf_var1w=load(op1);lf_var2w=op2; \ 00131 lf_resw=lf_var1w & lf_var2w; \ 00132 lflags.type=t_TESTw; 00133 00134 /* All DWORD General Instructions */ 00135 00136 #define ADDD(op1,op2,load,save) \ 00137 lf_var1d=load(op1);lf_var2d=op2; \ 00138 lf_resd=lf_var1d+lf_var2d; \ 00139 save(op1,lf_resd); \ 00140 lflags.type=t_ADDd; 00141 00142 #define ADCD(op1,op2,load,save) \ 00143 lflags.oldcf=get_CF()!=0; \ 00144 lf_var1d=load(op1);lf_var2d=op2; \ 00145 lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \ 00146 save(op1,lf_resd); \ 00147 lflags.type=t_ADCd; 00148 00149 #define SBBD(op1,op2,load,save) \ 00150 lflags.oldcf=get_CF()!=0; \ 00151 lf_var1d=load(op1);lf_var2d=op2; \ 00152 lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \ 00153 save(op1,lf_resd); \ 00154 lflags.type=t_SBBd; 00155 00156 #define SUBD(op1,op2,load,save) \ 00157 lf_var1d=load(op1);lf_var2d=op2; \ 00158 lf_resd=lf_var1d-lf_var2d; \ 00159 save(op1,lf_resd); \ 00160 lflags.type=t_SUBd; 00161 00162 #define ORD(op1,op2,load,save) \ 00163 lf_var1d=load(op1);lf_var2d=op2; \ 00164 lf_resd=lf_var1d | lf_var2d; \ 00165 save(op1,lf_resd); \ 00166 lflags.type=t_ORd; 00167 00168 #define XORD(op1,op2,load,save) \ 00169 lf_var1d=load(op1);lf_var2d=op2; \ 00170 lf_resd=lf_var1d ^ lf_var2d; \ 00171 save(op1,lf_resd); \ 00172 lflags.type=t_XORd; 00173 00174 #define ANDD(op1,op2,load,save) \ 00175 lf_var1d=load(op1);lf_var2d=op2; \ 00176 lf_resd=lf_var1d & lf_var2d; \ 00177 save(op1,lf_resd); \ 00178 lflags.type=t_ANDd; 00179 00180 #define CMPD(op1,op2,load,save) \ 00181 lf_var1d=load(op1);lf_var2d=op2; \ 00182 lf_resd=lf_var1d-lf_var2d; \ 00183 lflags.type=t_CMPd; 00184 00185 00186 #define TESTD(op1,op2,load,save) \ 00187 lf_var1d=load(op1);lf_var2d=op2; \ 00188 lf_resd=lf_var1d & lf_var2d; \ 00189 lflags.type=t_TESTd; 00190 00191 00192 00193 00194 #define INCB(op1,load,save) \ 00195 LoadCF;lf_var1b=load(op1); \ 00196 lf_resb=lf_var1b+1; \ 00197 save(op1,lf_resb); \ 00198 lflags.type=t_INCb; \ 00199 00200 #define INCW(op1,load,save) \ 00201 LoadCF;lf_var1w=load(op1); \ 00202 lf_resw=lf_var1w+1; \ 00203 save(op1,lf_resw); \ 00204 lflags.type=t_INCw; 00205 00206 #define INCD(op1,load,save) \ 00207 LoadCF;lf_var1d=load(op1); \ 00208 lf_resd=lf_var1d+1; \ 00209 save(op1,lf_resd); \ 00210 lflags.type=t_INCd; 00211 00212 #define DECB(op1,load,save) \ 00213 LoadCF;lf_var1b=load(op1); \ 00214 lf_resb=lf_var1b-1; \ 00215 save(op1,lf_resb); \ 00216 lflags.type=t_DECb; 00217 00218 #define DECW(op1,load,save) \ 00219 LoadCF;lf_var1w=load(op1); \ 00220 lf_resw=lf_var1w-1; \ 00221 save(op1,lf_resw); \ 00222 lflags.type=t_DECw; 00223 00224 #define DECD(op1,load,save) \ 00225 LoadCF;lf_var1d=load(op1); \ 00226 lf_resd=lf_var1d-1; \ 00227 save(op1,lf_resd); \ 00228 lflags.type=t_DECd; 00229 00230 00231 00232 #define ROLB(op1,op2,load,save) \ 00233 FillFlagsNoCFOF(); \ 00234 lf_var1b=load(op1); \ 00235 lf_var2b=op2&0x07; \ 00236 lf_resb=(lf_var1b << lf_var2b) | \ 00237 (lf_var1b >> (8-lf_var2b)); \ 00238 save(op1,lf_resb); \ 00239 SETFLAGBIT(CF,lf_resb & 1); \ 00240 SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); 00241 00242 #define ROLW(op1,op2,load,save) \ 00243 FillFlagsNoCFOF(); \ 00244 lf_var1w=load(op1); \ 00245 lf_var2b=op2&0xf; \ 00246 lf_resw=(lf_var1w << lf_var2b) | \ 00247 (lf_var1w >> (16-lf_var2b)); \ 00248 save(op1,lf_resw); \ 00249 SETFLAGBIT(CF,lf_resw & 1); \ 00250 SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); 00251 00252 #define ROLD(op1,op2,load,save) \ 00253 FillFlagsNoCFOF(); \ 00254 lf_var1d=load(op1); \ 00255 lf_var2b=op2; \ 00256 lf_resd=(lf_var1d << lf_var2b) | \ 00257 (lf_var1d >> (32-lf_var2b)); \ 00258 save(op1,lf_resd); \ 00259 SETFLAGBIT(CF,lf_resd & 1); \ 00260 SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); 00261 00262 00263 #define RORB(op1,op2,load,save) \ 00264 FillFlagsNoCFOF(); \ 00265 lf_var1b=load(op1); \ 00266 lf_var2b=op2&0x07; \ 00267 lf_resb=(lf_var1b >> lf_var2b) | \ 00268 (lf_var1b << (8-lf_var2b)); \ 00269 save(op1,lf_resb); \ 00270 SETFLAGBIT(CF,lf_resb & 0x80); \ 00271 SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); 00272 00273 #define RORW(op1,op2,load,save) \ 00274 FillFlagsNoCFOF(); \ 00275 lf_var1w=load(op1); \ 00276 lf_var2b=op2&0xf; \ 00277 lf_resw=(lf_var1w >> lf_var2b) | \ 00278 (lf_var1w << (16-lf_var2b)); \ 00279 save(op1,lf_resw); \ 00280 SETFLAGBIT(CF,lf_resw & 0x8000); \ 00281 SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); 00282 00283 #define RORD(op1,op2,load,save) \ 00284 FillFlagsNoCFOF(); \ 00285 lf_var1d=load(op1); \ 00286 lf_var2b=op2; \ 00287 lf_resd=(lf_var1d >> lf_var2b) | \ 00288 (lf_var1d << (32-lf_var2b)); \ 00289 save(op1,lf_resd); \ 00290 SETFLAGBIT(CF,lf_resd & 0x80000000); \ 00291 SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); 00292 00293 00294 #define RCLB(op1,op2,load,save) \ 00295 if (!(op2%9)) break; \ 00296 { Bit8u cf=(Bit8u)FillFlags()&0x1; \ 00297 lf_var1b=load(op1); \ 00298 lf_var2b=op2%9; \ 00299 lf_resb=(lf_var1b << lf_var2b) | \ 00300 (cf << (lf_var2b-1)) | \ 00301 (lf_var1b >> (9-lf_var2b)); \ 00302 save(op1,lf_resb); \ 00303 SETFLAGBIT(CF,(((unsigned int)lf_var1b >> (8u-lf_var2b)) & 1u)); \ 00304 SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resb >> 7u)); \ 00305 } 00306 00307 #define RCLW(op1,op2,load,save) \ 00308 if (!(op2%17)) break; \ 00309 { Bit16u cf=(Bit16u)FillFlags()&0x1; \ 00310 lf_var1w=load(op1); \ 00311 lf_var2b=op2%17; \ 00312 lf_resw=(lf_var1w << lf_var2b) | \ 00313 (cf << (lf_var2b-1)) | \ 00314 (lf_var1w >> (17-lf_var2b)); \ 00315 save(op1,lf_resw); \ 00316 SETFLAGBIT(CF,(((unsigned int)lf_var1w >> (16u-lf_var2b)) & 1u)); \ 00317 SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resw >> 15u)); \ 00318 } 00319 00320 #define RCLD(op1,op2,load,save) \ 00321 if (!op2) break; \ 00322 { Bit32u cf=(Bit32u)FillFlags()&0x1; \ 00323 lf_var1d=load(op1); \ 00324 lf_var2b=op2; \ 00325 if (lf_var2b==1) { \ 00326 lf_resd=(lf_var1d << 1) | cf; \ 00327 } else { \ 00328 lf_resd=(lf_var1d << lf_var2b) | \ 00329 (cf << (lf_var2b-1)) | \ 00330 (lf_var1d >> (33-lf_var2b)); \ 00331 } \ 00332 save(op1,lf_resd); \ 00333 SETFLAGBIT(CF,(((unsigned int)lf_var1d >> (32u-lf_var2b)) & 1u)); \ 00334 SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resd >> 31u)); \ 00335 } 00336 00337 #define RCRB(op1,op2,load,save) \ 00338 if (op2%9) { \ 00339 Bit8u cf=(Bit8u)FillFlags()&0x1; \ 00340 lf_var1b=load(op1); \ 00341 lf_var2b=op2%9; \ 00342 lf_resb=(lf_var1b >> lf_var2b) | \ 00343 (cf << (8-lf_var2b)) | \ 00344 (lf_var1b << (9-lf_var2b)); \ 00345 save(op1,lf_resb); \ 00346 SETFLAGBIT(CF,((unsigned int)lf_var1b >> (lf_var2b - 1u)) & 1u); \ 00347 SETFLAGBIT(OF,(lf_resb ^ ((unsigned int)lf_resb<<1u)) & 0x80u); \ 00348 } 00349 00350 #define RCRW(op1,op2,load,save) \ 00351 if (op2%17) { \ 00352 Bit16u cf=(Bit16u)FillFlags()&0x1; \ 00353 lf_var1w=load(op1); \ 00354 lf_var2b=op2%17; \ 00355 lf_resw=(lf_var1w >> lf_var2b) | \ 00356 (cf << (16-lf_var2b)) | \ 00357 (lf_var1w << (17-lf_var2b)); \ 00358 save(op1,lf_resw); \ 00359 SETFLAGBIT(CF,((unsigned int)lf_var1w >> (lf_var2b - 1u)) & 1u); \ 00360 SETFLAGBIT(OF,(lf_resw ^ ((unsigned int)lf_resw<<1u)) & 0x8000u); \ 00361 } 00362 00363 #define RCRD(op1,op2,load,save) \ 00364 if (op2) { \ 00365 Bit32u cf=(Bit32u)FillFlags()&0x1; \ 00366 lf_var1d=load(op1); \ 00367 lf_var2b=op2; \ 00368 if (lf_var2b==1) { \ 00369 lf_resd=lf_var1d >> 1 | cf << 31; \ 00370 } else { \ 00371 lf_resd=(lf_var1d >> lf_var2b) | \ 00372 (cf << (32-lf_var2b)) | \ 00373 (lf_var1d << (33-lf_var2b)); \ 00374 } \ 00375 save(op1,lf_resd); \ 00376 SETFLAGBIT(CF,((unsigned int)lf_var1d >> (lf_var2b - 1u)) & 1u); \ 00377 SETFLAGBIT(OF,(lf_resd ^ ((unsigned int)lf_resd<<1u)) & 0x80000000u); \ 00378 } 00379 00380 00381 #define SHLB(op1,op2,load,save) \ 00382 lf_var1b=load(op1);lf_var2b=op2; \ 00383 lf_resb=(lf_var2b < 8u) ? ((unsigned int)lf_var1b << lf_var2b) : 0; \ 00384 save(op1,lf_resb); \ 00385 lflags.type=t_SHLb; 00386 00387 #define SHLW(op1,op2,load,save) \ 00388 lf_var1w=load(op1);lf_var2b=op2 ; \ 00389 lf_resw=(lf_var2b < 16u) ? ((unsigned int)lf_var1w << lf_var2b) : 0; \ 00390 save(op1,lf_resw); \ 00391 lflags.type=t_SHLw; 00392 00393 #define SHLD(op1,op2,load,save) \ 00394 lf_var1d=load(op1);lf_var2b=op2; \ 00395 lf_resd=(lf_var2b < 32u) ? ((unsigned int)lf_var1d << lf_var2b) : 0; \ 00396 save(op1,lf_resd); \ 00397 lflags.type=t_SHLd; 00398 00399 00400 #define SHRB(op1,op2,load,save) \ 00401 lf_var1b=load(op1);lf_var2b=op2; \ 00402 lf_resb=(lf_var2b < 8u) ? ((unsigned int)lf_var1b >> lf_var2b) : 0; \ 00403 save(op1,lf_resb); \ 00404 lflags.type=t_SHRb; 00405 00406 #define SHRW(op1,op2,load,save) \ 00407 lf_var1w=load(op1);lf_var2b=op2; \ 00408 lf_resw=(lf_var2b < 16u) ? ((unsigned int)lf_var1w >> lf_var2b) : 0; \ 00409 save(op1,lf_resw); \ 00410 lflags.type=t_SHRw; 00411 00412 #define SHRD(op1,op2,load,save) \ 00413 lf_var1d=load(op1);lf_var2b=op2; \ 00414 lf_resd=(lf_var2b < 32u) ? ((unsigned int)lf_var1d >> lf_var2b) : 0; \ 00415 save(op1,lf_resd); \ 00416 lflags.type=t_SHRd; 00417 00418 00419 #define SARB(op1,op2,load,save) \ 00420 lf_var1b=load(op1);lf_var2b=op2; \ 00421 if (lf_var2b>8) lf_var2b=8; \ 00422 if (lf_var1b & 0x80) { \ 00423 lf_resb=(lf_var1b >> lf_var2b)| \ 00424 (0xff << (8 - lf_var2b)); \ 00425 } else { \ 00426 lf_resb=lf_var1b >> lf_var2b; \ 00427 } \ 00428 save(op1,lf_resb); \ 00429 lflags.type=t_SARb; 00430 00431 #define SARW(op1,op2,load,save) \ 00432 lf_var1w=load(op1);lf_var2b=op2; \ 00433 if (lf_var2b>16) lf_var2b=16; \ 00434 if (lf_var1w & 0x8000) { \ 00435 lf_resw=(lf_var1w >> lf_var2b)| \ 00436 (0xffff << (16 - lf_var2b)); \ 00437 } else { \ 00438 lf_resw=lf_var1w >> lf_var2b; \ 00439 } \ 00440 save(op1,lf_resw); \ 00441 lflags.type=t_SARw; 00442 00443 #define SARD(op1,op2,load,save) \ 00444 lf_var2b=op2;lf_var1d=load(op1); \ 00445 if (lf_var1d & 0x80000000) { \ 00446 lf_resd=(lf_var1d >> lf_var2b)| \ 00447 (0xffffffff << (32 - lf_var2b)); \ 00448 } else { \ 00449 lf_resd=lf_var1d >> lf_var2b; \ 00450 } \ 00451 save(op1,lf_resd); \ 00452 lflags.type=t_SARd; 00453 00454 00455 00456 #define DAA() \ 00457 if (((reg_al & 0x0F)>0x09) || get_AF()) { \ 00458 if ((reg_al > 0x99) || get_CF()) { \ 00459 reg_al+=0x60; \ 00460 SETFLAGBIT(CF,true); \ 00461 } else { \ 00462 SETFLAGBIT(CF,false); \ 00463 } \ 00464 reg_al+=0x06; \ 00465 SETFLAGBIT(AF,true); \ 00466 } else { \ 00467 if ((reg_al > 0x99) || get_CF()) { \ 00468 reg_al+=0x60; \ 00469 SETFLAGBIT(CF,true); \ 00470 } else { \ 00471 SETFLAGBIT(CF,false); \ 00472 } \ 00473 SETFLAGBIT(AF,false); \ 00474 } \ 00475 SETFLAGBIT(SF,(reg_al&0x80)); \ 00476 SETFLAGBIT(ZF,(reg_al==0)); \ 00477 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00478 lflags.type=t_UNKNOWN; 00479 00480 00481 #define DAS() \ 00482 { \ 00483 Bit8u osigned=reg_al & 0x80; \ 00484 if (((reg_al & 0x0f) > 9) || get_AF()) { \ 00485 if ((reg_al>0x99) || get_CF()) { \ 00486 reg_al-=0x60; \ 00487 SETFLAGBIT(CF,true); \ 00488 } else { \ 00489 SETFLAGBIT(CF,(reg_al<=0x05)); \ 00490 } \ 00491 reg_al-=6; \ 00492 SETFLAGBIT(AF,true); \ 00493 } else { \ 00494 if ((reg_al>0x99) || get_CF()) { \ 00495 reg_al-=0x60; \ 00496 SETFLAGBIT(CF,true); \ 00497 } else { \ 00498 SETFLAGBIT(CF,false); \ 00499 } \ 00500 SETFLAGBIT(AF,false); \ 00501 } \ 00502 SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0)); \ 00503 SETFLAGBIT(SF,(reg_al&0x80)); \ 00504 SETFLAGBIT(ZF,(reg_al==0)); \ 00505 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00506 lflags.type=t_UNKNOWN; \ 00507 } 00508 00509 00510 #define AAA() \ 00511 SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9))); \ 00512 if ((reg_al & 0xf) > 9) { \ 00513 SETFLAGBIT(OF,(reg_al&0xf0)==0x70); \ 00514 reg_ax += 0x106; \ 00515 SETFLAGBIT(CF,true); \ 00516 SETFLAGBIT(ZF,(reg_al == 0)); \ 00517 SETFLAGBIT(AF,true); \ 00518 } else if (get_AF()) { \ 00519 reg_ax += 0x106; \ 00520 SETFLAGBIT(OF,false); \ 00521 SETFLAGBIT(CF,true); \ 00522 SETFLAGBIT(ZF,false); \ 00523 SETFLAGBIT(AF,true); \ 00524 } else { \ 00525 SETFLAGBIT(OF,false); \ 00526 SETFLAGBIT(CF,false); \ 00527 SETFLAGBIT(ZF,(reg_al == 0)); \ 00528 SETFLAGBIT(AF,false); \ 00529 } \ 00530 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00531 reg_al &= 0x0F; \ 00532 lflags.type=t_UNKNOWN; 00533 00534 #define AAS() \ 00535 if ((reg_al & 0x0f)>9) { \ 00536 SETFLAGBIT(SF,(reg_al>0x85)); \ 00537 reg_ax -= 0x106; \ 00538 SETFLAGBIT(OF,false); \ 00539 SETFLAGBIT(CF,true); \ 00540 SETFLAGBIT(AF,true); \ 00541 } else if (get_AF()) { \ 00542 SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85))); \ 00543 SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85)); \ 00544 reg_ax -= 0x106; \ 00545 SETFLAGBIT(CF,true); \ 00546 SETFLAGBIT(AF,true); \ 00547 } else { \ 00548 SETFLAGBIT(SF,(reg_al>=0x80)); \ 00549 SETFLAGBIT(OF,false); \ 00550 SETFLAGBIT(CF,false); \ 00551 SETFLAGBIT(AF,false); \ 00552 } \ 00553 SETFLAGBIT(ZF,(reg_al == 0)); \ 00554 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00555 reg_al &= 0x0F; \ 00556 lflags.type=t_UNKNOWN; 00557 00558 #define AAM(op1) \ 00559 { \ 00560 Bit8u dv=op1; \ 00561 if (dv!=0) { \ 00562 reg_ah=reg_al / dv; \ 00563 reg_al=reg_al % dv; \ 00564 SETFLAGBIT(SF,(reg_al & 0x80)); \ 00565 SETFLAGBIT(ZF,(reg_al == 0)); \ 00566 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00567 SETFLAGBIT(CF,false); \ 00568 SETFLAGBIT(OF,false); \ 00569 SETFLAGBIT(AF,false); \ 00570 lflags.type=t_UNKNOWN; \ 00571 } else EXCEPTION(0); \ 00572 } 00573 00574 00575 //Took this from bochs, i seriously hate these weird bcd opcodes 00576 #define AAD(op1) \ 00577 { \ 00578 Bit16u ax1 = reg_ah * op1; \ 00579 Bit16u ax2 = ax1 + reg_al; \ 00580 reg_al = (Bit8u) ax2; \ 00581 reg_ah = 0; \ 00582 SETFLAGBIT(CF,false); \ 00583 SETFLAGBIT(OF,false); \ 00584 SETFLAGBIT(AF,false); \ 00585 SETFLAGBIT(SF,reg_al >= 0x80); \ 00586 SETFLAGBIT(ZF,reg_al == 0); \ 00587 SETFLAGBIT(PF,parity_lookup[reg_al]); \ 00588 lflags.type=t_UNKNOWN; \ 00589 } 00590 00591 #define PARITY16(x) (parity_lookup[((unsigned int)((Bit16u)(x))>>8u)&0xffu]^parity_lookup[((Bit8u)(x))&0xffu]^FLAG_PF) 00592 #define PARITY32(x) (PARITY16(((Bit16u)(x))&0xffffu)^PARITY16(((unsigned int)((Bit32u)(x))>>16u)&0xffffu)^FLAG_PF) 00593 00594 #define MULB(op1,load,save) \ 00595 reg_ax=reg_al*load(op1); \ 00596 FillFlagsNoCFOF(); \ 00597 SETFLAGBIT(ZF,reg_al == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \ 00598 SETFLAGBIT(PF,PARITY16(reg_ax)); \ 00599 if (reg_ax & 0xff00) { \ 00600 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00601 } else { \ 00602 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00603 } 00604 00605 #define MULW(op1,load,save) \ 00606 { \ 00607 Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ 00608 reg_ax=(Bit16u)(tempu); \ 00609 reg_dx=(Bit16u)(tempu >> 16); \ 00610 FillFlagsNoCFOF(); \ 00611 SETFLAGBIT(ZF,reg_ax == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \ 00612 SETFLAGBIT(PF,PARITY16(reg_ax)^PARITY16(reg_dx)^FLAG_PF); \ 00613 if (reg_dx) { \ 00614 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00615 } else { \ 00616 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00617 } \ 00618 } 00619 00620 #define MULD(op1,load,save) \ 00621 { \ 00622 Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ 00623 reg_eax=(Bit32u)(tempu); \ 00624 reg_edx=(Bit32u)(tempu >> 32); \ 00625 FillFlagsNoCFOF(); \ 00626 SETFLAGBIT(ZF,reg_eax == 0 && CPU_CORE >= CPU_ARCHTYPE_286); \ 00627 SETFLAGBIT(PF,PARITY32(reg_eax)^PARITY32(reg_edx)^FLAG_PF); \ 00628 if (reg_edx) { \ 00629 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00630 } else { \ 00631 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00632 } \ 00633 } 00634 00635 #define DIVB(op1,load,save) \ 00636 { \ 00637 Bitu val=load(op1); \ 00638 if (val==0) EXCEPTION(0); \ 00639 Bitu quo=reg_ax / val; \ 00640 Bit8u rem=(Bit8u)(reg_ax % val); \ 00641 Bit8u quo8=(Bit8u)(quo&0xff); \ 00642 if (quo>0xff) EXCEPTION(0); \ 00643 reg_ah=rem; \ 00644 reg_al=quo8; \ 00645 FillFlags(); \ 00646 SETFLAGBIT(AF,0);/*FIXME*/ \ 00647 SETFLAGBIT(SF,0);/*FIXME*/ \ 00648 SETFLAGBIT(OF,0);/*FIXME*/ \ 00649 SETFLAGBIT(ZF,(rem==0)&&((quo8&1)!=0)); \ 00650 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00651 SETFLAGBIT(PF,parity_lookup[rem&0xff]^parity_lookup[quo8&0xff]^FLAG_PF); \ 00652 } 00653 00654 00655 #define DIVW(op1,load,save) \ 00656 { \ 00657 Bitu val=load(op1); \ 00658 if (val==0) EXCEPTION(0); \ 00659 Bitu num=((Bit32u)reg_dx<<16)|reg_ax; \ 00660 Bitu quo=num/val; \ 00661 Bit16u rem=(Bit16u)(num % val); \ 00662 Bit16u quo16=(Bit16u)(quo&0xffff); \ 00663 if (quo!=(Bit32u)quo16) EXCEPTION(0); \ 00664 reg_dx=rem; \ 00665 reg_ax=quo16; \ 00666 FillFlags(); \ 00667 SETFLAGBIT(AF,0);/*FIXME*/ \ 00668 SETFLAGBIT(SF,0);/*FIXME*/ \ 00669 SETFLAGBIT(OF,0);/*FIXME*/ \ 00670 SETFLAGBIT(ZF,(rem==0)&&((quo16&1)!=0)); \ 00671 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00672 SETFLAGBIT(PF,PARITY16(rem&0xffff)^PARITY16(quo16&0xffff)^FLAG_PF); \ 00673 } 00674 00675 #define DIVD(op1,load,save) \ 00676 { \ 00677 Bitu val=load(op1); \ 00678 if (val==0) EXCEPTION(0); \ 00679 Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ 00680 Bit64u quo=num/val; \ 00681 Bit32u rem=(Bit32u)(num % val); \ 00682 Bit32u quo32=(Bit32u)(quo&0xffffffff); \ 00683 if (quo!=(Bit64u)quo32) EXCEPTION(0); \ 00684 reg_edx=rem; \ 00685 reg_eax=quo32; \ 00686 FillFlags(); \ 00687 SETFLAGBIT(AF,0);/*FIXME*/ \ 00688 SETFLAGBIT(SF,0);/*FIXME*/ \ 00689 SETFLAGBIT(OF,0);/*FIXME*/ \ 00690 SETFLAGBIT(ZF,(rem==0)&&((quo32&1)!=0)); \ 00691 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00692 SETFLAGBIT(PF,PARITY32(rem&0xffffffff)^PARITY32(quo32&0xffffffff)^FLAG_PF); \ 00693 } 00694 00695 00696 #define IDIVB(op1,load,save) \ 00697 { \ 00698 Bits val=(Bit8s)(load(op1)); \ 00699 if (val==0) EXCEPTION(0); \ 00700 Bits quo=((Bit16s)reg_ax) / val; \ 00701 Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); \ 00702 Bit8s quo8s=(Bit8s)(quo&0xff); \ 00703 if (quo!=(Bit16s)quo8s) EXCEPTION(0); \ 00704 reg_ah=(Bit8u)rem; \ 00705 reg_al=(Bit8u)quo8s; \ 00706 FillFlags(); \ 00707 SETFLAGBIT(AF,0);/*FIXME*/ \ 00708 SETFLAGBIT(SF,0);/*FIXME*/ \ 00709 SETFLAGBIT(OF,0);/*FIXME*/ \ 00710 SETFLAGBIT(ZF,(rem==0)&&((quo8s&1)!=0)); \ 00711 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00712 SETFLAGBIT(PF,parity_lookup[rem&0xff]^parity_lookup[quo8s&0xff]^FLAG_PF); \ 00713 } 00714 00715 00716 #define IDIVW(op1,load,save) \ 00717 { \ 00718 Bits val=(Bit16s)(load(op1)); \ 00719 if (val==0) EXCEPTION(0); \ 00720 Bits num=(Bit32s)(((unsigned int)reg_dx<<16u)|(unsigned int)reg_ax); \ 00721 Bits quo=num/val; \ 00722 Bit16s rem=(Bit16s)(num % val); \ 00723 Bit16s quo16s=(Bit16s)quo; \ 00724 if (quo!=(Bit32s)quo16s) EXCEPTION(0); \ 00725 reg_dx=(Bit16u)rem; \ 00726 reg_ax=(Bit16u)quo16s; \ 00727 FillFlags(); \ 00728 SETFLAGBIT(AF,0);/*FIXME*/ \ 00729 SETFLAGBIT(SF,0);/*FIXME*/ \ 00730 SETFLAGBIT(OF,0);/*FIXME*/ \ 00731 SETFLAGBIT(ZF,(rem==0)&&((quo16s&1)!=0)); \ 00732 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00733 SETFLAGBIT(PF,PARITY16(rem&0xffff)^PARITY16(quo16s&0xffff)^FLAG_PF); \ 00734 } 00735 00736 #define IDIVD(op1,load,save) \ 00737 { \ 00738 Bits val=(Bit32s)(load(op1)); \ 00739 if (val==0) EXCEPTION(0); \ 00740 Bit64s num=(Bit64s)((((Bit64u)reg_edx)<<(Bit64u)32)|(Bit64u)reg_eax); \ 00741 Bit64s quo=num/val; \ 00742 Bit32s rem=(Bit32s)(num % val); \ 00743 Bit32s quo32s=(Bit32s)(quo&0xffffffff); \ 00744 if (quo!=(Bit64s)quo32s) EXCEPTION(0); \ 00745 reg_edx=(Bit32u)rem; \ 00746 reg_eax=(Bit32u)quo32s; \ 00747 FillFlags(); \ 00748 SETFLAGBIT(AF,0);/*FIXME*/ \ 00749 SETFLAGBIT(SF,0);/*FIXME*/ \ 00750 SETFLAGBIT(OF,0);/*FIXME*/ \ 00751 SETFLAGBIT(ZF,(rem==0)&&((quo32s&1)!=0)); \ 00752 SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \ 00753 SETFLAGBIT(PF,PARITY32((Bit32u)rem&0xffffffffu)^PARITY32((Bit32u)quo32s&0xffffffffu)^FLAG_PF); \ 00754 } 00755 00756 #define IMULB(op1,load,save) \ 00757 { \ 00758 reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ 00759 FillFlagsNoCFOF(); \ 00760 SETFLAGBIT(ZF,reg_al == 0); \ 00761 SETFLAGBIT(SF,reg_al & 0x80); \ 00762 if ((reg_ax & 0xff80)==0xff80 || \ 00763 (reg_ax & 0xff80)==0x0000) { \ 00764 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00765 } else { \ 00766 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00767 } \ 00768 } 00769 00770 00771 #define IMULW(op1,load,save) \ 00772 { \ 00773 Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ 00774 reg_ax=(Bit16u)(temps); \ 00775 reg_dx=(Bit16u)(temps >> 16); \ 00776 FillFlagsNoCFOF(); \ 00777 SETFLAGBIT(ZF,reg_ax == 0); \ 00778 SETFLAGBIT(SF,reg_ax & 0x8000); \ 00779 if ((((unsigned int)temps & 0xffff8000)==0xffff8000 || \ 00780 ((unsigned int)temps & 0xffff8000)==0x0000)) { \ 00781 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00782 } else { \ 00783 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00784 } \ 00785 } 00786 00787 #define IMULD(op1,load,save) \ 00788 { \ 00789 Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ 00790 ((Bit64s)((Bit32s)(load(op1)))); \ 00791 reg_eax=(Bit32u)(temps); \ 00792 reg_edx=(Bit32u)(temps >> 32); \ 00793 FillFlagsNoCFOF(); \ 00794 SETFLAGBIT(ZF,reg_eax == 0); \ 00795 SETFLAGBIT(SF,reg_eax & 0x80000000); \ 00796 if ((reg_edx==0xffffffff) && \ 00797 (reg_eax & 0x80000000) ) { \ 00798 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00799 } else if ( (reg_edx==0x00000000) && \ 00800 (reg_eax< 0x80000000) ) { \ 00801 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00802 } else { \ 00803 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00804 } \ 00805 } 00806 00807 #define DIMULW(op1,op2,op3,load,save) \ 00808 { \ 00809 Bits res=((Bit16s)op2) * ((Bit16s)op3); \ 00810 save(op1,res & 0xffff); \ 00811 FillFlagsNoCFOF(); \ 00812 if ((res>= -32768) && (res<=32767)) { \ 00813 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00814 } else { \ 00815 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00816 } \ 00817 } 00818 00819 #define DIMULD(op1,op2,op3,load,save) \ 00820 { \ 00821 Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ 00822 save(op1,(Bit32s)res); \ 00823 FillFlagsNoCFOF(); \ 00824 if ((res>=-((Bit64s)(2147483647)+1)) && \ 00825 (res<=(Bit64s)2147483647)) { \ 00826 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ 00827 } else { \ 00828 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ 00829 } \ 00830 } 00831 00832 #if CPU_CORE == CPU_ARCHTYPE_8086 00833 # define CPU_SHIFTOP_MASK(x,m) ((x) & 0xff) 00834 #else 00835 # define CPU_SHIFTOP_MASK(x,m) ((x) & 0x1f) 00836 #endif 00837 00838 /* FIXME: For 8086 core we care mostly about whether or not SHL/SHR emulate the non-masked shift count. 00839 * Note that running this code compiled for Intel processors naturally imposes the shift count, 00840 * compilers generate a shift instruction and do not consider the CPU masking the bit count. 00841 * 00842 * unsigned int a = 0x12345678,b = 0x20,c; 00843 * c = a << b; <-- on Intel x86 builds, c == a because GCC will compile to shl eax,cl and Intel processors will act like c == a << (b&0x1F). 00844 * 00845 * What we care about is that shift counts greater than or equal to the width of the target register come out to zero, 00846 * or for SAR, that all bits become copies of the sign bit. When emulating the 8086 we want DOS programs to be able to 00847 * test that we are an 8086 by executing shl ax,cl with cl == 32 and to get AX == 0 as a result instead of AX unchanged. 00848 * the shift count mask test is one of the several tests DOS programs may do to differentiate 8086 from 80186. */ 00849 #define GRP2B(blah) \ 00850 { \ 00851 GetRM;Bitu which=(rm>>3)&7; \ 00852 if (rm >= 0xc0) { \ 00853 GetEArb; \ 00854 Bit8u val=CPU_SHIFTOP_MASK(blah,7); \ 00855 if (!val) break; \ 00856 switch (which) { \ 00857 case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \ 00858 case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ 00859 case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break; \ 00860 case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break; \ 00861 case 0x04:/* SHL and SAL are the same */ \ 00862 case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break; \ 00863 case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break; \ 00864 case 0x07:SARB(*earb,val,LoadRb,SaveRb);break; \ 00865 } \ 00866 } else { \ 00867 GetEAa; \ 00868 Bit8u val=CPU_SHIFTOP_MASK(blah,7); \ 00869 if (!val) break; \ 00870 switch (which) { \ 00871 case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \ 00872 case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ 00873 case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break; \ 00874 case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break; \ 00875 case 0x04:/* SHL and SAL are the same */ \ 00876 case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break; \ 00877 case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break; \ 00878 case 0x07:SARB(eaa,val,LoadMb,SaveMb);break; \ 00879 } \ 00880 } \ 00881 } 00882 00883 00884 00885 #define GRP2W(blah) \ 00886 { \ 00887 GetRM;Bitu which=(rm>>3)&7; \ 00888 if (rm >= 0xc0) { \ 00889 GetEArw; \ 00890 Bit8u val=CPU_SHIFTOP_MASK(blah,15); \ 00891 if (!val) break; \ 00892 switch (which) { \ 00893 case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \ 00894 case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ 00895 case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break; \ 00896 case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break; \ 00897 case 0x04:/* SHL and SAL are the same */ \ 00898 case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break; \ 00899 case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break; \ 00900 case 0x07:SARW(*earw,val,LoadRw,SaveRw);break; \ 00901 } \ 00902 } else { \ 00903 GetEAa; \ 00904 Bit8u val=CPU_SHIFTOP_MASK(blah,15); \ 00905 if (!val) break; \ 00906 switch (which) { \ 00907 case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \ 00908 case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ 00909 case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break; \ 00910 case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break; \ 00911 case 0x04:/* SHL and SAL are the same */ \ 00912 case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break; \ 00913 case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break; \ 00914 case 0x07:SARW(eaa,val,LoadMw,SaveMw);break; \ 00915 } \ 00916 } \ 00917 } 00918 00919 00920 #define GRP2D(blah) \ 00921 { \ 00922 GetRM;Bitu which=(rm>>3)&7; \ 00923 if (rm >= 0xc0) { \ 00924 GetEArd; \ 00925 Bit8u val=CPU_SHIFTOP_MASK(blah,31); \ 00926 if (!val) break; \ 00927 switch (which) { \ 00928 case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \ 00929 case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ 00930 case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break; \ 00931 case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break; \ 00932 case 0x04:/* SHL and SAL are the same */ \ 00933 case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break; \ 00934 case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break; \ 00935 case 0x07:SARD(*eard,val,LoadRd,SaveRd);break; \ 00936 } \ 00937 } else { \ 00938 GetEAa; \ 00939 Bit8u val=CPU_SHIFTOP_MASK(blah,31); \ 00940 if (!val) break; \ 00941 switch (which) { \ 00942 case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \ 00943 case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \ 00944 case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break; \ 00945 case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break; \ 00946 case 0x04:/* SHL and SAL are the same */ \ 00947 case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break; \ 00948 case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break; \ 00949 case 0x07:SARD(eaa,val,LoadMd,SaveMd);break; \ 00950 } \ 00951 } \ 00952 } 00953 00954 /* let's hope bochs has it correct with the higher than 16 shifts */ 00955 /* double-precision shift left has low bits in second argument */ 00956 #define DSHLW(op1,op2,op3,load,save) \ 00957 Bit8u val=op3 & 0x1Fu; \ 00958 if (!val) break; \ 00959 lf_var2b=val;lf_var1d=((unsigned int)load(op1)<<16u)|op2; \ 00960 Bit32u tempd=lf_var1d << lf_var2b; \ 00961 if (lf_var2b>16u) tempd |= ((unsigned int)op2 << (lf_var2b - 16u)); \ 00962 lf_resw=(Bit16u)((unsigned int)tempd >> 16u); \ 00963 save(op1,lf_resw); \ 00964 lflags.type=t_DSHLw; 00965 00966 #define DSHLD(op1,op2,op3,load,save) \ 00967 Bit8u val=op3 & 0x1Fu; \ 00968 if (!val) break; \ 00969 lf_var2b=val;lf_var1d=load(op1); \ 00970 lf_resd=((unsigned int)lf_var1d << lf_var2b) | ((unsigned int)op2 >> (32u-lf_var2b)); \ 00971 save(op1,lf_resd); \ 00972 lflags.type=t_DSHLd; 00973 00974 /* double-precision shift right has high bits in second argument */ 00975 #define DSHRW(op1,op2,op3,load,save) \ 00976 Bit8u val=op3 & 0x1Fu; \ 00977 if (!val) break; \ 00978 lf_var2b=val;lf_var1d=((unsigned int)op2<<16u)|load(op1); \ 00979 Bit32u tempd=(unsigned int)lf_var1d >> lf_var2b; \ 00980 if (lf_var2b>16u) tempd |= ((unsigned int)op2 << (32u-lf_var2b)); \ 00981 lf_resw=(Bit16u)(tempd); \ 00982 save(op1,lf_resw); \ 00983 lflags.type=t_DSHRw; 00984 00985 #define DSHRD(op1,op2,op3,load,save) \ 00986 Bit8u val=op3 & 0x1Fu; \ 00987 if (!val) break; \ 00988 lf_var2b=val;lf_var1d=load(op1); \ 00989 lf_resd=((unsigned int)lf_var1d >> lf_var2b) | ((unsigned int)op2 << (32u-lf_var2b)); \ 00990 save(op1,lf_resd); \ 00991 lflags.type=t_DSHRd; 00992 00993 #define BSWAPW(op1) \ 00994 op1 = 0; 00995 00996 #define BSWAPD(op1) \ 00997 op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);