DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/instructions.h
00001 /*
00002  *  Copyright (C) 2002-2013  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
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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         if (!(op2&0x7)) {                                                               \
00234                 if (op2&0x18) {                                                         \
00235                         FillFlagsNoCFOF();                                              \
00236                         SETFLAGBIT(CF,op1 & 1);                                 \
00237                         SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7));  \
00238                 }                                                                                       \
00239                 break;                                                                          \
00240         }                                                                                               \
00241         FillFlagsNoCFOF();                                                              \
00242         lf_var1b=load(op1);                                                             \
00243         lf_var2b=op2&0x07;                                                              \
00244         lf_resb=(lf_var1b << lf_var2b) |                                \
00245                         (lf_var1b >> (8-lf_var2b));                             \
00246         save(op1,lf_resb);                                                              \
00247         SETFLAGBIT(CF,lf_resb & 1);                                             \
00248         SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7));
00249 
00250 #define ROLW(op1,op2,load,save)                                         \
00251         if (!(op2&0xf)) {                                                               \
00252                 if (op2&0x10) {                                                         \
00253                         FillFlagsNoCFOF();                                              \
00254                         SETFLAGBIT(CF,op1 & 1);                                 \
00255                         SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \
00256                 }                                                                                       \
00257                 break;                                                                          \
00258         }                                                                                               \
00259         FillFlagsNoCFOF();                                                              \
00260         lf_var1w=load(op1);                                                             \
00261         lf_var2b=op2&0xf;                                                               \
00262         lf_resw=(lf_var1w << lf_var2b) |                                \
00263                         (lf_var1w >> (16-lf_var2b));                    \
00264         save(op1,lf_resw);                                                              \
00265         SETFLAGBIT(CF,lf_resw & 1);                                             \
00266         SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15));
00267 
00268 #define ROLD(op1,op2,load,save)                                         \
00269         if (!op2) break;                                                                \
00270         FillFlagsNoCFOF();                                                              \
00271         lf_var1d=load(op1);                                                             \
00272         lf_var2b=op2;                                                                   \
00273         lf_resd=(lf_var1d << lf_var2b) |                                \
00274                         (lf_var1d >> (32-lf_var2b));                    \
00275         save(op1,lf_resd);                                                              \
00276         SETFLAGBIT(CF,lf_resd & 1);                                             \
00277         SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31));
00278 
00279 
00280 #define RORB(op1,op2,load,save)                                         \
00281         if (!(op2&0x7)) {                                                               \
00282                 if (op2&0x18) {                                                         \
00283                         FillFlagsNoCFOF();                                              \
00284                         SETFLAGBIT(CF,op1>>7);                                  \
00285                         SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1));                       \
00286                 }                                                                                       \
00287                 break;                                                                          \
00288         }                                                                                               \
00289         FillFlagsNoCFOF();                                                              \
00290         lf_var1b=load(op1);                                                             \
00291         lf_var2b=op2&0x07;                                                              \
00292         lf_resb=(lf_var1b >> lf_var2b) |                                \
00293                         (lf_var1b << (8-lf_var2b));                             \
00294         save(op1,lf_resb);                                                              \
00295         SETFLAGBIT(CF,lf_resb & 0x80);                                  \
00296         SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80);
00297 
00298 #define RORW(op1,op2,load,save)                                 \
00299         if (!(op2&0xf)) {                                                       \
00300                 if (op2&0x10) {                                                 \
00301                         FillFlagsNoCFOF();                                      \
00302                         SETFLAGBIT(CF,op1>>15);                         \
00303                         SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1));                     \
00304                 }                                                                               \
00305                 break;                                                                  \
00306         }                                                                                       \
00307         FillFlagsNoCFOF();                                                      \
00308         lf_var1w=load(op1);                                                     \
00309         lf_var2b=op2&0xf;                                                       \
00310         lf_resw=(lf_var1w >> lf_var2b) |                        \
00311                         (lf_var1w << (16-lf_var2b));            \
00312         save(op1,lf_resw);                                                      \
00313         SETFLAGBIT(CF,lf_resw & 0x8000);                        \
00314         SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000);
00315 
00316 #define RORD(op1,op2,load,save)                                 \
00317         if (!op2) break;                                                        \
00318         FillFlagsNoCFOF();                                                      \
00319         lf_var1d=load(op1);                                                     \
00320         lf_var2b=op2;                                                           \
00321         lf_resd=(lf_var1d >> lf_var2b) |                        \
00322                         (lf_var1d << (32-lf_var2b));            \
00323         save(op1,lf_resd);                                                      \
00324         SETFLAGBIT(CF,lf_resd & 0x80000000);            \
00325         SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000);
00326 
00327 
00328 #define RCLB(op1,op2,load,save)                                                 \
00329         if (!(op2%9)) break;                                                            \
00330 {       Bit8u cf=(Bit8u)FillFlags()&0x1;                                        \
00331         lf_var1b=load(op1);                                                                     \
00332         lf_var2b=op2%9;                                                                         \
00333         lf_resb=(lf_var1b << lf_var2b) |                                        \
00334                         (cf << (lf_var2b-1)) |                                          \
00335                         (lf_var1b >> (9-lf_var2b));                                     \
00336         save(op1,lf_resb);                                                                      \
00337         SETFLAGBIT(CF,(((unsigned int)lf_var1b >> (8u-lf_var2b)) & 1u));        \
00338         SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resb >> 7u));        \
00339 }
00340 
00341 #define RCLW(op1,op2,load,save)                                                 \
00342         if (!(op2%17)) break;                                                           \
00343 {       Bit16u cf=(Bit16u)FillFlags()&0x1;                                      \
00344         lf_var1w=load(op1);                                                                     \
00345         lf_var2b=op2%17;                                                                        \
00346         lf_resw=(lf_var1w << lf_var2b) |                                        \
00347                         (cf << (lf_var2b-1)) |                                          \
00348                         (lf_var1w >> (17-lf_var2b));                            \
00349         save(op1,lf_resw);                                                                      \
00350         SETFLAGBIT(CF,(((unsigned int)lf_var1w >> (16u-lf_var2b)) & 1u));       \
00351         SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resw >> 15u));       \
00352 }
00353 
00354 #define RCLD(op1,op2,load,save)                                                 \
00355         if (!op2) break;                                                                        \
00356 {       Bit32u cf=(Bit32u)FillFlags()&0x1;                                      \
00357         lf_var1d=load(op1);                                                                     \
00358         lf_var2b=op2;                                                                           \
00359         if (lf_var2b==1)        {                                                               \
00360                 lf_resd=(lf_var1d << 1) | cf;                                   \
00361         } else  {                                                                                       \
00362                 lf_resd=(lf_var1d << lf_var2b) |                                \
00363                 (cf << (lf_var2b-1)) |                                                  \
00364                 (lf_var1d >> (33-lf_var2b));                                    \
00365         }                                                                                                       \
00366         save(op1,lf_resd);                                                                      \
00367         SETFLAGBIT(CF,(((unsigned int)lf_var1d >> (32u-lf_var2b)) & 1u));       \
00368         SETFLAGBIT(OF,(reg_flags & 1u) ^ ((unsigned int)lf_resd >> 31u));       \
00369 }
00370 
00371 
00372 
00373 #define RCRB(op1,op2,load,save)                                                         \
00374         if (op2%9) {                                                                                    \
00375                 Bit8u cf=(Bit8u)FillFlags()&0x1;                                        \
00376                 lf_var1b=load(op1);                                                                     \
00377                 lf_var2b=op2%9;                                                                         \
00378                 lf_resb=(lf_var1b >> lf_var2b) |                                        \
00379                                 (cf << (8-lf_var2b)) |                                          \
00380                                 (lf_var1b << (9-lf_var2b));                                     \
00381                 save(op1,lf_resb);                                                                      \
00382                 SETFLAGBIT(CF,((unsigned int)lf_var1b >> (lf_var2b - 1u)) & 1u);        \
00383                 SETFLAGBIT(OF,(lf_resb ^ ((unsigned int)lf_resb<<1u)) & 0x80u);         \
00384         }
00385 
00386 #define RCRW(op1,op2,load,save)                                                         \
00387         if (op2%17) {                                                                                   \
00388                 Bit16u cf=(Bit16u)FillFlags()&0x1;                                      \
00389                 lf_var1w=load(op1);                                                                     \
00390                 lf_var2b=op2%17;                                                                        \
00391                 lf_resw=(lf_var1w >> lf_var2b) |                                        \
00392                                 (cf << (16-lf_var2b)) |                                         \
00393                                 (lf_var1w << (17-lf_var2b));                            \
00394                 save(op1,lf_resw);                                                                      \
00395                 SETFLAGBIT(CF,((unsigned int)lf_var1w >> (lf_var2b - 1u)) & 1u);        \
00396                 SETFLAGBIT(OF,(lf_resw ^ ((unsigned int)lf_resw<<1u)) & 0x8000u);       \
00397         }
00398 
00399 #define RCRD(op1,op2,load,save)                                                         \
00400         if (op2) {                                                                                              \
00401                 Bit32u cf=(Bit32u)FillFlags()&0x1;                                      \
00402                 lf_var1d=load(op1);                                                                     \
00403                 lf_var2b=op2;                                                                           \
00404                 if (lf_var2b==1) {                                                                      \
00405                         lf_resd=lf_var1d >> 1 | cf << 31;                               \
00406                 } else {                                                                                        \
00407                         lf_resd=(lf_var1d >> lf_var2b) |                                \
00408                                 (cf << (32-lf_var2b)) |                                         \
00409                                 (lf_var1d << (33-lf_var2b));                            \
00410                 }                                                                                                       \
00411                 save(op1,lf_resd);                                                                      \
00412                 SETFLAGBIT(CF,((unsigned int)lf_var1d >> (lf_var2b - 1u)) & 1u);        \
00413                 SETFLAGBIT(OF,(lf_resd ^ ((unsigned int)lf_resd<<1u)) & 0x80000000u);   \
00414         }
00415 
00416 
00417 #define SHLB(op1,op2,load,save)                                                         \
00418         if (!op2) break;                                                                                \
00419         lf_var1b=load(op1);lf_var2b=op2;                                \
00420         lf_resb=(lf_var2b < 8u) ? ((unsigned int)lf_var1b << lf_var2b) : 0;                     \
00421         save(op1,lf_resb);                                                              \
00422         lflags.type=t_SHLb;
00423 
00424 #define SHLW(op1,op2,load,save)                                                         \
00425         if (!op2) break;                                                                                \
00426         lf_var1w=load(op1);lf_var2b=op2 ;                               \
00427         lf_resw=(lf_var2b < 16u) ? ((unsigned int)lf_var1w << lf_var2b) : 0;                    \
00428         save(op1,lf_resw);                                                              \
00429         lflags.type=t_SHLw;
00430 
00431 #define SHLD(op1,op2,load,save)                                                         \
00432         if (!op2) break;                                                                                \
00433         lf_var1d=load(op1);lf_var2b=op2;                                \
00434         lf_resd=(lf_var2b < 32u) ? ((unsigned int)lf_var1d << lf_var2b) : 0;                    \
00435         save(op1,lf_resd);                                                              \
00436         lflags.type=t_SHLd;
00437 
00438 
00439 #define SHRB(op1,op2,load,save)                                                         \
00440         if (!op2) break;                                                                                \
00441         lf_var1b=load(op1);lf_var2b=op2;                                \
00442         lf_resb=(lf_var2b < 8u) ? ((unsigned int)lf_var1b >> lf_var2b) : 0;                     \
00443         save(op1,lf_resb);                                                              \
00444         lflags.type=t_SHRb;
00445 
00446 #define SHRW(op1,op2,load,save)                                                         \
00447         if (!op2) break;                                                                                \
00448         lf_var1w=load(op1);lf_var2b=op2;                                \
00449         lf_resw=(lf_var2b < 16u) ? ((unsigned int)lf_var1w >> lf_var2b) : 0;                    \
00450         save(op1,lf_resw);                                                              \
00451         lflags.type=t_SHRw;
00452 
00453 #define SHRD(op1,op2,load,save)                                                         \
00454         if (!op2) break;                                                                                \
00455         lf_var1d=load(op1);lf_var2b=op2;                                \
00456         lf_resd=(lf_var2b < 32u) ? ((unsigned int)lf_var1d >> lf_var2b) : 0;                    \
00457         save(op1,lf_resd);                                                              \
00458         lflags.type=t_SHRd;
00459 
00460 
00461 #define SARB(op1,op2,load,save)                                                         \
00462         if (!op2) break;                                                                                \
00463         lf_var1b=load(op1);lf_var2b=op2;                                \
00464         if (lf_var2b>8) lf_var2b=8;                                             \
00465     if (lf_var1b & 0x80) {                                                              \
00466                 lf_resb=(lf_var1b >> lf_var2b)|         \
00467                 (0xff << (8 - lf_var2b));                                               \
00468         } else {                                                                                                \
00469                 lf_resb=lf_var1b >> lf_var2b;           \
00470     }                                                                                                           \
00471         save(op1,lf_resb);                                                              \
00472         lflags.type=t_SARb;
00473 
00474 #define SARW(op1,op2,load,save)                                                         \
00475         if (!op2) break;                                                                \
00476         lf_var1w=load(op1);lf_var2b=op2;                        \
00477         if (lf_var2b>16) lf_var2b=16;                                   \
00478         if (lf_var1w & 0x8000) {                                                        \
00479                 lf_resw=(lf_var1w >> lf_var2b)|         \
00480                 (0xffff << (16 - lf_var2b));                                    \
00481         } else {                                                                                                \
00482                 lf_resw=lf_var1w >> lf_var2b;           \
00483     }                                                                                                           \
00484         save(op1,lf_resw);                                                              \
00485         lflags.type=t_SARw;
00486 
00487 #define SARD(op1,op2,load,save)                                                         \
00488         if (!op2) break;                                                                \
00489         lf_var2b=op2;lf_var1d=load(op1);                        \
00490         if (lf_var1d & 0x80000000) {                                            \
00491                 lf_resd=(lf_var1d >> lf_var2b)|         \
00492                 (0xffffffff << (32 - lf_var2b));                                \
00493         } else {                                                                                                \
00494                 lf_resd=lf_var1d >> lf_var2b;           \
00495     }                                                                                                           \
00496         save(op1,lf_resd);                                                              \
00497         lflags.type=t_SARd;
00498 
00499 
00500 
00501 #define DAA()                                                                                           \
00502         if (((reg_al & 0x0F)>0x09) || get_AF()) {                               \
00503                 if ((reg_al > 0x99) || get_CF()) {                                      \
00504                         reg_al+=0x60;                                                                   \
00505                         SETFLAGBIT(CF,true);                                                    \
00506                 } else {                                                                                        \
00507                         SETFLAGBIT(CF,false);                                                   \
00508                 }                                                                                                       \
00509                 reg_al+=0x06;                                                                           \
00510                 SETFLAGBIT(AF,true);                                                            \
00511         } else {                                                                                                \
00512                 if ((reg_al > 0x99) || get_CF()) {                                      \
00513                         reg_al+=0x60;                                                                   \
00514                         SETFLAGBIT(CF,true);                                                    \
00515                 } else {                                                                                        \
00516                         SETFLAGBIT(CF,false);                                                   \
00517                 }                                                                                                       \
00518                 SETFLAGBIT(AF,false);                                                           \
00519         }                                                                                                               \
00520         SETFLAGBIT(SF,(reg_al&0x80));                                                   \
00521         SETFLAGBIT(ZF,(reg_al==0));                                                             \
00522         SETFLAGBIT(PF,parity_lookup[reg_al]);                                   \
00523         lflags.type=t_UNKNOWN;
00524 
00525 
00526 #define DAS()                                                                                           \
00527 {                                                                                                                       \
00528         Bit8u osigned=reg_al & 0x80;                                                    \
00529         if (((reg_al & 0x0f) > 9) || get_AF()) {                                \
00530                 if ((reg_al>0x99) || get_CF()) {                                        \
00531                         reg_al-=0x60;                                                                   \
00532                         SETFLAGBIT(CF,true);                                                    \
00533                 } else {                                                                                        \
00534                         SETFLAGBIT(CF,(reg_al<=0x05));                                  \
00535                 }                                                                                                       \
00536                 reg_al-=6;                                                                                      \
00537                 SETFLAGBIT(AF,true);                                                            \
00538         } else {                                                                                                \
00539                 if ((reg_al>0x99) || get_CF()) {                                        \
00540                         reg_al-=0x60;                                                                   \
00541                         SETFLAGBIT(CF,true);                                                    \
00542                 } else {                                                                                        \
00543                         SETFLAGBIT(CF,false);                                                   \
00544                 }                                                                                                       \
00545                 SETFLAGBIT(AF,false);                                                           \
00546         }                                                                                                               \
00547         SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0));                   \
00548         SETFLAGBIT(SF,(reg_al&0x80));                                                   \
00549         SETFLAGBIT(ZF,(reg_al==0));                                                             \
00550         SETFLAGBIT(PF,parity_lookup[reg_al]);                                   \
00551         lflags.type=t_UNKNOWN;                                                                  \
00552 }
00553 
00554 
00555 #define AAA()                                                                                           \
00556         SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9)));              \
00557         if ((reg_al & 0xf) > 9) {                                                               \
00558                 SETFLAGBIT(OF,(reg_al&0xf0)==0x70);                                     \
00559                 reg_ax += 0x106;                                                                        \
00560                 SETFLAGBIT(CF,true);                                                            \
00561                 SETFLAGBIT(ZF,(reg_al == 0));                                           \
00562                 SETFLAGBIT(AF,true);                                                            \
00563         } else if (get_AF()) {                                                                  \
00564                 reg_ax += 0x106;                                                                        \
00565                 SETFLAGBIT(OF,false);                                                           \
00566                 SETFLAGBIT(CF,true);                                                            \
00567                 SETFLAGBIT(ZF,false);                                                           \
00568                 SETFLAGBIT(AF,true);                                                            \
00569         } else {                                                                                                \
00570                 SETFLAGBIT(OF,false);                                                           \
00571                 SETFLAGBIT(CF,false);                                                           \
00572                 SETFLAGBIT(ZF,(reg_al == 0));                                           \
00573                 SETFLAGBIT(AF,false);                                                           \
00574         }                                                                                                               \
00575         SETFLAGBIT(PF,parity_lookup[reg_al]);                                   \
00576         reg_al &= 0x0F;                                                                                 \
00577         lflags.type=t_UNKNOWN;
00578 
00579 #define AAS()                                                                                           \
00580         if ((reg_al & 0x0f)>9) {                                                                \
00581                 SETFLAGBIT(SF,(reg_al>0x85));                                           \
00582                 reg_ax -= 0x106;                                                                        \
00583                 SETFLAGBIT(OF,false);                                                           \
00584                 SETFLAGBIT(CF,true);                                                            \
00585                 SETFLAGBIT(AF,true);                                                            \
00586         } else if (get_AF()) {                                                                  \
00587                 SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85)));      \
00588                 SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85));          \
00589                 reg_ax -= 0x106;                                                                        \
00590                 SETFLAGBIT(CF,true);                                                            \
00591                 SETFLAGBIT(AF,true);                                                            \
00592         } else {                                                                                                \
00593                 SETFLAGBIT(SF,(reg_al>=0x80));                                          \
00594                 SETFLAGBIT(OF,false);                                                           \
00595                 SETFLAGBIT(CF,false);                                                           \
00596                 SETFLAGBIT(AF,false);                                                           \
00597         }                                                                                                               \
00598         SETFLAGBIT(ZF,(reg_al == 0));                                                   \
00599         SETFLAGBIT(PF,parity_lookup[reg_al]);                                   \
00600         reg_al &= 0x0F;                                                                                 \
00601         lflags.type=t_UNKNOWN;
00602 
00603 #define AAM(op1)                                                                                        \
00604 {                                                                                                                       \
00605         Bit8u dv=op1;                                                                                   \
00606         if (dv!=0) {                                                                                    \
00607                 reg_ah=reg_al / dv;                                                                     \
00608                 reg_al=reg_al % dv;                                                                     \
00609                 SETFLAGBIT(SF,(reg_al & 0x80));                                         \
00610                 SETFLAGBIT(ZF,(reg_al == 0));                                           \
00611                 SETFLAGBIT(PF,parity_lookup[reg_al]);                           \
00612                 SETFLAGBIT(CF,false);                                                           \
00613                 SETFLAGBIT(OF,false);                                                           \
00614                 SETFLAGBIT(AF,false);                                                           \
00615                 lflags.type=t_UNKNOWN;                                                          \
00616         } else EXCEPTION(0);                                                                    \
00617 }
00618 
00619 
00620 //Took this from bochs, i seriously hate these weird bcd opcodes
00621 #define AAD(op1)                                                                                        \
00622         {                                                                                                               \
00623                 Bit16u ax1 = reg_ah * op1;                                                      \
00624                 Bit16u ax2 = ax1 + reg_al;                                                      \
00625                 reg_al = (Bit8u) ax2;                                                           \
00626                 reg_ah = 0;                                                                                     \
00627                 SETFLAGBIT(CF,false);                                                           \
00628                 SETFLAGBIT(OF,false);                                                           \
00629                 SETFLAGBIT(AF,false);                                                           \
00630                 SETFLAGBIT(SF,reg_al >= 0x80);                                          \
00631                 SETFLAGBIT(ZF,reg_al == 0);                                                     \
00632                 SETFLAGBIT(PF,parity_lookup[reg_al]);                           \
00633                 lflags.type=t_UNKNOWN;                                                          \
00634         }
00635 
00636 #define PARITY16(x)  (parity_lookup[((unsigned int)((Bit16u)(x))>>8u)&0xffu]^parity_lookup[((Bit8u)(x))&0xffu]^FLAG_PF)
00637 #define PARITY32(x)  (PARITY16(((Bit16u)(x))&0xffffu)^PARITY16(((unsigned int)((Bit32u)(x))>>16u)&0xffffu)^FLAG_PF)
00638 
00639 #define MULB(op1,load,save)                                                                     \
00640         reg_ax=reg_al*load(op1);                                                                \
00641         FillFlagsNoCFOF();                                                                              \
00642         SETFLAGBIT(ZF,reg_al == 0);                                                             \
00643         SETFLAGBIT(PF,PARITY16(reg_ax));                                                                \
00644         if (reg_ax & 0xff00) {                                                                  \
00645                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00646         } else {                                                                                                \
00647                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00648         }
00649 
00650 #define MULW(op1,load,save)                                                                     \
00651 {                                                                                                                       \
00652         Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1));                              \
00653         reg_ax=(Bit16u)(tempu);                                                                 \
00654         reg_dx=(Bit16u)(tempu >> 16);                                                   \
00655         FillFlagsNoCFOF();                                                                              \
00656         SETFLAGBIT(ZF,reg_ax == 0);                                                             \
00657         SETFLAGBIT(PF,PARITY16(reg_ax)^PARITY16(reg_dx)^FLAG_PF);                                               \
00658         if (reg_dx) {                                                                                   \
00659                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00660         } else {                                                                                                \
00661                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00662         }                                                                                                               \
00663 }
00664 
00665 #define MULD(op1,load,save)                                                                     \
00666 {                                                                                                                       \
00667         Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1));               \
00668         reg_eax=(Bit32u)(tempu);                                                                \
00669         reg_edx=(Bit32u)(tempu >> 32);                                                  \
00670         FillFlagsNoCFOF();                                                                              \
00671         SETFLAGBIT(ZF,reg_eax == 0);                                                    \
00672         SETFLAGBIT(PF,PARITY32(reg_eax)^PARITY32(reg_edx)^FLAG_PF);                                             \
00673         if (reg_edx) {                                                                                  \
00674                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00675         } else {                                                                                                \
00676                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00677         }                                                                                                               \
00678 }
00679 
00680 #define DIVB(op1,load,save)                                                                     \
00681 {                                                                                                                       \
00682         Bitu val=load(op1);                                                                             \
00683         if (val==0)     EXCEPTION(0);                                                           \
00684         Bitu quo=reg_ax / val;                                                                  \
00685         Bit8u rem=(Bit8u)(reg_ax % val);                                                \
00686         Bit8u quo8=(Bit8u)(quo&0xff);                                                   \
00687         if (quo>0xff) EXCEPTION(0);                                                             \
00688         reg_ah=rem;                                                                                             \
00689         reg_al=quo8;                                                                                    \
00690         FillFlags();                                                                                    \
00691         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00692         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00693         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00694         SETFLAGBIT(ZF,(rem==0)&&((quo8&1)!=0));                                                         \
00695         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00696         SETFLAGBIT(PF,parity_lookup[rem&0xff]^parity_lookup[quo8&0xff]^FLAG_PF);                                        \
00697 }
00698 
00699 
00700 #define DIVW(op1,load,save)                                                                     \
00701 {                                                                                                                       \
00702         Bitu val=load(op1);                                                                             \
00703         if (val==0)     EXCEPTION(0);                                                           \
00704         Bitu num=((Bit32u)reg_dx<<16)|reg_ax;                                                   \
00705         Bitu quo=num/val;                                                                               \
00706         Bit16u rem=(Bit16u)(num % val);                                                 \
00707         Bit16u quo16=(Bit16u)(quo&0xffff);                                              \
00708         if (quo!=(Bit32u)quo16) EXCEPTION(0);                                   \
00709         reg_dx=rem;                                                                                             \
00710         reg_ax=quo16;                                                                                   \
00711         FillFlags();                                                                                    \
00712         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00713         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00714         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00715         SETFLAGBIT(ZF,(rem==0)&&((quo16&1)!=0));                                                                \
00716         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00717         SETFLAGBIT(PF,PARITY16(rem&0xffff)^PARITY16(quo16&0xffff)^FLAG_PF);                                     \
00718 }
00719 
00720 #define DIVD(op1,load,save)                                                                     \
00721 {                                                                                                                       \
00722         Bitu val=load(op1);                                                                             \
00723         if (val==0) EXCEPTION(0);                                                                       \
00724         Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;                             \
00725         Bit64u quo=num/val;                                                                             \
00726         Bit32u rem=(Bit32u)(num % val);                                                 \
00727         Bit32u quo32=(Bit32u)(quo&0xffffffff);                                  \
00728         if (quo!=(Bit64u)quo32) EXCEPTION(0);                                   \
00729         reg_edx=rem;                                                                                    \
00730         reg_eax=quo32;                                                                                  \
00731         FillFlags();                                                                                    \
00732         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00733         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00734         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00735         SETFLAGBIT(ZF,(rem==0)&&((quo32&1)!=0));                                                                \
00736         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00737         SETFLAGBIT(PF,PARITY32(rem&0xffffffff)^PARITY32(quo32&0xffffffff)^FLAG_PF);                                     \
00738 }
00739 
00740 
00741 #define IDIVB(op1,load,save)                                                            \
00742 {                                                                                                                       \
00743         Bits val=(Bit8s)(load(op1));                                                    \
00744         if (val==0)     EXCEPTION(0);                                                           \
00745         Bits quo=((Bit16s)reg_ax) / val;                                                \
00746         Bit8s rem=(Bit8s)((Bit16s)reg_ax % val);                                \
00747         Bit8s quo8s=(Bit8s)(quo&0xff);                                                  \
00748         if (quo!=(Bit16s)quo8s) EXCEPTION(0);                                   \
00749         reg_ah=(Bit8u)rem;                                                                                              \
00750         reg_al=(Bit8u)quo8s;                                                                                    \
00751         FillFlags();                                                                                    \
00752         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00753         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00754         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00755         SETFLAGBIT(ZF,(rem==0)&&((quo8s&1)!=0));                                                                \
00756         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00757         SETFLAGBIT(PF,parity_lookup[rem&0xff]^parity_lookup[quo8s&0xff]^FLAG_PF);                                       \
00758 }
00759 
00760 
00761 #define IDIVW(op1,load,save)                                                            \
00762 {                                                                                                                       \
00763         Bits val=(Bit16s)(load(op1));                                                   \
00764         if (val==0) EXCEPTION(0);                                                                       \
00765         Bits num=(Bit32s)(((unsigned int)reg_dx<<16u)|(unsigned int)reg_ax);                                    \
00766         Bits quo=num/val;                                                                               \
00767         Bit16s rem=(Bit16s)(num % val);                                                 \
00768         Bit16s quo16s=(Bit16s)quo;                                                              \
00769         if (quo!=(Bit32s)quo16s) EXCEPTION(0);                                  \
00770         reg_dx=(Bit16u)rem;                                                                                             \
00771         reg_ax=(Bit16u)quo16s;                                                                                  \
00772         FillFlags();                                                                                    \
00773         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00774         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00775         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00776         SETFLAGBIT(ZF,(rem==0)&&((quo16s&1)!=0));                                                               \
00777         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00778         SETFLAGBIT(PF,PARITY16(rem&0xffff)^PARITY16(quo16s&0xffff)^FLAG_PF);                                    \
00779 }
00780 
00781 #define IDIVD(op1,load,save)                                                            \
00782 {                                                                                                                       \
00783         Bits val=(Bit32s)(load(op1));                                                   \
00784         if (val==0) EXCEPTION(0);                                                                       \
00785         Bit64s num=(Bit64s)((((Bit64u)reg_edx)<<(Bit64u)32)|(Bit64u)reg_eax);                           \
00786         Bit64s quo=num/val;                                                                             \
00787         Bit32s rem=(Bit32s)(num % val);                                                 \
00788         Bit32s quo32s=(Bit32s)(quo&0xffffffff);                                 \
00789         if (quo!=(Bit64s)quo32s) EXCEPTION(0);                                  \
00790         reg_edx=(Bit32u)rem;                                                                                    \
00791         reg_eax=(Bit32u)quo32s;                                                                                 \
00792         FillFlags();                                                                                    \
00793         SETFLAGBIT(AF,0);/*FIXME*/                                                                      \
00794         SETFLAGBIT(SF,0);/*FIXME*/                                                                      \
00795         SETFLAGBIT(OF,0);/*FIXME*/                                                                      \
00796         SETFLAGBIT(ZF,(rem==0)&&((quo32s&1)!=0));                                                               \
00797         SETFLAGBIT(CF,((rem&3) >= 1 && (rem&3) <= 2)); \
00798         SETFLAGBIT(PF,PARITY32((Bit32u)rem&0xffffffffu)^PARITY32((Bit32u)quo32s&0xffffffffu)^FLAG_PF);                                  \
00799 }
00800 
00801 #define IMULB(op1,load,save)                                                            \
00802 {                                                                                                                       \
00803         reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1)));                  \
00804         FillFlagsNoCFOF();                                                                              \
00805         if ((reg_ax & 0xff80)==0xff80 ||                                                \
00806                 (reg_ax & 0xff80)==0x0000) {                                            \
00807                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00808         } else {                                                                                                \
00809                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00810         }                                                                                                               \
00811 }
00812         
00813 
00814 #define IMULW(op1,load,save)                                                            \
00815 {                                                                                                                       \
00816         Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1)));              \
00817         reg_ax=(Bit16u)(temps);                                                                 \
00818         reg_dx=(Bit16u)(temps >> 16);                                                   \
00819         FillFlagsNoCFOF();                                                                              \
00820         if (((temps & 0xffff8000)==0xffff8000 ||                                \
00821                 (temps & 0xffff8000)==0x0000)) {                                        \
00822                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00823         } else {                                                                                                \
00824                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00825         }                                                                                                               \
00826 }
00827 
00828 #define IMULD(op1,load,save)                                                            \
00829 {                                                                                                                       \
00830         Bit64s temps=((Bit64s)((Bit32s)reg_eax))*                               \
00831                                  ((Bit64s)((Bit32s)(load(op1))));                       \
00832         reg_eax=(Bit32u)(temps);                                                                \
00833         reg_edx=(Bit32u)(temps >> 32);                                                  \
00834         FillFlagsNoCFOF();                                                                              \
00835         if ((reg_edx==0xffffffff) &&                                                    \
00836                 (reg_eax & 0x80000000) ) {                                                      \
00837                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00838         } else if ( (reg_edx==0x00000000) &&                                    \
00839                                 (reg_eax< 0x80000000) ) {                                       \
00840                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00841         } else {                                                                                                \
00842                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00843         }                                                                                                               \
00844 }
00845 
00846 #define DIMULW(op1,op2,op3,load,save)                                           \
00847 {                                                                                                                       \
00848         Bits res=((Bit16s)op2) * ((Bit16s)op3);                                 \
00849         save(op1,res & 0xffff);                                                                 \
00850         FillFlagsNoCFOF();                                                                              \
00851         if ((res>= -32768)  && (res<=32767)) {                                  \
00852                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00853         } else {                                                                                                \
00854                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00855         }                                                                                                               \
00856 }
00857 
00858 #define DIMULD(op1,op2,op3,load,save)                                           \
00859 {                                                                                                                       \
00860         Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3));     \
00861         save(op1,(Bit32s)res);                                                                  \
00862         FillFlagsNoCFOF();                                                                              \
00863         if ((res>=-((Bit64s)(2147483647)+1)) &&                                 \
00864                 (res<=(Bit64s)2147483647)) {                                            \
00865                 SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);                      \
00866         } else {                                                                                                \
00867                 SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);                        \
00868         }                                                                                                               \
00869 }
00870 
00871 #if CPU_CORE == CPU_ARCHTYPE_8086
00872 #  define CPU_SHIFTOP_MASK(x,m) ((x) & 0xff)
00873 #else
00874 #  define CPU_SHIFTOP_MASK(x,m) ((x) & 0x1f)
00875 #endif
00876 
00877 /* FIXME: For 8086 core we care mostly about whether or not SHL/SHR emulate the non-masked shift count.
00878  *        Note that running this code compiled for Intel processors naturally imposes the shift count,
00879  *        compilers generate a shift instruction and do not consider the CPU masking the bit count.
00880  *
00881  *        unsigned int a = 0x12345678,b = 0x20,c;
00882  *        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).
00883  *
00884  *        What we care about is that shift counts greater than or equal to the width of the target register come out to zero,
00885  *        or for SAR, that all bits become copies of the sign bit. When emulating the 8086 we want DOS programs to be able to
00886  *        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.
00887  *        the shift count mask test is one of the several tests DOS programs may do to differentiate 8086 from 80186. */
00888 #define GRP2B(blah)                                                                                     \
00889 {                                                                                                                       \
00890         GetRM;Bitu which=(rm>>3)&7;                                                             \
00891         if (rm >= 0xc0) {                                                                               \
00892                 GetEArb;                                                                                        \
00893                 Bit8u val=CPU_SHIFTOP_MASK(blah,7);                                                             \
00894                 switch (which)  {                                                                       \
00895                 case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break;          \
00896                 case 0x01:RORB(*earb,val,LoadRb,SaveRb);break;          \
00897                 case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break;          \
00898                 case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break;          \
00899                 case 0x04:/* SHL and SAL are the same */                        \
00900                 case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break;          \
00901                 case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break;          \
00902                 case 0x07:SARB(*earb,val,LoadRb,SaveRb);break;          \
00903                 }                                                                                                       \
00904         } else {                                                                                                \
00905                 GetEAa;                                                                                         \
00906                 Bit8u val=CPU_SHIFTOP_MASK(blah,7);                                                             \
00907                 switch (which) {                                                                        \
00908                 case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break;            \
00909                 case 0x01:RORB(eaa,val,LoadMb,SaveMb);break;            \
00910                 case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break;            \
00911                 case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break;            \
00912                 case 0x04:/* SHL and SAL are the same */                        \
00913                 case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break;            \
00914                 case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break;            \
00915                 case 0x07:SARB(eaa,val,LoadMb,SaveMb);break;            \
00916                 }                                                                                                       \
00917         }                                                                                                               \
00918 }
00919 
00920 
00921 
00922 #define GRP2W(blah)                                                                                     \
00923 {                                                                                                                       \
00924         GetRM;Bitu which=(rm>>3)&7;                                                             \
00925         if (rm >= 0xc0) {                                                                               \
00926                 GetEArw;                                                                                        \
00927                 Bit8u val=CPU_SHIFTOP_MASK(blah,15);                                                            \
00928                 switch (which)  {                                                                       \
00929                 case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break;          \
00930                 case 0x01:RORW(*earw,val,LoadRw,SaveRw);break;          \
00931                 case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break;          \
00932                 case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break;          \
00933                 case 0x04:/* SHL and SAL are the same */                        \
00934                 case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break;          \
00935                 case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break;          \
00936                 case 0x07:SARW(*earw,val,LoadRw,SaveRw);break;          \
00937                 }                                                                                                       \
00938         } else {                                                                                                \
00939                 GetEAa;                                                                                         \
00940                 Bit8u val=CPU_SHIFTOP_MASK(blah,15);                                                            \
00941                 switch (which) {                                                                        \
00942                 case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break;            \
00943                 case 0x01:RORW(eaa,val,LoadMw,SaveMw);break;            \
00944                 case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break;            \
00945                 case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break;            \
00946                 case 0x04:/* SHL and SAL are the same */                        \
00947                 case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break;            \
00948                 case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break;            \
00949                 case 0x07:SARW(eaa,val,LoadMw,SaveMw);break;            \
00950                 }                                                                                                       \
00951         }                                                                                                               \
00952 }
00953 
00954 
00955 #define GRP2D(blah)                                                                                     \
00956 {                                                                                                                       \
00957         GetRM;Bitu which=(rm>>3)&7;                                                             \
00958         if (rm >= 0xc0) {                                                                               \
00959                 GetEArd;                                                                                        \
00960                 Bit8u val=CPU_SHIFTOP_MASK(blah,31);                                                            \
00961                 switch (which)  {                                                                       \
00962                 case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break;          \
00963                 case 0x01:RORD(*eard,val,LoadRd,SaveRd);break;          \
00964                 case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break;          \
00965                 case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break;          \
00966                 case 0x04:/* SHL and SAL are the same */                        \
00967                 case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break;          \
00968                 case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break;          \
00969                 case 0x07:SARD(*eard,val,LoadRd,SaveRd);break;          \
00970                 }                                                                                                       \
00971         } else {                                                                                                \
00972                 GetEAa;                                                                                         \
00973                 Bit8u val=CPU_SHIFTOP_MASK(blah,31);                                                            \
00974                 switch (which) {                                                                        \
00975                 case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break;            \
00976                 case 0x01:RORD(eaa,val,LoadMd,SaveMd);break;            \
00977                 case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break;            \
00978                 case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break;            \
00979                 case 0x04:/* SHL and SAL are the same */                        \
00980                 case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break;            \
00981                 case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break;            \
00982                 case 0x07:SARD(eaa,val,LoadMd,SaveMd);break;            \
00983                 }                                                                                                       \
00984         }                                                                                                               \
00985 }
00986 
00987 /* let's hope bochs has it correct with the higher than 16 shifts */
00988 /* double-precision shift left has low bits in second argument */
00989 #define DSHLW(op1,op2,op3,load,save)                                                                    \
00990         Bit8u val=op3 & 0x1Fu;                                                                                          \
00991         if (!val) break;                                                                                                        \
00992         lf_var2b=val;lf_var1d=((unsigned int)load(op1)<<16u)|op2;                                       \
00993         Bit32u tempd=lf_var1d << lf_var2b;                                                      \
00994         if (lf_var2b>16u) tempd |= ((unsigned int)op2 << (lf_var2b - 16u));                     \
00995         lf_resw=(Bit16u)((unsigned int)tempd >> 16u);                                                           \
00996         save(op1,lf_resw);                                                                                      \
00997         lflags.type=t_DSHLw;
00998 
00999 #define DSHLD(op1,op2,op3,load,save)                                                                    \
01000         Bit8u val=op3 & 0x1Fu;                                                                                          \
01001         if (!val) break;                                                                                                        \
01002         lf_var2b=val;lf_var1d=load(op1);                                                        \
01003         lf_resd=((unsigned int)lf_var1d << lf_var2b) | ((unsigned int)op2 >> (32u-lf_var2b));   \
01004         save(op1,lf_resd);                                                                                      \
01005         lflags.type=t_DSHLd;
01006 
01007 /* double-precision shift right has high bits in second argument */
01008 #define DSHRW(op1,op2,op3,load,save)                                                                    \
01009         Bit8u val=op3 & 0x1Fu;                                                                                          \
01010         if (!val) break;                                                                                                        \
01011         lf_var2b=val;lf_var1d=((unsigned int)op2<<16u)|load(op1);                                       \
01012         Bit32u tempd=(unsigned int)lf_var1d >> lf_var2b;                                                        \
01013         if (lf_var2b>16u) tempd |= ((unsigned int)op2 << (32u-lf_var2b));                       \
01014         lf_resw=(Bit16u)(tempd);                                                                                \
01015         save(op1,lf_resw);                                                                                      \
01016         lflags.type=t_DSHRw;
01017 
01018 #define DSHRD(op1,op2,op3,load,save)                                                                    \
01019         Bit8u val=op3 & 0x1Fu;                                                                                          \
01020         if (!val) break;                                                                                                        \
01021         lf_var2b=val;lf_var1d=load(op1);                                                        \
01022         lf_resd=((unsigned int)lf_var1d >> lf_var2b) | ((unsigned int)op2 << (32u-lf_var2b));   \
01023         save(op1,lf_resd);                                                                                      \
01024         lflags.type=t_DSHRd;
01025 
01026 #define BSWAPW(op1)                                                                                                             \
01027         op1 = 0;
01028 
01029 #define BSWAPD(op1)                                                                                                             \
01030         op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);