1 /*
2  *  Copyright (C) 2002-2021  The DOSBox Team
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "lazyflags.h"
20 
21 /* Jumps */
22 
23 /* All Byte general instructions */
24 #define ADDB(op1,op2,load,save)								\
25 	lf_var1b=load(op1);lf_var2b=op2;					\
26 	lf_resb=lf_var1b+lf_var2b;					\
27 	save(op1,lf_resb);								\
28 	lflags.type=t_ADDb;
29 
30 #define ADCB(op1,op2,load,save)								\
31 	lflags.oldcf=get_CF()!=0;								\
32 	lf_var1b=load(op1);lf_var2b=op2;					\
33 	lf_resb=lf_var1b+lf_var2b+lflags.oldcf;		\
34 	save(op1,lf_resb);								\
35 	lflags.type=t_ADCb;
36 
37 #define SBBB(op1,op2,load,save)								\
38 	lflags.oldcf=get_CF()!=0;									\
39 	lf_var1b=load(op1);lf_var2b=op2;					\
40 	lf_resb=lf_var1b-(lf_var2b+lflags.oldcf);	\
41 	save(op1,lf_resb);								\
42 	lflags.type=t_SBBb;
43 
44 #define SUBB(op1,op2,load,save)								\
45 	lf_var1b=load(op1);lf_var2b=op2;					\
46 	lf_resb=lf_var1b-lf_var2b;					\
47 	save(op1,lf_resb);								\
48 	lflags.type=t_SUBb;
49 
50 #define ORB(op1,op2,load,save)								\
51 	lf_var1b=load(op1);lf_var2b=op2;					\
52 	lf_resb=lf_var1b | lf_var2b;				\
53 	save(op1,lf_resb);								\
54 	lflags.type=t_ORb;
55 
56 #define XORB(op1,op2,load,save)								\
57 	lf_var1b=load(op1);lf_var2b=op2;					\
58 	lf_resb=lf_var1b ^ lf_var2b;				\
59 	save(op1,lf_resb);								\
60 	lflags.type=t_XORb;
61 
62 #define ANDB(op1,op2,load,save)								\
63 	lf_var1b=load(op1);lf_var2b=op2;					\
64 	lf_resb=lf_var1b & lf_var2b;				\
65 	save(op1,lf_resb);								\
66 	lflags.type=t_ANDb;
67 
68 #define CMPB(op1,op2,load,save)								\
69 	lf_var1b=load(op1);lf_var2b=op2;					\
70 	lf_resb=lf_var1b-lf_var2b;					\
71 	lflags.type=t_CMPb;
72 
73 #define TESTB(op1,op2,load,save)							\
74 	lf_var1b=load(op1);lf_var2b=op2;					\
75 	lf_resb=lf_var1b & lf_var2b;				\
76 	lflags.type=t_TESTb;
77 
78 /* All Word General instructions */
79 
80 #define ADDW(op1,op2,load,save)								\
81 	lf_var1w=load(op1);lf_var2w=op2;					\
82 	lf_resw=lf_var1w+lf_var2w;					\
83 	save(op1,lf_resw);								\
84 	lflags.type=t_ADDw;
85 
86 #define ADCW(op1,op2,load,save)								\
87 	lflags.oldcf=get_CF()!=0;									\
88 	lf_var1w=load(op1);lf_var2w=op2;					\
89 	lf_resw=lf_var1w+lf_var2w+lflags.oldcf;		\
90 	save(op1,lf_resw);								\
91 	lflags.type=t_ADCw;
92 
93 #define SBBW(op1,op2,load,save)								\
94 	lflags.oldcf=get_CF()!=0;									\
95 	lf_var1w=load(op1);lf_var2w=op2;					\
96 	lf_resw=lf_var1w-(lf_var2w+lflags.oldcf);	\
97 	save(op1,lf_resw);								\
98 	lflags.type=t_SBBw;
99 
100 #define SUBW(op1,op2,load,save)								\
101 	lf_var1w=load(op1);lf_var2w=op2;					\
102 	lf_resw=lf_var1w-lf_var2w;					\
103 	save(op1,lf_resw);								\
104 	lflags.type=t_SUBw;
105 
106 #define ORW(op1,op2,load,save)								\
107 	lf_var1w=load(op1);lf_var2w=op2;					\
108 	lf_resw=lf_var1w | lf_var2w;				\
109 	save(op1,lf_resw);								\
110 	lflags.type=t_ORw;
111 
112 #define XORW(op1,op2,load,save)								\
113 	lf_var1w=load(op1);lf_var2w=op2;					\
114 	lf_resw=lf_var1w ^ lf_var2w;				\
115 	save(op1,lf_resw);								\
116 	lflags.type=t_XORw;
117 
118 #define ANDW(op1,op2,load,save)								\
119 	lf_var1w=load(op1);lf_var2w=op2;					\
120 	lf_resw=lf_var1w & lf_var2w;				\
121 	save(op1,lf_resw);								\
122 	lflags.type=t_ANDw;
123 
124 #define CMPW(op1,op2,load,save)								\
125 	lf_var1w=load(op1);lf_var2w=op2;					\
126 	lf_resw=lf_var1w-lf_var2w;					\
127 	lflags.type=t_CMPw;
128 
129 #define TESTW(op1,op2,load,save)							\
130 	lf_var1w=load(op1);lf_var2w=op2;					\
131 	lf_resw=lf_var1w & lf_var2w;				\
132 	lflags.type=t_TESTw;
133 
134 /* All DWORD General Instructions */
135 
136 #define ADDD(op1,op2,load,save)								\
137 	lf_var1d=load(op1);lf_var2d=op2;					\
138 	lf_resd=lf_var1d+lf_var2d;					\
139 	save(op1,lf_resd);								\
140 	lflags.type=t_ADDd;
141 
142 #define ADCD(op1,op2,load,save)								\
143 	lflags.oldcf=get_CF()!=0;									\
144 	lf_var1d=load(op1);lf_var2d=op2;					\
145 	lf_resd=lf_var1d+lf_var2d+lflags.oldcf;		\
146 	save(op1,lf_resd);								\
147 	lflags.type=t_ADCd;
148 
149 #define SBBD(op1,op2,load,save)								\
150 	lflags.oldcf=get_CF()!=0;									\
151 	lf_var1d=load(op1);lf_var2d=op2;					\
152 	lf_resd=lf_var1d-(lf_var2d+lflags.oldcf);	\
153 	save(op1,lf_resd);								\
154 	lflags.type=t_SBBd;
155 
156 #define SUBD(op1,op2,load,save)								\
157 	lf_var1d=load(op1);lf_var2d=op2;					\
158 	lf_resd=lf_var1d-lf_var2d;					\
159 	save(op1,lf_resd);								\
160 	lflags.type=t_SUBd;
161 
162 #define ORD(op1,op2,load,save)								\
163 	lf_var1d=load(op1);lf_var2d=op2;					\
164 	lf_resd=lf_var1d | lf_var2d;				\
165 	save(op1,lf_resd);								\
166 	lflags.type=t_ORd;
167 
168 #define XORD(op1,op2,load,save)								\
169 	lf_var1d=load(op1);lf_var2d=op2;					\
170 	lf_resd=lf_var1d ^ lf_var2d;				\
171 	save(op1,lf_resd);								\
172 	lflags.type=t_XORd;
173 
174 #define ANDD(op1,op2,load,save)								\
175 	lf_var1d=load(op1);lf_var2d=op2;					\
176 	lf_resd=lf_var1d & lf_var2d;				\
177 	save(op1,lf_resd);								\
178 	lflags.type=t_ANDd;
179 
180 #define CMPD(op1,op2,load,save)								\
181 	lf_var1d=load(op1);lf_var2d=op2;					\
182 	lf_resd=lf_var1d-lf_var2d;					\
183 	lflags.type=t_CMPd;
184 
185 
186 #define TESTD(op1,op2,load,save)							\
187 	lf_var1d=load(op1);lf_var2d=op2;					\
188 	lf_resd=lf_var1d & lf_var2d;				\
189 	lflags.type=t_TESTd;
190 
191 
192 
193 
194 #define INCB(op1,load,save)									\
195 	LoadCF;lf_var1b=load(op1);								\
196 	lf_resb=lf_var1b+1;										\
197 	save(op1,lf_resb);										\
198 	lflags.type=t_INCb;										\
199 
200 #define INCW(op1,load,save)									\
201 	LoadCF;lf_var1w=load(op1);								\
202 	lf_resw=lf_var1w+1;										\
203 	save(op1,lf_resw);										\
204 	lflags.type=t_INCw;
205 
206 #define INCD(op1,load,save)									\
207 	LoadCF;lf_var1d=load(op1);								\
208 	lf_resd=lf_var1d+1;										\
209 	save(op1,lf_resd);										\
210 	lflags.type=t_INCd;
211 
212 #define DECB(op1,load,save)									\
213 	LoadCF;lf_var1b=load(op1);								\
214 	lf_resb=lf_var1b-1;										\
215 	save(op1,lf_resb);										\
216 	lflags.type=t_DECb;
217 
218 #define DECW(op1,load,save)									\
219 	LoadCF;lf_var1w=load(op1);								\
220 	lf_resw=lf_var1w-1;										\
221 	save(op1,lf_resw);										\
222 	lflags.type=t_DECw;
223 
224 #define DECD(op1,load,save)									\
225 	LoadCF;lf_var1d=load(op1);								\
226 	lf_resd=lf_var1d-1;										\
227 	save(op1,lf_resd);										\
228 	lflags.type=t_DECd;
229 
230 
231 
232 #define ROLB(op1,op2,load,save)						\
233 	FillFlagsNoCFOF();								\
234 	lf_var1b=load(op1);								\
235 	lf_var2b=op2&0x07;								\
236 	lf_resb=(lf_var1b << lf_var2b) |				\
237 			(lf_var1b >> (8-lf_var2b));				\
238 	save(op1,lf_resb);								\
239 	SETFLAGBIT(CF,lf_resb & 1);						\
240 	SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7));
241 
242 #define ROLW(op1,op2,load,save)						\
243 	FillFlagsNoCFOF();								\
244 	lf_var1w=load(op1);								\
245 	lf_var2b=op2&0xf;								\
246 	lf_resw=(lf_var1w << lf_var2b) |				\
247 			(lf_var1w >> (16-lf_var2b));			\
248 	save(op1,lf_resw);								\
249 	SETFLAGBIT(CF,lf_resw & 1);						\
250 	SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15));
251 
252 #define ROLD(op1,op2,load,save)						\
253 	FillFlagsNoCFOF();								\
254 	lf_var1d=load(op1);								\
255 	lf_var2b=op2;									\
256 	lf_resd=(lf_var1d << lf_var2b) |				\
257 			(lf_var1d >> (32-lf_var2b));			\
258 	save(op1,lf_resd);								\
259 	SETFLAGBIT(CF,lf_resd & 1);						\
260 	SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31));
261 
262 
263 #define RORB(op1,op2,load,save)						\
264 	FillFlagsNoCFOF();								\
265 	lf_var1b=load(op1);								\
266 	lf_var2b=op2&0x07;								\
267 	lf_resb=(lf_var1b >> lf_var2b) |				\
268 			(lf_var1b << (8-lf_var2b));				\
269 	save(op1,lf_resb);								\
270 	SETFLAGBIT(CF,lf_resb & 0x80);					\
271 	SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80);
272 
273 #define RORW(op1,op2,load,save)					\
274 	FillFlagsNoCFOF();							\
275 	lf_var1w=load(op1);							\
276 	lf_var2b=op2&0xf;							\
277 	lf_resw=(lf_var1w >> lf_var2b) |			\
278 			(lf_var1w << (16-lf_var2b));		\
279 	save(op1,lf_resw);							\
280 	SETFLAGBIT(CF,lf_resw & 0x8000);			\
281 	SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000);
282 
283 #define RORD(op1,op2,load,save)					\
284 	FillFlagsNoCFOF();							\
285 	lf_var1d=load(op1);							\
286 	lf_var2b=op2;								\
287 	lf_resd=(lf_var1d >> lf_var2b) |			\
288 			(lf_var1d << (32-lf_var2b));		\
289 	save(op1,lf_resd);							\
290 	SETFLAGBIT(CF,lf_resd & 0x80000000);		\
291 	SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000);
292 
293 
294 #define RCLB(op1,op2,load,save)							\
295 	if (!(op2%9)) break;								\
296 {	Bit8u cf=(Bit8u)FillFlags()&0x1;					\
297 	lf_var1b=load(op1);									\
298 	lf_var2b=op2%9;										\
299 	lf_resb=(lf_var1b << lf_var2b) |					\
300 			(cf << (lf_var2b-1)) |						\
301 			(lf_var1b >> (9-lf_var2b));					\
302  	save(op1,lf_resb);									\
303 	SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1));	\
304 	SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7));	\
305 }
306 
307 #define RCLW(op1,op2,load,save)							\
308 	if (!(op2%17)) break;								\
309 {	Bit16u cf=(Bit16u)FillFlags()&0x1;					\
310 	lf_var1w=load(op1);									\
311 	lf_var2b=op2%17;									\
312 	lf_resw=(lf_var1w << lf_var2b) |					\
313 			(cf << (lf_var2b-1)) |						\
314 			(lf_var1w >> (17-lf_var2b));				\
315 	save(op1,lf_resw);									\
316 	SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1));	\
317 	SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15));	\
318 }
319 
320 #define RCLD(op1, op2, load, save) \
321 	if (!op2) \
322 		break; \
323 	{ \
324 		const uint32_t cf = FillFlags() & 0x1; \
325 		lf_var1d = load(op1); \
326 		lf_var2b = op2; \
327 		if (lf_var2b == 1) { \
328 			lf_resd = (lf_var1d << 1) | cf; \
329 		} else { \
330 			lf_resd = (lf_var1d << lf_var2b) | \
331 			          (cf << lf_var2b_minus_one()) | \
332 			          (lf_var1d >> (33 - lf_var2b)); \
333 		} \
334 		save(op1, lf_resd); \
335 		SETFLAGBIT(CF, ((lf_var1d >> (32 - lf_var2b)) & 1)); \
336 		SETFLAGBIT(OF, (reg_flags & 1) ^ (lf_resd >> 31)); \
337 	}
338 
339 #define RCRB(op1, op2, load, save) \
340 	if (op2 % 9) { \
341 		Bit8u cf = (Bit8u)FillFlags() & 0x1; \
342 		lf_var1b = load(op1); \
343 		lf_var2b = op2 % 9; \
344 		lf_resb = (lf_var1b >> lf_var2b) | (cf << (8 - lf_var2b)) | \
345 		          (lf_var1b << (9 - lf_var2b)); \
346 		save(op1, lf_resb); \
347 		SETFLAGBIT(CF, (lf_var1b >> lf_var2b_minus_one()) & 1); \
348 		SETFLAGBIT(OF, (lf_resb ^ (lf_resb << 1)) & 0x80); \
349 	}
350 
351 #define RCRW(op1, op2, load, save) \
352 	if (op2 % 17) { \
353 		Bit16u cf = (Bit16u)FillFlags() & 0x1; \
354 		lf_var1w = load(op1); \
355 		lf_var2b = op2 % 17; \
356 		lf_resw = (lf_var1w >> lf_var2b) | (cf << (16 - lf_var2b)) | \
357 		          (lf_var1w << (17 - lf_var2b)); \
358 		save(op1, lf_resw); \
359 		SETFLAGBIT(CF, (lf_var1w >> lf_var2b_minus_one()) & 1); \
360 		SETFLAGBIT(OF, (lf_resw ^ (lf_resw << 1)) & 0x8000); \
361 	}
362 
363 #define RCRD(op1, op2, load, save) \
364 	if (op2) { \
365 		const uint32_t cf = FillFlags() & 0x1; \
366 		lf_var1d = load(op1); \
367 		lf_var2b = op2; \
368 		if (lf_var2b == 1) { \
369 			lf_resd = lf_var1d >> 1 | cf << 31; \
370 		} else { \
371 			lf_resd = (lf_var1d >> lf_var2b) | \
372 			          (cf << (32 - lf_var2b)) | \
373 			          (lf_var1d << (33 - lf_var2b)); \
374 		} \
375 		save(op1, lf_resd); \
376 		SETFLAGBIT(CF, (lf_var1d >> lf_var2b_minus_one()) & 1); \
377 		SETFLAGBIT(OF, (lf_resd ^ (lf_resd << 1)) & 0x80000000); \
378 	}
379 
380 #define SHLB(op1,op2,load,save)								\
381 	lf_var1b=load(op1);lf_var2b=op2;				\
382 	lf_resb=lf_var1b << lf_var2b;			\
383 	save(op1,lf_resb);								\
384 	lflags.type=t_SHLb;
385 
386 #define SHLW(op1,op2,load,save)								\
387 	lf_var1w=load(op1);lf_var2b=op2 ;				\
388 	lf_resw=lf_var1w << lf_var2b;			\
389 	save(op1,lf_resw);								\
390 	lflags.type=t_SHLw;
391 
392 #define SHLD(op1,op2,load,save)								\
393 	lf_var1d=load(op1);lf_var2b=op2;				\
394 	lf_resd=lf_var1d << lf_var2b;			\
395 	save(op1,lf_resd);								\
396 	lflags.type=t_SHLd;
397 
398 
399 #define SHRB(op1,op2,load,save)								\
400 	lf_var1b=load(op1);lf_var2b=op2;				\
401 	lf_resb=lf_var1b >> lf_var2b;			\
402 	save(op1,lf_resb);								\
403 	lflags.type=t_SHRb;
404 
405 #define SHRW(op1,op2,load,save)								\
406 	lf_var1w=load(op1);lf_var2b=op2;				\
407 	lf_resw=lf_var1w >> lf_var2b;			\
408 	save(op1,lf_resw);								\
409 	lflags.type=t_SHRw;
410 
411 #define SHRD(op1,op2,load,save)								\
412 	lf_var1d=load(op1);lf_var2b=op2;				\
413 	lf_resd=lf_var1d >> lf_var2b;			\
414 	save(op1,lf_resd);								\
415 	lflags.type=t_SHRd;
416 
417 
418 #define SARB(op1,op2,load,save)								\
419 	lf_var1b=load(op1);lf_var2b=op2;				\
420 	if (lf_var2b>8) lf_var2b=8;						\
421     if (lf_var1b & 0x80) {								\
422 		lf_resb=(lf_var1b >> lf_var2b)|		\
423 		(0xff << (8 - lf_var2b));						\
424 	} else {												\
425 		lf_resb=lf_var1b >> lf_var2b;		\
426     }														\
427 	save(op1,lf_resb);								\
428 	lflags.type=t_SARb;
429 
430 #define SARW(op1,op2,load,save)								\
431 	lf_var1w=load(op1);lf_var2b=op2;			\
432 	if (lf_var2b>16) lf_var2b=16;					\
433 	if (lf_var1w & 0x8000) {							\
434 		lf_resw=(lf_var1w >> lf_var2b)|		\
435 		(0xffff << (16 - lf_var2b));					\
436 	} else {												\
437 		lf_resw=lf_var1w >> lf_var2b;		\
438     }														\
439 	save(op1,lf_resw);								\
440 	lflags.type=t_SARw;
441 
442 #define SARD(op1,op2,load,save)								\
443 	lf_var2b=op2;lf_var1d=load(op1);			\
444 	if (lf_var1d & 0x80000000) {						\
445 		lf_resd=(lf_var1d >> lf_var2b)|		\
446 		(0xffffffff << (32 - lf_var2b));				\
447 	} else {												\
448 		lf_resd=lf_var1d >> lf_var2b;		\
449     }														\
450 	save(op1,lf_resd);								\
451 	lflags.type=t_SARd;
452 
453 
454 
455 #define DAA()												\
456 	if (((reg_al & 0x0F)>0x09) || get_AF()) {				\
457 		if ((reg_al > 0x99) || get_CF()) {					\
458 			reg_al+=0x60;									\
459 			SETFLAGBIT(CF,true);							\
460 		} else {											\
461 			SETFLAGBIT(CF,false);							\
462 		}													\
463 		reg_al+=0x06;										\
464 		SETFLAGBIT(AF,true);								\
465 	} else {												\
466 		if ((reg_al > 0x99) || get_CF()) {					\
467 			reg_al+=0x60;									\
468 			SETFLAGBIT(CF,true);							\
469 		} else {											\
470 			SETFLAGBIT(CF,false);							\
471 		}													\
472 		SETFLAGBIT(AF,false);								\
473 	}														\
474 	SETFLAGBIT(SF,(reg_al&0x80));							\
475 	SETFLAGBIT(ZF,(reg_al==0));								\
476 	SETFLAGBIT(PF,parity_lookup[reg_al]);					\
477 	lflags.type=t_UNKNOWN;
478 
479 
480 #define DAS()												\
481 {															\
482 	Bit8u osigned=reg_al & 0x80;							\
483 	if (((reg_al & 0x0f) > 9) || get_AF()) {				\
484 		if ((reg_al>0x99) || get_CF()) {					\
485 			reg_al-=0x60;									\
486 			SETFLAGBIT(CF,true);							\
487 		} else {											\
488 			SETFLAGBIT(CF,(reg_al<=0x05));					\
489 		}													\
490 		reg_al-=6;											\
491 		SETFLAGBIT(AF,true);								\
492 	} else {												\
493 		if ((reg_al>0x99) || get_CF()) {					\
494 			reg_al-=0x60;									\
495 			SETFLAGBIT(CF,true);							\
496 		} else {											\
497 			SETFLAGBIT(CF,false);							\
498 		}													\
499 		SETFLAGBIT(AF,false);								\
500 	}														\
501 	SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0));			\
502 	SETFLAGBIT(SF,(reg_al&0x80));							\
503 	SETFLAGBIT(ZF,(reg_al==0));								\
504 	SETFLAGBIT(PF,parity_lookup[reg_al]);					\
505 	lflags.type=t_UNKNOWN;									\
506 }
507 
508 
509 #define AAA()												\
510 	SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9)));		\
511 	if ((reg_al & 0xf) > 9) {								\
512 		SETFLAGBIT(OF,(reg_al&0xf0)==0x70);					\
513 		reg_ax += 0x106;									\
514 		SETFLAGBIT(CF,true);								\
515 		SETFLAGBIT(ZF,(reg_al == 0));						\
516 		SETFLAGBIT(AF,true);								\
517 	} else if (get_AF()) {									\
518 		reg_ax += 0x106;									\
519 		SETFLAGBIT(OF,false);								\
520 		SETFLAGBIT(CF,true);								\
521 		SETFLAGBIT(ZF,false);								\
522 		SETFLAGBIT(AF,true);								\
523 	} else {												\
524 		SETFLAGBIT(OF,false);								\
525 		SETFLAGBIT(CF,false);								\
526 		SETFLAGBIT(ZF,(reg_al == 0));						\
527 		SETFLAGBIT(AF,false);								\
528 	}														\
529 	SETFLAGBIT(PF,parity_lookup[reg_al]);					\
530 	reg_al &= 0x0F;											\
531 	lflags.type=t_UNKNOWN;
532 
533 #define AAS()												\
534 	if ((reg_al & 0x0f)>9) {								\
535 		SETFLAGBIT(SF,(reg_al>0x85));						\
536 		reg_ax -= 0x106;									\
537 		SETFLAGBIT(OF,false);								\
538 		SETFLAGBIT(CF,true);								\
539 		SETFLAGBIT(AF,true);								\
540 	} else if (get_AF()) {									\
541 		SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85)));	\
542 		SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85));		\
543 		reg_ax -= 0x106;									\
544 		SETFLAGBIT(CF,true);								\
545 		SETFLAGBIT(AF,true);								\
546 	} else {												\
547 		SETFLAGBIT(SF,(reg_al>=0x80));						\
548 		SETFLAGBIT(OF,false);								\
549 		SETFLAGBIT(CF,false);								\
550 		SETFLAGBIT(AF,false);								\
551 	}														\
552 	SETFLAGBIT(ZF,(reg_al == 0));							\
553 	SETFLAGBIT(PF,parity_lookup[reg_al]);					\
554 	reg_al &= 0x0F;											\
555 	lflags.type=t_UNKNOWN;
556 
557 #define AAM(op1)											\
558 {															\
559 	Bit8u dv=op1;											\
560 	if (dv!=0) {											\
561 		reg_ah=reg_al / dv;									\
562 		reg_al=reg_al % dv;									\
563 		SETFLAGBIT(SF,(reg_al & 0x80));						\
564 		SETFLAGBIT(ZF,(reg_al == 0));						\
565 		SETFLAGBIT(PF,parity_lookup[reg_al]);				\
566 		SETFLAGBIT(CF,false);								\
567 		SETFLAGBIT(OF,false);								\
568 		SETFLAGBIT(AF,false);								\
569 		lflags.type=t_UNKNOWN;								\
570 	} else EXCEPTION(0);									\
571 }
572 
573 
574 //Took this from bochs, i seriously hate these weird bcd opcodes
575 #define AAD(op1)											\
576 	{														\
577 		Bit16u ax1 = reg_ah * op1;							\
578 		Bit16u ax2 = ax1 + reg_al;							\
579 		reg_al = (Bit8u) ax2;								\
580 		reg_ah = 0;											\
581 		SETFLAGBIT(CF,false);								\
582 		SETFLAGBIT(OF,false);								\
583 		SETFLAGBIT(AF,false);								\
584 		SETFLAGBIT(SF,reg_al >= 0x80);						\
585 		SETFLAGBIT(ZF,reg_al == 0);							\
586 		SETFLAGBIT(PF,parity_lookup[reg_al]);				\
587 		lflags.type=t_UNKNOWN;								\
588 	}
589 
590 #define MULB(op1,load,save)									\
591 	reg_ax=reg_al*load(op1);								\
592 	FillFlagsNoCFOF();										\
593 	SETFLAGBIT(ZF,reg_al == 0);								\
594 	if (reg_ax & 0xff00) {									\
595 		SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);			\
596 	} else {												\
597 		SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);			\
598 	}
599 
600 #define MULW(op1, load, save) \
601 	{ \
602 		const uint32_t res = static_cast<uint32_t>(reg_ax) * \
603 		                     static_cast<uint32_t>(load(op1)); \
604 		reg_ax = static_cast<uint16_t>(res); \
605 		reg_dx = static_cast<uint16_t>(res >> 16); \
606 		FillFlagsNoCFOF(); \
607 		SETFLAGBIT(ZF, reg_ax == 0); \
608 		if (reg_dx) { \
609 			SETFLAGBIT(CF, true); \
610 			SETFLAGBIT(OF, true); \
611 		} else { \
612 			SETFLAGBIT(CF, false); \
613 			SETFLAGBIT(OF, false); \
614 		} \
615 	}
616 
617 #define MULD(op1, load, save) \
618 	{ \
619 		const uint64_t res = static_cast<uint64_t>(reg_eax) * \
620 		                     static_cast<uint64_t>(load(op1)); \
621 		reg_eax = static_cast<uint32_t>(res); \
622 		reg_edx = static_cast<uint32_t>(res >> 32); \
623 		FillFlagsNoCFOF(); \
624 		SETFLAGBIT(ZF, reg_eax == 0); \
625 		if (reg_edx) { \
626 			SETFLAGBIT(CF, true); \
627 			SETFLAGBIT(OF, true); \
628 		} else { \
629 			SETFLAGBIT(CF, false); \
630 			SETFLAGBIT(OF, false); \
631 		} \
632 	}
633 
634 #define DIVB(op1,load,save)									\
635 {															\
636 	Bitu val=load(op1);										\
637 	if (val==0)	EXCEPTION(0);								\
638 	Bitu quo=reg_ax / val;									\
639 	Bit8u rem=(Bit8u)(reg_ax % val);						\
640 	Bit8u quo8=(Bit8u)(quo&0xff);							\
641 	if (quo>0xff) EXCEPTION(0);								\
642 	reg_ah=rem;												\
643 	reg_al=quo8;											\
644 	SETFLAGBIT(OF,false);									\
645 }
646 
647 
648 #define DIVW(op1,load,save)									\
649 {															\
650 	Bitu val=load(op1);										\
651 	if (val==0)	EXCEPTION(0);								\
652 	Bitu num=((Bit32u)reg_dx<<16)|reg_ax;							\
653 	Bitu quo=num/val;										\
654 	Bit16u rem=(Bit16u)(num % val);							\
655 	Bit16u quo16=(Bit16u)(quo&0xffff);						\
656 	if (quo!=(Bit32u)quo16) EXCEPTION(0);					\
657 	reg_dx=rem;												\
658 	reg_ax=quo16;											\
659 	SETFLAGBIT(OF,false);									\
660 }
661 
662 #define DIVD(op1,load,save)									\
663 {															\
664 	Bitu val=load(op1);										\
665 	if (val==0) EXCEPTION(0);									\
666 	Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;				\
667 	Bit64u quo=num/val;										\
668 	Bit32u rem=(Bit32u)(num % val);							\
669 	Bit32u quo32=(Bit32u)(quo&0xffffffff);					\
670 	if (quo!=(Bit64u)quo32) EXCEPTION(0);					\
671 	reg_edx=rem;											\
672 	reg_eax=quo32;											\
673 	SETFLAGBIT(OF,false);									\
674 }
675 
676 
677 #define IDIVB(op1,load,save)								\
678 {															\
679 	Bits val=(Bit8s)(load(op1));							\
680 	if (val==0)	EXCEPTION(0);								\
681 	Bits quo=((Bit16s)reg_ax) / val;						\
682 	Bit8s rem=(Bit8s)((Bit16s)reg_ax % val);				\
683 	Bit8s quo8s=(Bit8s)(quo&0xff);							\
684 	if (quo!=(Bit16s)quo8s) EXCEPTION(0);					\
685 	reg_ah=rem;												\
686 	reg_al=quo8s;											\
687 	SETFLAGBIT(OF,false);									\
688 }
689 
690 #define IDIVW(op1, load, save) \
691 	{ \
692 		const auto val = static_cast<int16_t>(load(op1)); \
693 		if (val == 0) \
694 			EXCEPTION(0); \
695 		const auto num = (reg_dx << 16) | reg_ax; \
696 		const auto quo = num / val; \
697 		const auto rem = num % val; \
698 		const auto quo16s = static_cast<int16_t>(quo); \
699 		if (quo != quo16s) \
700 			EXCEPTION(0); \
701 		reg_ax = quo16s; \
702 		reg_dx = static_cast<int16_t>(rem); \
703 		SETFLAGBIT(OF, false); \
704 	}
705 
706 #define IDIVD(op1,load,save)								\
707 {															\
708 	Bits val=(Bit32s)(load(op1));							\
709 	if (val==0) EXCEPTION(0);									\
710 	Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;				\
711 	Bit64s quo=num/val;										\
712 	Bit32s rem=(Bit32s)(num % val);							\
713 	Bit32s quo32s=(Bit32s)(quo&0xffffffff);					\
714 	if (quo!=(Bit64s)quo32s) EXCEPTION(0);					\
715 	reg_edx=rem;											\
716 	reg_eax=quo32s;											\
717 	SETFLAGBIT(OF,false);									\
718 }
719 
720 #define IMULB(op1,load,save)								\
721 {															\
722 	reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1)));			\
723 	FillFlagsNoCFOF();										\
724 	SETFLAGBIT(ZF,reg_al == 0);								\
725 	SETFLAGBIT(SF,reg_al & 0x80);							\
726 	if ((reg_ax & 0xff80)==0xff80 ||						\
727 		(reg_ax & 0xff80)==0x0000) {						\
728 		SETFLAGBIT(CF,false);SETFLAGBIT(OF,false);			\
729 	} else {												\
730 		SETFLAGBIT(CF,true);SETFLAGBIT(OF,true);			\
731 	}														\
732 }
733 
734 #define IMULW(op1, load, save) \
735 	{ \
736 		const auto res = static_cast<int16_t>(reg_ax) * \
737 		                 static_cast<int16_t>(load(op1)); \
738 		reg_ax = static_cast<int16_t>(res); \
739 		reg_dx = static_cast<int16_t>(res >> 16); \
740 		FillFlagsNoCFOF(); \
741 		SETFLAGBIT(ZF, reg_ax == 0); \
742 		SETFLAGBIT(SF, reg_ax & 0x8000); \
743 		if (((res & 0xffff8000) == 0xffff8000 || \
744 		     (res & 0xffff8000) == 0x0000)) { \
745 			SETFLAGBIT(CF, false); \
746 			SETFLAGBIT(OF, false); \
747 		} else { \
748 			SETFLAGBIT(CF, true); \
749 			SETFLAGBIT(OF, true); \
750 		} \
751 	}
752 
753 #define IMULD(op1, load, save) \
754 	{ \
755 		Bit64s temps = ((Bit64s)((Bit32s)reg_eax)) * \
756 		               ((Bit64s)((Bit32s)(load(op1)))); \
757 		reg_eax = (Bit32s)(temps); \
758 		reg_edx = (Bit32s)(temps >> 32); \
759 		FillFlagsNoCFOF(); \
760 		SETFLAGBIT(ZF, reg_eax == 0); \
761 		SETFLAGBIT(SF, reg_eax & 0x80000000); \
762 		if ((reg_edx == 0xffffffff) && (reg_eax & 0x80000000)) { \
763 			SETFLAGBIT(CF, false); \
764 			SETFLAGBIT(OF, false); \
765 		} else if ((reg_edx == 0x00000000) && (reg_eax < 0x80000000)) { \
766 			SETFLAGBIT(CF, false); \
767 			SETFLAGBIT(OF, false); \
768 		} else { \
769 			SETFLAGBIT(CF, true); \
770 			SETFLAGBIT(OF, true); \
771 		} \
772 	}
773 
774 #define DIMULW(op1, op2, op3, load, save) \
775 	{ \
776 		const auto res = op2 * op3; \
777 		save(op1, res & 0xffff); \
778 		FillFlagsNoCFOF(); \
779 		if ((res >= -32768) && (res <= 32767)) { \
780 			SETFLAGBIT(CF, false); \
781 			SETFLAGBIT(OF, false); \
782 		} else { \
783 			SETFLAGBIT(CF, true); \
784 			SETFLAGBIT(OF, true); \
785 		} \
786 	}
787 
788 #define DIMULD(op1, op2, op3, load, save) \
789 	{ \
790 		const auto res = static_cast<int64_t>(op2) * \
791 		                 static_cast<int64_t>(op3); \
792 		save(op1, (Bit32s)res); \
793 		FillFlagsNoCFOF(); \
794 		if ((res >= -((Bit64s)(2147483647) + 1)) && \
795 		    (res <= (Bit64s)2147483647)) { \
796 			SETFLAGBIT(CF, false); \
797 			SETFLAGBIT(OF, false); \
798 		} else { \
799 			SETFLAGBIT(CF, true); \
800 			SETFLAGBIT(OF, true); \
801 		} \
802 	}
803 
804 #define GRP2B(blah)											\
805 {															\
806 	GetRM;Bitu which=(rm>>3)&7;								\
807 	if (rm >= 0xc0) {										\
808 		GetEArb;											\
809 		Bit8u val=blah & 0x1f;								\
810 		if (!val) break;									\
811 		switch (which)	{									\
812 		case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break;		\
813 		case 0x01:RORB(*earb,val,LoadRb,SaveRb);break;		\
814 		case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break;		\
815 		case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break;		\
816 		case 0x04:/* SHL and SAL are the same */			\
817 		case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break;		\
818 		case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break;		\
819 		case 0x07:SARB(*earb,val,LoadRb,SaveRb);break;		\
820 		}													\
821 	} else {												\
822 		GetEAa;												\
823 		Bit8u val=blah & 0x1f;								\
824 		if (!val) break;									\
825 		switch (which) {									\
826 		case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break;		\
827 		case 0x01:RORB(eaa,val,LoadMb,SaveMb);break;		\
828 		case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break;		\
829 		case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break;		\
830 		case 0x04:/* SHL and SAL are the same */			\
831 		case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break;		\
832 		case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break;		\
833 		case 0x07:SARB(eaa,val,LoadMb,SaveMb);break;		\
834 		}													\
835 	}														\
836 }
837 
838 
839 
840 #define GRP2W(blah)											\
841 {															\
842 	GetRM;Bitu which=(rm>>3)&7;								\
843 	if (rm >= 0xc0) {										\
844 		GetEArw;											\
845 		Bit8u val=blah & 0x1f;								\
846 		if (!val) break;									\
847 		switch (which)	{									\
848 		case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break;		\
849 		case 0x01:RORW(*earw,val,LoadRw,SaveRw);break;		\
850 		case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break;		\
851 		case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break;		\
852 		case 0x04:/* SHL and SAL are the same */			\
853 		case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break;		\
854 		case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break;		\
855 		case 0x07:SARW(*earw,val,LoadRw,SaveRw);break;		\
856 		}													\
857 	} else {												\
858 		GetEAa;												\
859 		Bit8u val=blah & 0x1f;								\
860 		if (!val) break;									\
861 		switch (which) {									\
862 		case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break;		\
863 		case 0x01:RORW(eaa,val,LoadMw,SaveMw);break;		\
864 		case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break;		\
865 		case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break;		\
866 		case 0x04:/* SHL and SAL are the same */			\
867 		case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break;		\
868 		case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break;		\
869 		case 0x07:SARW(eaa,val,LoadMw,SaveMw);break;		\
870 		}													\
871 	}														\
872 }
873 
874 
875 #define GRP2D(blah)											\
876 {															\
877 	GetRM;Bitu which=(rm>>3)&7;								\
878 	if (rm >= 0xc0) {										\
879 		GetEArd;											\
880 		Bit8u val=blah & 0x1f;								\
881 		if (!val) break;									\
882 		switch (which)	{									\
883 		case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break;		\
884 		case 0x01:RORD(*eard,val,LoadRd,SaveRd);break;		\
885 		case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break;		\
886 		case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break;		\
887 		case 0x04:/* SHL and SAL are the same */			\
888 		case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break;		\
889 		case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break;		\
890 		case 0x07:SARD(*eard,val,LoadRd,SaveRd);break;		\
891 		}													\
892 	} else {												\
893 		GetEAa;												\
894 		Bit8u val=blah & 0x1f;								\
895 		if (!val) break;									\
896 		switch (which) {									\
897 		case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break;		\
898 		case 0x01:RORD(eaa,val,LoadMd,SaveMd);break;		\
899 		case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break;		\
900 		case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break;		\
901 		case 0x04:/* SHL and SAL are the same */			\
902 		case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break;		\
903 		case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break;		\
904 		case 0x07:SARD(eaa,val,LoadMd,SaveMd);break;		\
905 		}													\
906 	}														\
907 }
908 
909 /* let's hope bochs has it correct with the higher than 16 shifts */
910 /* double-precision shift left has low bits in second argument */
911 #define DSHLW(op1,op2,op3,load,save)									\
912 	Bit8u val=op3 & 0x1F;												\
913 	if (!val) break;													\
914 	lf_var2b=val;lf_var1d=(load(op1)<<16)|op2;					\
915 	Bit32u tempd=lf_var1d << lf_var2b;							\
916   	if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16));			\
917 	lf_resw=(Bit16u)(tempd >> 16);								\
918 	save(op1,lf_resw);											\
919 	lflags.type=t_DSHLw;
920 
921 #define DSHLD(op1,op2,op3,load,save)									\
922 	Bit8u val=op3 & 0x1F;												\
923 	if (!val) break;													\
924 	lf_var2b=val;lf_var1d=load(op1);							\
925 	lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b));	\
926 	save(op1,lf_resd);											\
927 	lflags.type=t_DSHLd;
928 
929 /* double-precision shift right has high bits in second argument */
930 #define DSHRW(op1,op2,op3,load,save)									\
931 	Bit8u val=op3 & 0x1F;												\
932 	if (!val) break;													\
933 	lf_var2b=val;lf_var1d=(op2<<16)|load(op1);					\
934 	Bit32u tempd=lf_var1d >> lf_var2b;							\
935   	if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b ));			\
936 	lf_resw=(Bit16u)(tempd);										\
937 	save(op1,lf_resw);											\
938 	lflags.type=t_DSHRw;
939 
940 #define DSHRD(op1,op2,op3,load,save)									\
941 	Bit8u val=op3 & 0x1F;												\
942 	if (!val) break;													\
943 	lf_var2b=val;lf_var1d=load(op1);							\
944 	lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b));	\
945 	save(op1,lf_resd);											\
946 	lflags.type=t_DSHRd;
947 
948 #define BSWAPW(op1)														\
949 	op1 = 0;
950 
951 #define BSWAPD(op1)														\
952 	op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);
953