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