1/****************************************************************************
2*
3*						Realmode X86 Emulator Library
4*
5*            	Copyright (C) 1996-1999 SciTech Software, Inc.
6* 				     Copyright (C) David Mosberger-Tang
7* 					   Copyright (C) 1999 Egbert Eich
8*
9*  ========================================================================
10*
11*  Permission to use, copy, modify, distribute, and sell this software and
12*  its documentation for any purpose is hereby granted without fee,
13*  provided that the above copyright notice appear in all copies and that
14*  both that copyright notice and this permission notice appear in
15*  supporting documentation, and that the name of the authors not be used
16*  in advertising or publicity pertaining to distribution of the software
17*  without specific, written prior permission.  The authors makes no
18*  representations about the suitability of this software for any purpose.
19*  It is provided "as is" without express or implied warranty.
20*
21*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27*  PERFORMANCE OF THIS SOFTWARE.
28*
29*  ========================================================================
30*
31* Language:		ANSI C
32* Environment:	Any
33* Developer:    Kendall Bennett
34*
35* Description:  This file contains the code to implement the primitive
36*				machine operations used by the emulation code in ops.c
37*
38* Carry Chain Calculation
39*
40* This represents a somewhat expensive calculation which is
41* apparently required to emulate the setting of the OF and AF flag.
42* The latter is not so important, but the former is.  The overflow
43* flag is the XOR of the top two bits of the carry chain for an
44* addition (similar for subtraction).  Since we do not want to
45* simulate the addition in a bitwise manner, we try to calculate the
46* carry chain given the two operands and the result.
47*
48* So, given the following table, which represents the addition of two
49* bits, we can derive a formula for the carry chain.
50*
51* a   b   cin   r     cout
52* 0   0   0     0     0
53* 0   0   1     1     0
54* 0   1   0     1     0
55* 0   1   1     0     1
56* 1   0   0     1     0
57* 1   0   1     0     1
58* 1   1   0     0     1
59* 1   1   1     1     1
60*
61* Construction of table for cout:
62*
63* ab
64* r  \  00   01   11  10
65* |------------------
66* 0  |   0    1    1   1
67* 1  |   0    0    1   0
68*
69* By inspection, one gets:  cc = ab +  r'(a + b)
70*
71* That represents alot of operations, but NO CHOICE....
72*
73* Borrow Chain Calculation.
74*
75* The following table represents the subtraction of two bits, from
76* which we can derive a formula for the borrow chain.
77*
78* a   b   bin   r     bout
79* 0   0   0     0     0
80* 0   0   1     1     1
81* 0   1   0     1     1
82* 0   1   1     0     1
83* 1   0   0     1     0
84* 1   0   1     0     0
85* 1   1   0     0     0
86* 1   1   1     1     1
87*
88* Construction of table for cout:
89*
90* ab
91* r  \  00   01   11  10
92* |------------------
93* 0  |   0    1    0   0
94* 1  |   1    1    1   0
95*
96* By inspection, one gets:  bc = a'b +  r(a' + b)
97*
98****************************************************************************/
99
100#define	PRIM_OPS_NO_REDEFINE_ASM
101#include "x86emu/x86emui.h"
102
103/*------------------------- Global Variables ------------------------------*/
104
105#ifndef	__HAVE_INLINE_ASSEMBLER__
106
107static u32 x86emu_parity_tab[8] =
108{
109	0x96696996,
110	0x69969669,
111	0x69969669,
112	0x96696996,
113	0x69969669,
114	0x96696996,
115	0x96696996,
116	0x69969669,
117};
118
119#endif
120
121#define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
122#define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)
123
124/*----------------------------- Implementation ----------------------------*/
125
126#ifndef	__HAVE_INLINE_ASSEMBLER__
127
128/****************************************************************************
129REMARKS:
130Implements the AAA instruction and side effects.
131****************************************************************************/
132u16 aaa_word(u16 d)
133{
134	u16	res;
135	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
136		d += 0x6;
137		d += 0x100;
138		SET_FLAG(F_AF);
139		SET_FLAG(F_CF);
140	} else {
141		CLEAR_FLAG(F_CF);
142		CLEAR_FLAG(F_AF);
143	}
144	res = (u16)(d & 0xFF0F);
145	CLEAR_FLAG(F_SF);
146	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
147	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
148	return res;
149}
150
151/****************************************************************************
152REMARKS:
153Implements the AAA instruction and side effects.
154****************************************************************************/
155u16 aas_word(u16 d)
156{
157	u16	res;
158	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
159		d -= 0x6;
160		d -= 0x100;
161		SET_FLAG(F_AF);
162		SET_FLAG(F_CF);
163	} else {
164		CLEAR_FLAG(F_CF);
165		CLEAR_FLAG(F_AF);
166	}
167	res = (u16)(d & 0xFF0F);
168	CLEAR_FLAG(F_SF);
169	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
170	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
171	return res;
172}
173
174/****************************************************************************
175REMARKS:
176Implements the AAD instruction and side effects.
177****************************************************************************/
178u16 aad_word(u16 d)
179{
180	u16 l;
181	u8 hb, lb;
182
183	hb = (u8)((d >> 8) & 0xff);
184	lb = (u8)((d & 0xff));
185	l = (u16)((lb + 10 * hb) & 0xFF);
186
187	CLEAR_FLAG(F_CF);
188	CLEAR_FLAG(F_AF);
189	CLEAR_FLAG(F_OF);
190	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
191	CONDITIONAL_SET_FLAG(l == 0, F_ZF);
192	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
193	return l;
194}
195
196/****************************************************************************
197REMARKS:
198Implements the AAM instruction and side effects.
199****************************************************************************/
200u16 aam_word(u8 d)
201{
202    u16 h, l;
203
204	h = (u16)(d / 10);
205	l = (u16)(d % 10);
206	l |= (u16)(h << 8);
207
208	CLEAR_FLAG(F_CF);
209	CLEAR_FLAG(F_AF);
210	CLEAR_FLAG(F_OF);
211	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
212	CONDITIONAL_SET_FLAG(l == 0, F_ZF);
213	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
214    return l;
215}
216
217/****************************************************************************
218REMARKS:
219Implements the ADC instruction and side effects.
220****************************************************************************/
221u8 adc_byte(u8 d, u8 s)
222{
223	register u32 res;   /* all operands in native machine order */
224	register u32 cc;
225
226	if (ACCESS_FLAG(F_CF))
227		res = 1 + d + s;
228	else
229		res = d + s;
230
231	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
232	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
233	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
234	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
235
236	/* calculate the carry chain  SEE NOTE AT TOP. */
237	cc = (s & d) | ((~res) & (s | d));
238	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
239	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
240	return (u8)res;
241}
242
243/****************************************************************************
244REMARKS:
245Implements the ADC instruction and side effects.
246****************************************************************************/
247u16 adc_word(u16 d, u16 s)
248{
249	register u32 res;   /* all operands in native machine order */
250	register u32 cc;
251
252	if (ACCESS_FLAG(F_CF))
253		res = 1 + d + s;
254	else
255		res = d + s;
256
257	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
258	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
259	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
260	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
261
262	/* calculate the carry chain  SEE NOTE AT TOP. */
263	cc = (s & d) | ((~res) & (s | d));
264	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
265	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
266	return (u16)res;
267}
268
269/****************************************************************************
270REMARKS:
271Implements the ADC instruction and side effects.
272****************************************************************************/
273u32 adc_long(u32 d, u32 s)
274{
275	register u32 lo;	/* all operands in native machine order */
276	register u32 hi;
277	register u32 res;
278	register u32 cc;
279
280	if (ACCESS_FLAG(F_CF)) {
281		lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
282		res = 1 + d + s;
283		}
284	else {
285		lo = (d & 0xFFFF) + (s & 0xFFFF);
286		res = d + s;
287		}
288	hi = (lo >> 16) + (d >> 16) + (s >> 16);
289
290	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
291	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
292	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
293	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
294
295	/* calculate the carry chain  SEE NOTE AT TOP. */
296	cc = (s & d) | ((~res) & (s | d));
297	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
298	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
299	return res;
300}
301
302/****************************************************************************
303REMARKS:
304Implements the ADD instruction and side effects.
305****************************************************************************/
306u8 add_byte(u8 d, u8 s)
307{
308	register u32 res;   /* all operands in native machine order */
309	register u32 cc;
310
311	res = d + s;
312	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
313	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
314	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
315	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
316
317	/* calculate the carry chain  SEE NOTE AT TOP. */
318	cc = (s & d) | ((~res) & (s | d));
319	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
320	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
321	return (u8)res;
322}
323
324/****************************************************************************
325REMARKS:
326Implements the ADD instruction and side effects.
327****************************************************************************/
328u16 add_word(u16 d, u16 s)
329{
330	register u32 res;   /* all operands in native machine order */
331	register u32 cc;
332
333	res = d + s;
334	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
335	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
336	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
337	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
338
339	/* calculate the carry chain  SEE NOTE AT TOP. */
340	cc = (s & d) | ((~res) & (s | d));
341	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
342	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
343	return (u16)res;
344}
345
346/****************************************************************************
347REMARKS:
348Implements the ADD instruction and side effects.
349****************************************************************************/
350u32 add_long(u32 d, u32 s)
351{
352	register u32 lo;	/* all operands in native machine order */
353	register u32 hi;
354	register u32 res;
355	register u32 cc;
356
357	lo = (d & 0xFFFF) + (s & 0xFFFF);
358	res = d + s;
359	hi = (lo >> 16) + (d >> 16) + (s >> 16);
360
361	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
362	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
363	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
364	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
365
366    /* calculate the carry chain  SEE NOTE AT TOP. */
367    cc = (s & d) | ((~res) & (s | d));
368	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
369	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
370
371    return res;
372}
373
374/****************************************************************************
375REMARKS:
376Implements the AND instruction and side effects.
377****************************************************************************/
378u8 and_byte(u8 d, u8 s)
379{
380	register u8 res;    /* all operands in native machine order */
381
382	res = d & s;
383
384	/* set the flags  */
385	CLEAR_FLAG(F_OF);
386	CLEAR_FLAG(F_CF);
387	CLEAR_FLAG(F_AF);
388	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
389	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
390	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
391	return res;
392}
393
394/****************************************************************************
395REMARKS:
396Implements the AND instruction and side effects.
397****************************************************************************/
398u16 and_word(u16 d, u16 s)
399{
400    register u16 res;   /* all operands in native machine order */
401
402    res = d & s;
403
404    /* set the flags  */
405	CLEAR_FLAG(F_OF);
406	CLEAR_FLAG(F_CF);
407	CLEAR_FLAG(F_AF);
408	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
409	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
410	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
411    return res;
412}
413
414/****************************************************************************
415REMARKS:
416Implements the AND instruction and side effects.
417****************************************************************************/
418u32 and_long(u32 d, u32 s)
419{
420	register u32 res;   /* all operands in native machine order */
421
422	res = d & s;
423
424	/* set the flags  */
425	CLEAR_FLAG(F_OF);
426	CLEAR_FLAG(F_CF);
427	CLEAR_FLAG(F_AF);
428	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
429	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
430	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
431	return res;
432}
433
434/****************************************************************************
435REMARKS:
436Implements the CMP instruction and side effects.
437****************************************************************************/
438u8 cmp_byte(u8 d, u8 s)
439{
440	register u32 res;   /* all operands in native machine order */
441	register u32 bc;
442
443	res = d - s;
444	CLEAR_FLAG(F_CF);
445	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
446	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
447	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
448
449	/* calculate the borrow chain.  See note at top */
450	bc = (res & (~d | s)) | (~d & s);
451	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
452	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
453	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
454	return d;
455}
456
457/****************************************************************************
458REMARKS:
459Implements the CMP instruction and side effects.
460****************************************************************************/
461u16 cmp_word(u16 d, u16 s)
462{
463	register u32 res;   /* all operands in native machine order */
464	register u32 bc;
465
466	res = d - s;
467	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
468	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
469	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
470
471	/* calculate the borrow chain.  See note at top */
472    bc = (res & (~d | s)) | (~d & s);
473	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
474	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
475	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
476	return d;
477}
478
479/****************************************************************************
480REMARKS:
481Implements the CMP instruction and side effects.
482****************************************************************************/
483u32 cmp_long(u32 d, u32 s)
484{
485	register u32 res;   /* all operands in native machine order */
486	register u32 bc;
487
488	res = d - s;
489	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
490	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
491	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
492
493	/* calculate the borrow chain.  See note at top */
494	bc = (res & (~d | s)) | (~d & s);
495	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
496	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
497	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
498	return d;
499}
500
501/****************************************************************************
502REMARKS:
503Implements the DAA instruction and side effects.
504****************************************************************************/
505u8 daa_byte(u8 d)
506{
507	u32 res = d;
508	if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
509		res += 6;
510		SET_FLAG(F_AF);
511	}
512	if (res > 0x9F || ACCESS_FLAG(F_CF)) {
513		res += 0x60;
514		SET_FLAG(F_CF);
515	}
516	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
517	CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
518	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
519	return (u8)res;
520}
521
522/****************************************************************************
523REMARKS:
524Implements the DAS instruction and side effects.
525****************************************************************************/
526u8 das_byte(u8 d)
527{
528	if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
529		d -= 6;
530		SET_FLAG(F_AF);
531	}
532	if (d > 0x9F || ACCESS_FLAG(F_CF)) {
533		d -= 0x60;
534		SET_FLAG(F_CF);
535	}
536	CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
537	CONDITIONAL_SET_FLAG(d == 0, F_ZF);
538	CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
539	return d;
540}
541
542/****************************************************************************
543REMARKS:
544Implements the DEC instruction and side effects.
545****************************************************************************/
546u8 dec_byte(u8 d)
547{
548    register u32 res;   /* all operands in native machine order */
549    register u32 bc;
550
551    res = d - 1;
552	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
553	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
554	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
555
556	/* calculate the borrow chain.  See note at top */
557	/* based on sub_byte, uses s==1.  */
558	bc = (res & (~d | 1)) | (~d & 1);
559	/* carry flag unchanged */
560	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
561	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
562	return (u8)res;
563}
564
565/****************************************************************************
566REMARKS:
567Implements the DEC instruction and side effects.
568****************************************************************************/
569u16 dec_word(u16 d)
570{
571    register u32 res;   /* all operands in native machine order */
572    register u32 bc;
573
574    res = d - 1;
575	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
576	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
577	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
578
579    /* calculate the borrow chain.  See note at top */
580    /* based on the sub_byte routine, with s==1 */
581    bc = (res & (~d | 1)) | (~d & 1);
582    /* carry flag unchanged */
583	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
584	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
585	return (u16)res;
586}
587
588/****************************************************************************
589REMARKS:
590Implements the DEC instruction and side effects.
591****************************************************************************/
592u32 dec_long(u32 d)
593{
594    register u32 res;   /* all operands in native machine order */
595    register u32 bc;
596
597    res = d - 1;
598
599	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
600	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
601	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
602
603    /* calculate the borrow chain.  See note at top */
604	bc = (res & (~d | 1)) | (~d & 1);
605	/* carry flag unchanged */
606	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
607	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
608	return res;
609}
610
611/****************************************************************************
612REMARKS:
613Implements the INC instruction and side effects.
614****************************************************************************/
615u8 inc_byte(u8 d)
616{
617	register u32 res;   /* all operands in native machine order */
618	register u32 cc;
619
620	res = d + 1;
621	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
622	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
623	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
624
625	/* calculate the carry chain  SEE NOTE AT TOP. */
626	cc = ((1 & d) | (~res)) & (1 | d);
627	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
628	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
629	return (u8)res;
630}
631
632/****************************************************************************
633REMARKS:
634Implements the INC instruction and side effects.
635****************************************************************************/
636u16 inc_word(u16 d)
637{
638	register u32 res;   /* all operands in native machine order */
639	register u32 cc;
640
641	res = d + 1;
642	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
643	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
644	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
645
646	/* calculate the carry chain  SEE NOTE AT TOP. */
647	cc = (1 & d) | ((~res) & (1 | d));
648	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
649	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
650	return (u16)res;
651}
652
653/****************************************************************************
654REMARKS:
655Implements the INC instruction and side effects.
656****************************************************************************/
657u32 inc_long(u32 d)
658{
659	register u32 res;   /* all operands in native machine order */
660	register u32 cc;
661
662	res = d + 1;
663	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
664	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
665	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
666
667	/* calculate the carry chain  SEE NOTE AT TOP. */
668	cc = (1 & d) | ((~res) & (1 | d));
669	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
670	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
671	return res;
672}
673
674/****************************************************************************
675REMARKS:
676Implements the OR instruction and side effects.
677****************************************************************************/
678u8 or_byte(u8 d, u8 s)
679{
680	register u8 res;    /* all operands in native machine order */
681
682	res = d | s;
683	CLEAR_FLAG(F_OF);
684	CLEAR_FLAG(F_CF);
685	CLEAR_FLAG(F_AF);
686	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
687	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
688	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
689	return res;
690}
691
692/****************************************************************************
693REMARKS:
694Implements the OR instruction and side effects.
695****************************************************************************/
696u16 or_word(u16 d, u16 s)
697{
698	register u16 res;   /* all operands in native machine order */
699
700	res = d | s;
701	/* set the carry flag to be bit 8 */
702	CLEAR_FLAG(F_OF);
703	CLEAR_FLAG(F_CF);
704	CLEAR_FLAG(F_AF);
705	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
706	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
707	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
708	return res;
709}
710
711/****************************************************************************
712REMARKS:
713Implements the OR instruction and side effects.
714****************************************************************************/
715u32 or_long(u32 d, u32 s)
716{
717	register u32 res;   /* all operands in native machine order */
718
719	res = d | s;
720
721	/* set the carry flag to be bit 8 */
722	CLEAR_FLAG(F_OF);
723	CLEAR_FLAG(F_CF);
724	CLEAR_FLAG(F_AF);
725	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
726	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
727	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
728	return res;
729}
730
731/****************************************************************************
732REMARKS:
733Implements the OR instruction and side effects.
734****************************************************************************/
735u8 neg_byte(u8 s)
736{
737    register u8 res;
738    register u8 bc;
739
740	CONDITIONAL_SET_FLAG(s != 0, F_CF);
741	res = (u8)-s;
742	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
743	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
744	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
745	/* calculate the borrow chain --- modified such that d=0.
746	   substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
747	   (the one used for sub) and simplifying, since ~d=0xff...,
748	   ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
749	   ~d&s == s.  So the simplified result is: */
750	bc = res | s;
751	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
752	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
753	return res;
754}
755
756/****************************************************************************
757REMARKS:
758Implements the OR instruction and side effects.
759****************************************************************************/
760u16 neg_word(u16 s)
761{
762	register u16 res;
763	register u16 bc;
764
765	CONDITIONAL_SET_FLAG(s != 0, F_CF);
766	res = (u16)-s;
767	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
768	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
769	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
770
771	/* calculate the borrow chain --- modified such that d=0.
772	   substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
773	   (the one used for sub) and simplifying, since ~d=0xff...,
774	   ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
775	   ~d&s == s.  So the simplified result is: */
776	bc = res | s;
777	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
778	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
779	return res;
780}
781
782/****************************************************************************
783REMARKS:
784Implements the OR instruction and side effects.
785****************************************************************************/
786u32 neg_long(u32 s)
787{
788	register u32 res;
789	register u32 bc;
790
791	CONDITIONAL_SET_FLAG(s != 0, F_CF);
792	res = (u32)-s;
793	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
794	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
795	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
796
797	/* calculate the borrow chain --- modified such that d=0.
798	   substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
799	   (the one used for sub) and simplifying, since ~d=0xff...,
800	   ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
801	   ~d&s == s.  So the simplified result is: */
802	bc = res | s;
803	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
804	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
805	return res;
806}
807
808/****************************************************************************
809REMARKS:
810Implements the NOT instruction and side effects.
811****************************************************************************/
812u8 not_byte(u8 s)
813{
814	return ~s;
815}
816
817/****************************************************************************
818REMARKS:
819Implements the NOT instruction and side effects.
820****************************************************************************/
821u16 not_word(u16 s)
822{
823	return ~s;
824}
825
826/****************************************************************************
827REMARKS:
828Implements the NOT instruction and side effects.
829****************************************************************************/
830u32 not_long(u32 s)
831{
832	return ~s;
833}
834
835/****************************************************************************
836REMARKS:
837Implements the RCL instruction and side effects.
838****************************************************************************/
839u8 rcl_byte(u8 d, u8 s)
840{
841    register unsigned int res, cnt, mask, cf;
842
843    /* s is the rotate distance.  It varies from 0 - 8. */
844	/* have
845
846       CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
847
848       want to rotate through the carry by "s" bits.  We could
849       loop, but that's inefficient.  So the width is 9,
850       and we split into three parts:
851
852       The new carry flag   (was B_n)
853       the stuff in B_n-1 .. B_0
854       the stuff in B_7 .. B_n+1
855
856       The new rotate is done mod 9, and given this,
857       for a rotation of n bits (mod 9) the new carry flag is
858       then located n bits from the MSB.  The low part is
859       then shifted up cnt bits, and the high part is or'd
860       in.  Using CAPS for new values, and lowercase for the
861       original values, this can be expressed as:
862
863       IF n > 0
864       1) CF <-  b_(8-n)
865       2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
866       3) B_(n-1) <- cf
867       4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
868	 */
869	res = d;
870	if ((cnt = s % 9) != 0) {
871        /* extract the new CARRY FLAG. */
872        /* CF <-  b_(8-n)             */
873        cf = (d >> (8 - cnt)) & 0x1;
874
875        /* get the low stuff which rotated
876           into the range B_7 .. B_cnt */
877        /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
878        /* note that the right hand side done by the mask */
879		res = (d << cnt) & 0xff;
880
881        /* now the high stuff which rotated around
882           into the positions B_cnt-2 .. B_0 */
883        /* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
884        /* shift it downward, 7-(n-2) = 9-n positions.
885           and mask off the result before or'ing in.
886         */
887        mask = (1 << (cnt - 1)) - 1;
888        res |= (d >> (9 - cnt)) & mask;
889
890        /* if the carry flag was set, or it in.  */
891		if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
892            /*  B_(n-1) <- cf */
893            res |= 1 << (cnt - 1);
894        }
895        /* set the new carry flag, based on the variable "cf" */
896		CONDITIONAL_SET_FLAG(cf, F_CF);
897        /* OVERFLOW is set *IFF* cnt==1, then it is the
898           xor of CF and the most significant bit.  Blecck. */
899        /* parenthesized this expression since it appears to
900           be causing OF to be misset */
901        CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
902							 F_OF);
903
904    }
905	return (u8)res;
906}
907
908/****************************************************************************
909REMARKS:
910Implements the RCL instruction and side effects.
911****************************************************************************/
912u16 rcl_word(u16 d, u8 s)
913{
914	register unsigned int res, cnt, mask, cf;
915
916	res = d;
917	if ((cnt = s % 17) != 0) {
918		cf = (d >> (16 - cnt)) & 0x1;
919		res = (d << cnt) & 0xffff;
920		mask = (1 << (cnt - 1)) - 1;
921		res |= (d >> (17 - cnt)) & mask;
922		if (ACCESS_FLAG(F_CF)) {
923			res |= 1 << (cnt - 1);
924		}
925		CONDITIONAL_SET_FLAG(cf, F_CF);
926		CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
927							 F_OF);
928	}
929	return (u16)res;
930}
931
932/****************************************************************************
933REMARKS:
934Implements the RCL instruction and side effects.
935****************************************************************************/
936u32 rcl_long(u32 d, u8 s)
937{
938	register u32 res, cnt, mask, cf;
939
940	res = d;
941	if ((cnt = s % 33) != 0) {
942		cf = (d >> (32 - cnt)) & 0x1;
943		res = (d << cnt) & 0xffffffff;
944		mask = (1 << (cnt - 1)) - 1;
945		res |= (d >> (33 - cnt)) & mask;
946		if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
947			res |= 1 << (cnt - 1);
948		}
949		CONDITIONAL_SET_FLAG(cf, F_CF);
950		CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
951							 F_OF);
952	}
953	return res;
954}
955
956/****************************************************************************
957REMARKS:
958Implements the RCR instruction and side effects.
959****************************************************************************/
960u8 rcr_byte(u8 d, u8 s)
961{
962	u32	res, cnt;
963	u32	mask, cf, ocf = 0;
964
965	/* rotate right through carry */
966    /*
967       s is the rotate distance.  It varies from 0 - 8.
968       d is the byte object rotated.
969
970       have
971
972       CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
973
974       The new rotate is done mod 9, and given this,
975       for a rotation of n bits (mod 9) the new carry flag is
976       then located n bits from the LSB.  The low part is
977       then shifted up cnt bits, and the high part is or'd
978       in.  Using CAPS for new values, and lowercase for the
979       original values, this can be expressed as:
980
981       IF n > 0
982       1) CF <-  b_(n-1)
983       2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
984       3) B_(8-n) <- cf
985       4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0)
986	 */
987	res = d;
988	if ((cnt = s % 9) != 0) {
989        /* extract the new CARRY FLAG. */
990        /* CF <-  b_(n-1)              */
991        if (cnt == 1) {
992            cf = d & 0x1;
993            /* note hackery here.  Access_flag(..) evaluates to either
994               0 if flag not set
995               non-zero if flag is set.
996               doing access_flag(..) != 0 casts that into either
997			   0..1 in any representation of the flags register
998               (i.e. packed bit array or unpacked.)
999             */
1000			ocf = ACCESS_FLAG(F_CF) != 0;
1001        } else
1002            cf = (d >> (cnt - 1)) & 0x1;
1003
1004        /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
1005        /* note that the right hand side done by the mask
1006           This is effectively done by shifting the
1007           object to the right.  The result must be masked,
1008           in case the object came in and was treated
1009           as a negative number.  Needed??? */
1010
1011        mask = (1 << (8 - cnt)) - 1;
1012        res = (d >> cnt) & mask;
1013
1014        /* now the high stuff which rotated around
1015           into the positions B_cnt-2 .. B_0 */
1016        /* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
1017        /* shift it downward, 7-(n-2) = 9-n positions.
1018           and mask off the result before or'ing in.
1019         */
1020        res |= (d << (9 - cnt));
1021
1022        /* if the carry flag was set, or it in.  */
1023		if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
1024            /*  B_(8-n) <- cf */
1025            res |= 1 << (8 - cnt);
1026        }
1027        /* set the new carry flag, based on the variable "cf" */
1028		CONDITIONAL_SET_FLAG(cf, F_CF);
1029        /* OVERFLOW is set *IFF* cnt==1, then it is the
1030           xor of CF and the most significant bit.  Blecck. */
1031        /* parenthesized... */
1032		if (cnt == 1) {
1033			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
1034								 F_OF);
1035		}
1036	}
1037	return (u8)res;
1038}
1039
1040/****************************************************************************
1041REMARKS:
1042Implements the RCR instruction and side effects.
1043****************************************************************************/
1044u16 rcr_word(u16 d, u8 s)
1045{
1046	u32 res, cnt;
1047	u32	mask, cf, ocf = 0;
1048
1049	/* rotate right through carry */
1050	res = d;
1051	if ((cnt = s % 17) != 0) {
1052		if (cnt == 1) {
1053			cf = d & 0x1;
1054			ocf = ACCESS_FLAG(F_CF) != 0;
1055		} else
1056			cf = (d >> (cnt - 1)) & 0x1;
1057		mask = (1 << (16 - cnt)) - 1;
1058		res = (d >> cnt) & mask;
1059		res |= (d << (17 - cnt));
1060		if (ACCESS_FLAG(F_CF)) {
1061			res |= 1 << (16 - cnt);
1062		}
1063		CONDITIONAL_SET_FLAG(cf, F_CF);
1064		if (cnt == 1) {
1065			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
1066								 F_OF);
1067		}
1068	}
1069	return (u16)res;
1070}
1071
1072/****************************************************************************
1073REMARKS:
1074Implements the RCR instruction and side effects.
1075****************************************************************************/
1076u32 rcr_long(u32 d, u8 s)
1077{
1078	u32 res, cnt;
1079	u32 mask, cf, ocf = 0;
1080
1081	/* rotate right through carry */
1082	res = d;
1083	if ((cnt = s % 33) != 0) {
1084		if (cnt == 1) {
1085			cf = d & 0x1;
1086			ocf = ACCESS_FLAG(F_CF) != 0;
1087		} else
1088			cf = (d >> (cnt - 1)) & 0x1;
1089		mask = (1 << (32 - cnt)) - 1;
1090		res = (d >> cnt) & mask;
1091		if (cnt != 1)
1092			res |= (d << (33 - cnt));
1093		if (ACCESS_FLAG(F_CF)) {     /* carry flag is set */
1094			res |= 1 << (32 - cnt);
1095		}
1096		CONDITIONAL_SET_FLAG(cf, F_CF);
1097		if (cnt == 1) {
1098			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
1099								 F_OF);
1100		}
1101	}
1102	return res;
1103}
1104
1105/****************************************************************************
1106REMARKS:
1107Implements the ROL instruction and side effects.
1108****************************************************************************/
1109u8 rol_byte(u8 d, u8 s)
1110{
1111    register unsigned int res, cnt, mask;
1112
1113    /* rotate left */
1114    /*
1115       s is the rotate distance.  It varies from 0 - 8.
1116       d is the byte object rotated.
1117
1118       have
1119
1120       CF  B_7 ... B_0
1121
1122       The new rotate is done mod 8.
1123       Much simpler than the "rcl" or "rcr" operations.
1124
1125       IF n > 0
1126       1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0)
1127       2) B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n)
1128	 */
1129    res = d;
1130	if ((cnt = s % 8) != 0) {
1131		/* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
1132		res = (d << cnt);
1133
1134		/* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
1135		mask = (1 << cnt) - 1;
1136		res |= (d >> (8 - cnt)) & mask;
1137
1138		/* set the new carry flag, Note that it is the low order
1139		   bit of the result!!!                               */
1140		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1141		/* OVERFLOW is set *IFF* s==1, then it is the
1142		   xor of CF and the most significant bit.  Blecck. */
1143		CONDITIONAL_SET_FLAG(s == 1 &&
1144							 XOR2((res & 0x1) + ((res >> 6) & 0x2)),
1145							 F_OF);
1146	} if (s != 0) {
1147		/* set the new carry flag, Note that it is the low order
1148		   bit of the result!!!                               */
1149		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1150	}
1151	return (u8)res;
1152}
1153
1154/****************************************************************************
1155REMARKS:
1156Implements the ROL instruction and side effects.
1157****************************************************************************/
1158u16 rol_word(u16 d, u8 s)
1159{
1160    register unsigned int res, cnt, mask;
1161
1162	res = d;
1163	if ((cnt = s % 16) != 0) {
1164		res = (d << cnt);
1165		mask = (1 << cnt) - 1;
1166		res |= (d >> (16 - cnt)) & mask;
1167		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1168		CONDITIONAL_SET_FLAG(s == 1 &&
1169							 XOR2((res & 0x1) + ((res >> 14) & 0x2)),
1170							 F_OF);
1171	} if (s != 0) {
1172		/* set the new carry flag, Note that it is the low order
1173		   bit of the result!!!                               */
1174		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1175	}
1176	return (u16)res;
1177}
1178
1179/****************************************************************************
1180REMARKS:
1181Implements the ROL instruction and side effects.
1182****************************************************************************/
1183u32 rol_long(u32 d, u8 s)
1184{
1185    register u32 res, cnt, mask;
1186
1187	res = d;
1188	if ((cnt = s % 32) != 0) {
1189		res = (d << cnt);
1190		mask = (1 << cnt) - 1;
1191		res |= (d >> (32 - cnt)) & mask;
1192		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1193		CONDITIONAL_SET_FLAG(s == 1 &&
1194							 XOR2((res & 0x1) + ((res >> 30) & 0x2)),
1195							 F_OF);
1196	} if (s != 0) {
1197		/* set the new carry flag, Note that it is the low order
1198		   bit of the result!!!                               */
1199		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
1200	}
1201	return res;
1202}
1203
1204/****************************************************************************
1205REMARKS:
1206Implements the ROR instruction and side effects.
1207****************************************************************************/
1208u8 ror_byte(u8 d, u8 s)
1209{
1210    register unsigned int res, cnt, mask;
1211
1212    /* rotate right */
1213    /*
1214       s is the rotate distance.  It varies from 0 - 8.
1215       d is the byte object rotated.
1216
1217       have
1218
1219       B_7 ... B_0
1220
1221       The rotate is done mod 8.
1222
1223       IF n > 0
1224       1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
1225       2) B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0)
1226	 */
1227	res = d;
1228	if ((cnt = s % 8) != 0) {           /* not a typo, do nada if cnt==0 */
1229        /* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
1230        res = (d << (8 - cnt));
1231
1232        /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
1233        mask = (1 << (8 - cnt)) - 1;
1234        res |= (d >> (cnt)) & mask;
1235
1236        /* set the new carry flag, Note that it is the low order
1237           bit of the result!!!                               */
1238		CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1239		/* OVERFLOW is set *IFF* s==1, then it is the
1240           xor of the two most significant bits.  Blecck. */
1241		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
1242	} else if (s != 0) {
1243		/* set the new carry flag, Note that it is the low order
1244		   bit of the result!!!                               */
1245		CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
1246	}
1247	return (u8)res;
1248}
1249
1250/****************************************************************************
1251REMARKS:
1252Implements the ROR instruction and side effects.
1253****************************************************************************/
1254u16 ror_word(u16 d, u8 s)
1255{
1256    register unsigned int res, cnt, mask;
1257
1258	res = d;
1259	if ((cnt = s % 16) != 0) {
1260		res = (d << (16 - cnt));
1261		mask = (1 << (16 - cnt)) - 1;
1262		res |= (d >> (cnt)) & mask;
1263		CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1264		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
1265	} else if (s != 0) {
1266		/* set the new carry flag, Note that it is the low order
1267		   bit of the result!!!                               */
1268		CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
1269	}
1270	return (u16)res;
1271}
1272
1273/****************************************************************************
1274REMARKS:
1275Implements the ROR instruction and side effects.
1276****************************************************************************/
1277u32 ror_long(u32 d, u8 s)
1278{
1279	register u32 res, cnt, mask;
1280
1281	res = d;
1282	if ((cnt = s % 32) != 0) {
1283		res = (d << (32 - cnt));
1284		mask = (1 << (32 - cnt)) - 1;
1285		res |= (d >> (cnt)) & mask;
1286		CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1287		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
1288	} else if (s != 0) {
1289		/* set the new carry flag, Note that it is the low order
1290		   bit of the result!!!                               */
1291		CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
1292	}
1293	return res;
1294}
1295
1296/****************************************************************************
1297REMARKS:
1298Implements the SHL instruction and side effects.
1299****************************************************************************/
1300u8 shl_byte(u8 d, u8 s)
1301{
1302	unsigned int cnt, res, cf;
1303
1304	if (s < 8) {
1305		cnt = s % 8;
1306
1307		/* last bit shifted out goes into carry flag */
1308		if (cnt > 0) {
1309			res = d << cnt;
1310			cf = d & (1 << (8 - cnt));
1311			CONDITIONAL_SET_FLAG(cf, F_CF);
1312			CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1313			CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1314			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1315		} else {
1316			res = (u8) d;
1317		}
1318
1319		if (cnt == 1) {
1320			/* Needs simplification. */
1321			CONDITIONAL_SET_FLAG(
1322									(((res & 0x80) == 0x80) ^
1323									 (ACCESS_FLAG(F_CF) != 0)),
1324			/* was (M.x86.R_FLG&F_CF)==F_CF)), */
1325									F_OF);
1326		} else {
1327			CLEAR_FLAG(F_OF);
1328		}
1329	} else {
1330		res = 0;
1331		CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80, F_CF);
1332		CLEAR_FLAG(F_OF);
1333		CLEAR_FLAG(F_SF);
1334		SET_FLAG(F_PF);
1335		SET_FLAG(F_ZF);
1336    }
1337	return (u8)res;
1338}
1339
1340/****************************************************************************
1341REMARKS:
1342Implements the SHL instruction and side effects.
1343****************************************************************************/
1344u16 shl_word(u16 d, u8 s)
1345{
1346    unsigned int cnt, res, cf;
1347
1348	if (s < 16) {
1349		cnt = s % 16;
1350		if (cnt > 0) {
1351			res = d << cnt;
1352			cf = d & (1 << (16 - cnt));
1353			CONDITIONAL_SET_FLAG(cf, F_CF);
1354			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1355			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1356			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1357		} else {
1358			res = (u16) d;
1359		}
1360
1361		if (cnt == 1) {
1362			CONDITIONAL_SET_FLAG(
1363									(((res & 0x8000) == 0x8000) ^
1364									 (ACCESS_FLAG(F_CF) != 0)),
1365									F_OF);
1366        } else {
1367			CLEAR_FLAG(F_OF);
1368        }
1369    } else {
1370		res = 0;
1371		CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1372		CLEAR_FLAG(F_OF);
1373		CLEAR_FLAG(F_SF);
1374		SET_FLAG(F_PF);
1375		SET_FLAG(F_ZF);
1376	}
1377	return (u16)res;
1378}
1379
1380/****************************************************************************
1381REMARKS:
1382Implements the SHL instruction and side effects.
1383****************************************************************************/
1384u32 shl_long(u32 d, u8 s)
1385{
1386	unsigned int cnt, res, cf;
1387
1388	if (s < 32) {
1389		cnt = s % 32;
1390		if (cnt > 0) {
1391			res = d << cnt;
1392			cf = d & (1 << (32 - cnt));
1393			CONDITIONAL_SET_FLAG(cf, F_CF);
1394			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1395			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1396			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1397		} else {
1398			res = d;
1399		}
1400		if (cnt == 1) {
1401			CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1402								  (ACCESS_FLAG(F_CF) != 0)), F_OF);
1403		} else {
1404			CLEAR_FLAG(F_OF);
1405		}
1406	} else {
1407		res = 0;
1408		CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1409		CLEAR_FLAG(F_OF);
1410		CLEAR_FLAG(F_SF);
1411		SET_FLAG(F_PF);
1412		SET_FLAG(F_ZF);
1413	}
1414	return res;
1415}
1416
1417/****************************************************************************
1418REMARKS:
1419Implements the SHR instruction and side effects.
1420****************************************************************************/
1421u8 shr_byte(u8 d, u8 s)
1422{
1423	unsigned int cnt, res, cf;
1424
1425	if (s < 8) {
1426		cnt = s % 8;
1427		if (cnt > 0) {
1428			cf = d & (1 << (cnt - 1));
1429			res = d >> cnt;
1430			CONDITIONAL_SET_FLAG(cf, F_CF);
1431			CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1432			CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1433			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1434		} else {
1435			res = (u8) d;
1436		}
1437
1438		if (cnt == 1) {
1439			CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
1440		} else {
1441			CLEAR_FLAG(F_OF);
1442		}
1443	} else {
1444		res = 0;
1445		CONDITIONAL_SET_FLAG((d >> (s-1)) & 0x1, F_CF);
1446		CLEAR_FLAG(F_OF);
1447		CLEAR_FLAG(F_SF);
1448		SET_FLAG(F_PF);
1449		SET_FLAG(F_ZF);
1450	}
1451	return (u8)res;
1452}
1453
1454/****************************************************************************
1455REMARKS:
1456Implements the SHR instruction and side effects.
1457****************************************************************************/
1458u16 shr_word(u16 d, u8 s)
1459{
1460	unsigned int cnt, res, cf;
1461
1462	if (s < 16) {
1463		cnt = s % 16;
1464		if (cnt > 0) {
1465			cf = d & (1 << (cnt - 1));
1466			res = d >> cnt;
1467			CONDITIONAL_SET_FLAG(cf, F_CF);
1468			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1469			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1470			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1471		} else {
1472			res = d;
1473		}
1474
1475		if (cnt == 1) {
1476			CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1477        } else {
1478			CLEAR_FLAG(F_OF);
1479        }
1480	} else {
1481		res = 0;
1482		CLEAR_FLAG(F_CF);
1483		CLEAR_FLAG(F_OF);
1484		SET_FLAG(F_ZF);
1485		CLEAR_FLAG(F_SF);
1486		CLEAR_FLAG(F_PF);
1487    }
1488	return (u16)res;
1489}
1490
1491/****************************************************************************
1492REMARKS:
1493Implements the SHR instruction and side effects.
1494****************************************************************************/
1495u32 shr_long(u32 d, u8 s)
1496{
1497	unsigned int cnt, res, cf;
1498
1499	if (s < 32) {
1500		cnt = s % 32;
1501		if (cnt > 0) {
1502			cf = d & (1 << (cnt - 1));
1503			res = d >> cnt;
1504			CONDITIONAL_SET_FLAG(cf, F_CF);
1505			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1506			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1507			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1508        } else {
1509            res = d;
1510        }
1511        if (cnt == 1) {
1512			CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1513        } else {
1514			CLEAR_FLAG(F_OF);
1515        }
1516    } else {
1517        res = 0;
1518		CLEAR_FLAG(F_CF);
1519		CLEAR_FLAG(F_OF);
1520		SET_FLAG(F_ZF);
1521		CLEAR_FLAG(F_SF);
1522		CLEAR_FLAG(F_PF);
1523    }
1524    return res;
1525}
1526
1527/****************************************************************************
1528REMARKS:
1529Implements the SAR instruction and side effects.
1530****************************************************************************/
1531u8 sar_byte(u8 d, u8 s)
1532{
1533	unsigned int cnt, res, cf, mask, sf;
1534
1535	res = d;
1536	sf = d & 0x80;
1537    cnt = s % 8;
1538	if (cnt > 0 && cnt < 8) {
1539		mask = (1 << (8 - cnt)) - 1;
1540		cf = d & (1 << (cnt - 1));
1541		res = (d >> cnt) & mask;
1542		CONDITIONAL_SET_FLAG(cf, F_CF);
1543		if (sf) {
1544			res |= ~mask;
1545		}
1546		CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1547		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1548		CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1549    } else if (cnt >= 8) {
1550        if (sf) {
1551            res = 0xff;
1552			SET_FLAG(F_CF);
1553			CLEAR_FLAG(F_ZF);
1554			SET_FLAG(F_SF);
1555			SET_FLAG(F_PF);
1556		} else {
1557			res = 0;
1558			CLEAR_FLAG(F_CF);
1559			SET_FLAG(F_ZF);
1560			CLEAR_FLAG(F_SF);
1561			CLEAR_FLAG(F_PF);
1562		}
1563	}
1564	return (u8)res;
1565}
1566
1567/****************************************************************************
1568REMARKS:
1569Implements the SAR instruction and side effects.
1570****************************************************************************/
1571u16 sar_word(u16 d, u8 s)
1572{
1573    unsigned int cnt, res, cf, mask, sf;
1574
1575    sf = d & 0x8000;
1576    cnt = s % 16;
1577	res = d;
1578	if (cnt > 0 && cnt < 16) {
1579        mask = (1 << (16 - cnt)) - 1;
1580        cf = d & (1 << (cnt - 1));
1581        res = (d >> cnt) & mask;
1582		CONDITIONAL_SET_FLAG(cf, F_CF);
1583        if (sf) {
1584            res |= ~mask;
1585        }
1586		CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1587		CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1588		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1589    } else if (cnt >= 16) {
1590        if (sf) {
1591            res = 0xffff;
1592			SET_FLAG(F_CF);
1593			CLEAR_FLAG(F_ZF);
1594			SET_FLAG(F_SF);
1595			SET_FLAG(F_PF);
1596        } else {
1597            res = 0;
1598			CLEAR_FLAG(F_CF);
1599			SET_FLAG(F_ZF);
1600			CLEAR_FLAG(F_SF);
1601			CLEAR_FLAG(F_PF);
1602        }
1603    }
1604	return (u16)res;
1605}
1606
1607/****************************************************************************
1608REMARKS:
1609Implements the SAR instruction and side effects.
1610****************************************************************************/
1611u32 sar_long(u32 d, u8 s)
1612{
1613    u32 cnt, res, cf, mask, sf;
1614
1615    sf = d & 0x80000000;
1616    cnt = s % 32;
1617	res = d;
1618	if (cnt > 0 && cnt < 32) {
1619        mask = (1 << (32 - cnt)) - 1;
1620		cf = d & (1 << (cnt - 1));
1621        res = (d >> cnt) & mask;
1622		CONDITIONAL_SET_FLAG(cf, F_CF);
1623        if (sf) {
1624            res |= ~mask;
1625        }
1626		CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1627		CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1628		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1629    } else if (cnt >= 32) {
1630        if (sf) {
1631            res = 0xffffffff;
1632			SET_FLAG(F_CF);
1633			CLEAR_FLAG(F_ZF);
1634			SET_FLAG(F_SF);
1635			SET_FLAG(F_PF);
1636		} else {
1637			res = 0;
1638			CLEAR_FLAG(F_CF);
1639			SET_FLAG(F_ZF);
1640			CLEAR_FLAG(F_SF);
1641			CLEAR_FLAG(F_PF);
1642		}
1643	}
1644	return res;
1645}
1646
1647/****************************************************************************
1648REMARKS:
1649Implements the SHLD instruction and side effects.
1650****************************************************************************/
1651u16 shld_word (u16 d, u16 fill, u8 s)
1652{
1653	unsigned int cnt, res, cf;
1654
1655	if (s < 16) {
1656		cnt = s % 16;
1657		if (cnt > 0) {
1658			res = (d << cnt) | (fill >> (16-cnt));
1659			cf = d & (1 << (16 - cnt));
1660			CONDITIONAL_SET_FLAG(cf, F_CF);
1661			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1662			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1663			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1664		} else {
1665			res = d;
1666		}
1667		if (cnt == 1) {
1668			CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
1669								  (ACCESS_FLAG(F_CF) != 0)), F_OF);
1670		} else {
1671			CLEAR_FLAG(F_OF);
1672		}
1673	} else {
1674		res = 0;
1675		CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
1676		CLEAR_FLAG(F_OF);
1677		CLEAR_FLAG(F_SF);
1678		SET_FLAG(F_PF);
1679		SET_FLAG(F_ZF);
1680	}
1681	return (u16)res;
1682}
1683
1684/****************************************************************************
1685REMARKS:
1686Implements the SHLD instruction and side effects.
1687****************************************************************************/
1688u32 shld_long (u32 d, u32 fill, u8 s)
1689{
1690	unsigned int cnt, res, cf;
1691
1692	if (s < 32) {
1693		cnt = s % 32;
1694		if (cnt > 0) {
1695			res = (d << cnt) | (fill >> (32-cnt));
1696			cf = d & (1 << (32 - cnt));
1697			CONDITIONAL_SET_FLAG(cf, F_CF);
1698			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1699			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1700			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1701		} else {
1702			res = d;
1703		}
1704		if (cnt == 1) {
1705			CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
1706								  (ACCESS_FLAG(F_CF) != 0)), F_OF);
1707		} else {
1708			CLEAR_FLAG(F_OF);
1709		}
1710	} else {
1711		res = 0;
1712		CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF);
1713		CLEAR_FLAG(F_OF);
1714		CLEAR_FLAG(F_SF);
1715		SET_FLAG(F_PF);
1716		SET_FLAG(F_ZF);
1717	}
1718	return res;
1719}
1720
1721/****************************************************************************
1722REMARKS:
1723Implements the SHRD instruction and side effects.
1724****************************************************************************/
1725u16 shrd_word (u16 d, u16 fill, u8 s)
1726{
1727	unsigned int cnt, res, cf;
1728
1729	if (s < 16) {
1730		cnt = s % 16;
1731		if (cnt > 0) {
1732			cf = d & (1 << (cnt - 1));
1733			res = (d >> cnt) | (fill << (16 - cnt));
1734			CONDITIONAL_SET_FLAG(cf, F_CF);
1735			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1736			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1737			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1738		} else {
1739			res = d;
1740		}
1741
1742		if (cnt == 1) {
1743			CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
1744        } else {
1745			CLEAR_FLAG(F_OF);
1746        }
1747	} else {
1748		res = 0;
1749		CLEAR_FLAG(F_CF);
1750		CLEAR_FLAG(F_OF);
1751		SET_FLAG(F_ZF);
1752		CLEAR_FLAG(F_SF);
1753		CLEAR_FLAG(F_PF);
1754    }
1755	return (u16)res;
1756}
1757
1758/****************************************************************************
1759REMARKS:
1760Implements the SHRD instruction and side effects.
1761****************************************************************************/
1762u32 shrd_long (u32 d, u32 fill, u8 s)
1763{
1764	unsigned int cnt, res, cf;
1765
1766	if (s < 32) {
1767		cnt = s % 32;
1768		if (cnt > 0) {
1769			cf = d & (1 << (cnt - 1));
1770			res = (d >> cnt) | (fill << (32 - cnt));
1771			CONDITIONAL_SET_FLAG(cf, F_CF);
1772			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1773			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1774			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1775		} else {
1776			res = d;
1777		}
1778		if (cnt == 1) {
1779			CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
1780        } else {
1781			CLEAR_FLAG(F_OF);
1782        }
1783	} else {
1784		res = 0;
1785		CLEAR_FLAG(F_CF);
1786		CLEAR_FLAG(F_OF);
1787		SET_FLAG(F_ZF);
1788		CLEAR_FLAG(F_SF);
1789		CLEAR_FLAG(F_PF);
1790    }
1791	return res;
1792}
1793
1794/****************************************************************************
1795REMARKS:
1796Implements the SBB instruction and side effects.
1797****************************************************************************/
1798u8 sbb_byte(u8 d, u8 s)
1799{
1800    register u32 res;   /* all operands in native machine order */
1801    register u32 bc;
1802
1803	if (ACCESS_FLAG(F_CF))
1804		res = d - s - 1;
1805	else
1806		res = d - s;
1807	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1808	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1809	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1810
1811	/* calculate the borrow chain.  See note at top */
1812	bc = (res & (~d | s)) | (~d & s);
1813	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1814	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1815	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1816	return (u8)res;
1817}
1818
1819/****************************************************************************
1820REMARKS:
1821Implements the SBB instruction and side effects.
1822****************************************************************************/
1823u16 sbb_word(u16 d, u16 s)
1824{
1825    register u32 res;   /* all operands in native machine order */
1826    register u32 bc;
1827
1828	if (ACCESS_FLAG(F_CF))
1829        res = d - s - 1;
1830    else
1831        res = d - s;
1832	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1833	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1834	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1835
1836	/* calculate the borrow chain.  See note at top */
1837	bc = (res & (~d | s)) | (~d & s);
1838	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1839	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1840	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1841	return (u16)res;
1842}
1843
1844/****************************************************************************
1845REMARKS:
1846Implements the SBB instruction and side effects.
1847****************************************************************************/
1848u32 sbb_long(u32 d, u32 s)
1849{
1850	register u32 res;   /* all operands in native machine order */
1851	register u32 bc;
1852
1853	if (ACCESS_FLAG(F_CF))
1854        res = d - s - 1;
1855    else
1856        res = d - s;
1857	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1858	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1859	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1860
1861	/* calculate the borrow chain.  See note at top */
1862	bc = (res & (~d | s)) | (~d & s);
1863	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1864	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1865	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1866	return res;
1867}
1868
1869/****************************************************************************
1870REMARKS:
1871Implements the SUB instruction and side effects.
1872****************************************************************************/
1873u8 sub_byte(u8 d, u8 s)
1874{
1875	register u32 res;   /* all operands in native machine order */
1876	register u32 bc;
1877
1878	res = d - s;
1879	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1880	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
1881	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1882
1883	/* calculate the borrow chain.  See note at top */
1884	bc = (res & (~d | s)) | (~d & s);
1885	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
1886	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
1887	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1888	return (u8)res;
1889}
1890
1891/****************************************************************************
1892REMARKS:
1893Implements the SUB instruction and side effects.
1894****************************************************************************/
1895u16 sub_word(u16 d, u16 s)
1896{
1897    register u32 res;   /* all operands in native machine order */
1898    register u32 bc;
1899
1900    res = d - s;
1901	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1902	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
1903	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1904
1905	/* calculate the borrow chain.  See note at top */
1906	bc = (res & (~d | s)) | (~d & s);
1907	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
1908	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
1909	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1910	return (u16)res;
1911}
1912
1913/****************************************************************************
1914REMARKS:
1915Implements the SUB instruction and side effects.
1916****************************************************************************/
1917u32 sub_long(u32 d, u32 s)
1918{
1919	register u32 res;   /* all operands in native machine order */
1920	register u32 bc;
1921
1922	res = d - s;
1923	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1924	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
1925	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1926
1927	/* calculate the borrow chain.  See note at top */
1928	bc = (res & (~d | s)) | (~d & s);
1929	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
1930	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
1931	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
1932	return res;
1933}
1934
1935/****************************************************************************
1936REMARKS:
1937Implements the TEST instruction and side effects.
1938****************************************************************************/
1939void test_byte(u8 d, u8 s)
1940{
1941    register u32 res;   /* all operands in native machine order */
1942
1943    res = d & s;
1944
1945	CLEAR_FLAG(F_OF);
1946	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
1947	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1948	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1949    /* AF == dont care */
1950	CLEAR_FLAG(F_CF);
1951}
1952
1953/****************************************************************************
1954REMARKS:
1955Implements the TEST instruction and side effects.
1956****************************************************************************/
1957void test_word(u16 d, u16 s)
1958{
1959	register u32 res;   /* all operands in native machine order */
1960
1961	res = d & s;
1962
1963	CLEAR_FLAG(F_OF);
1964	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
1965	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1966	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1967	/* AF == dont care */
1968	CLEAR_FLAG(F_CF);
1969}
1970
1971/****************************************************************************
1972REMARKS:
1973Implements the TEST instruction and side effects.
1974****************************************************************************/
1975void test_long(u32 d, u32 s)
1976{
1977	register u32 res;   /* all operands in native machine order */
1978
1979	res = d & s;
1980
1981	CLEAR_FLAG(F_OF);
1982	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
1983	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
1984	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
1985	/* AF == dont care */
1986	CLEAR_FLAG(F_CF);
1987}
1988
1989/****************************************************************************
1990REMARKS:
1991Implements the XOR instruction and side effects.
1992****************************************************************************/
1993u8 xor_byte(u8 d, u8 s)
1994{
1995	register u8 res;    /* all operands in native machine order */
1996
1997	res = d ^ s;
1998	CLEAR_FLAG(F_OF);
1999	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
2000	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2001	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
2002	CLEAR_FLAG(F_CF);
2003	CLEAR_FLAG(F_AF);
2004	return res;
2005}
2006
2007/****************************************************************************
2008REMARKS:
2009Implements the XOR instruction and side effects.
2010****************************************************************************/
2011u16 xor_word(u16 d, u16 s)
2012{
2013	register u16 res;   /* all operands in native machine order */
2014
2015	res = d ^ s;
2016	CLEAR_FLAG(F_OF);
2017	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
2018	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2019	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2020	CLEAR_FLAG(F_CF);
2021	CLEAR_FLAG(F_AF);
2022	return res;
2023}
2024
2025/****************************************************************************
2026REMARKS:
2027Implements the XOR instruction and side effects.
2028****************************************************************************/
2029u32 xor_long(u32 d, u32 s)
2030{
2031	register u32 res;   /* all operands in native machine order */
2032
2033	res = d ^ s;
2034	CLEAR_FLAG(F_OF);
2035	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
2036	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
2037	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
2038	CLEAR_FLAG(F_CF);
2039	CLEAR_FLAG(F_AF);
2040	return res;
2041}
2042
2043/****************************************************************************
2044REMARKS:
2045Implements the IMUL instruction and side effects.
2046****************************************************************************/
2047void imul_byte(u8 s)
2048{
2049	s16 res = (s16)((s8)M.x86.R_AL * (s8)s);
2050
2051	M.x86.R_AX = res;
2052	if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
2053		((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
2054		CLEAR_FLAG(F_CF);
2055		CLEAR_FLAG(F_OF);
2056	} else {
2057		SET_FLAG(F_CF);
2058		SET_FLAG(F_OF);
2059	}
2060}
2061
2062/****************************************************************************
2063REMARKS:
2064Implements the IMUL instruction and side effects.
2065****************************************************************************/
2066void imul_word(u16 s)
2067{
2068	s32 res = (s16)M.x86.R_AX * (s16)s;
2069
2070	M.x86.R_AX = (u16)res;
2071	M.x86.R_DX = (u16)(res >> 16);
2072	if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
2073		((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
2074		CLEAR_FLAG(F_CF);
2075		CLEAR_FLAG(F_OF);
2076	} else {
2077		SET_FLAG(F_CF);
2078		SET_FLAG(F_OF);
2079	}
2080}
2081
2082/****************************************************************************
2083REMARKS:
2084Implements the IMUL instruction and side effects.
2085****************************************************************************/
2086void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2087{
2088#ifdef	__HAS_LONG_LONG__
2089	s64 res = (s32)d * (s32)s;
2090
2091	*res_lo = (u32)res;
2092	*res_hi = (u32)(res >> 32);
2093#else
2094	u32	d_lo,d_hi,d_sign;
2095	u32	s_lo,s_hi,s_sign;
2096	u32	rlo_lo,rlo_hi,rhi_lo;
2097
2098	if ((d_sign = d & 0x80000000) != 0)
2099		d = -d;
2100	d_lo = d & 0xFFFF;
2101	d_hi = d >> 16;
2102	if ((s_sign = s & 0x80000000) != 0)
2103		s = -s;
2104	s_lo = s & 0xFFFF;
2105	s_hi = s >> 16;
2106	rlo_lo = d_lo * s_lo;
2107	rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
2108	rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
2109	*res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2110	*res_hi = rhi_lo;
2111	if (d_sign != s_sign) {
2112		d = ~*res_lo;
2113		s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
2114		*res_lo = ~*res_lo+1;
2115		*res_hi = ~*res_hi+(s >> 16);
2116		}
2117#endif
2118}
2119
2120/****************************************************************************
2121REMARKS:
2122Implements the IMUL instruction and side effects.
2123****************************************************************************/
2124void imul_long(u32 s)
2125{
2126	imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s);
2127	if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
2128		((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
2129		CLEAR_FLAG(F_CF);
2130		CLEAR_FLAG(F_OF);
2131	} else {
2132		SET_FLAG(F_CF);
2133		SET_FLAG(F_OF);
2134	}
2135}
2136
2137/****************************************************************************
2138REMARKS:
2139Implements the MUL instruction and side effects.
2140****************************************************************************/
2141void mul_byte(u8 s)
2142{
2143	u16 res = (u16)(M.x86.R_AL * s);
2144
2145	M.x86.R_AX = res;
2146	if (M.x86.R_AH == 0) {
2147		CLEAR_FLAG(F_CF);
2148		CLEAR_FLAG(F_OF);
2149	} else {
2150		SET_FLAG(F_CF);
2151		SET_FLAG(F_OF);
2152	}
2153}
2154
2155/****************************************************************************
2156REMARKS:
2157Implements the MUL instruction and side effects.
2158****************************************************************************/
2159void mul_word(u16 s)
2160{
2161	u32 res = M.x86.R_AX * s;
2162
2163	M.x86.R_AX = (u16)res;
2164	M.x86.R_DX = (u16)(res >> 16);
2165	if (M.x86.R_DX == 0) {
2166		CLEAR_FLAG(F_CF);
2167		CLEAR_FLAG(F_OF);
2168    } else {
2169		SET_FLAG(F_CF);
2170		SET_FLAG(F_OF);
2171    }
2172}
2173
2174/****************************************************************************
2175REMARKS:
2176Implements the MUL instruction and side effects.
2177****************************************************************************/
2178void mul_long(u32 s)
2179{
2180#ifdef	__HAS_LONG_LONG__
2181	u64 res = (u32)M.x86.R_EAX * (u32)s;
2182
2183	M.x86.R_EAX = (u32)res;
2184	M.x86.R_EDX = (u32)(res >> 32);
2185#else
2186	u32	a,a_lo,a_hi;
2187	u32	s_lo,s_hi;
2188	u32	rlo_lo,rlo_hi,rhi_lo;
2189
2190	a = M.x86.R_EAX;
2191	a_lo = a & 0xFFFF;
2192	a_hi = a >> 16;
2193	s_lo = s & 0xFFFF;
2194	s_hi = s >> 16;
2195	rlo_lo = a_lo * s_lo;
2196	rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
2197	rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
2198	M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
2199	M.x86.R_EDX = rhi_lo;
2200#endif
2201
2202	if (M.x86.R_EDX == 0) {
2203		CLEAR_FLAG(F_CF);
2204		CLEAR_FLAG(F_OF);
2205	} else {
2206		SET_FLAG(F_CF);
2207		SET_FLAG(F_OF);
2208    }
2209}
2210
2211/****************************************************************************
2212REMARKS:
2213Implements the IDIV instruction and side effects.
2214****************************************************************************/
2215#define abs(a) (((a) < 0) ? -(a) : (a))
2216void idiv_byte(u8 s)
2217{
2218    s32 dvd, div, mod;
2219
2220	dvd = (s16)M.x86.R_AX;
2221	if (s == 0) {
2222		x86emu_intr_raise(0);
2223        return;
2224	}
2225	div = dvd / (s8)s;
2226	mod = dvd % (s8)s;
2227	if (abs(div) > 0x7f) {
2228		x86emu_intr_raise(0);
2229		return;
2230	}
2231	M.x86.R_AL = (s8) div;
2232	M.x86.R_AH = (s8) mod;
2233}
2234
2235/****************************************************************************
2236REMARKS:
2237Implements the IDIV instruction and side effects.
2238****************************************************************************/
2239void idiv_word(u16 s)
2240{
2241	s32 dvd, div, mod;
2242
2243	dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;
2244	if (s == 0) {
2245		x86emu_intr_raise(0);
2246		return;
2247	}
2248	div = dvd / (s16)s;
2249	mod = dvd % (s16)s;
2250	if (abs(div) > 0x7fff) {
2251		x86emu_intr_raise(0);
2252		return;
2253	}
2254	CLEAR_FLAG(F_CF);
2255	CLEAR_FLAG(F_SF);
2256	CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2257	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2258
2259	M.x86.R_AX = (u16)div;
2260	M.x86.R_DX = (u16)mod;
2261}
2262
2263/****************************************************************************
2264REMARKS:
2265Implements the IDIV instruction and side effects.
2266****************************************************************************/
2267void idiv_long(u32 s)
2268{
2269#ifdef	__HAS_LONG_LONG__
2270	s64 dvd, div, mod;
2271
2272	dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2273	if (s == 0) {
2274		x86emu_intr_raise(0);
2275		return;
2276	}
2277	div = dvd / (s32)s;
2278	mod = dvd % (s32)s;
2279	if (abs(div) > 0x7fffffff) {
2280		x86emu_intr_raise(0);
2281		return;
2282	}
2283#else
2284	s32 div = 0, mod;
2285	s32 h_dvd = M.x86.R_EDX;
2286	u32 l_dvd = M.x86.R_EAX;
2287	u32 abs_s = s & 0x7FFFFFFF;
2288	u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
2289	u32 h_s = abs_s >> 1;
2290	u32 l_s = abs_s << 31;
2291	int counter = 31;
2292	int carry;
2293
2294	if (s == 0) {
2295		x86emu_intr_raise(0);
2296		return;
2297	}
2298	do {
2299		div <<= 1;
2300		carry = (l_dvd >= l_s) ? 0 : 1;
2301
2302		if (abs_h_dvd < (h_s + carry)) {
2303			h_s >>= 1;
2304			l_s = abs_s << (--counter);
2305			continue;
2306		} else {
2307			abs_h_dvd -= (h_s + carry);
2308			l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2309				: (l_dvd - l_s);
2310			h_s >>= 1;
2311			l_s = abs_s << (--counter);
2312			div |= 1;
2313			continue;
2314		}
2315
2316	} while (counter > -1);
2317	/* overflow */
2318	if (abs_h_dvd || (l_dvd > abs_s)) {
2319		x86emu_intr_raise(0);
2320		return;
2321	}
2322	/* sign */
2323	div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
2324	mod = l_dvd;
2325
2326#endif
2327	CLEAR_FLAG(F_CF);
2328	CLEAR_FLAG(F_AF);
2329	CLEAR_FLAG(F_SF);
2330	SET_FLAG(F_ZF);
2331	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2332
2333	M.x86.R_EAX = (u32)div;
2334	M.x86.R_EDX = (u32)mod;
2335}
2336
2337/****************************************************************************
2338REMARKS:
2339Implements the DIV instruction and side effects.
2340****************************************************************************/
2341void div_byte(u8 s)
2342{
2343	u32 dvd, div, mod;
2344
2345	dvd = M.x86.R_AX;
2346    if (s == 0) {
2347		x86emu_intr_raise(0);
2348        return;
2349    }
2350	div = dvd / (u8)s;
2351	mod = dvd % (u8)s;
2352	if (abs(div) > 0xff) {
2353		x86emu_intr_raise(0);
2354        return;
2355	}
2356	M.x86.R_AL = (u8)div;
2357	M.x86.R_AH = (u8)mod;
2358}
2359
2360/****************************************************************************
2361REMARKS:
2362Implements the DIV instruction and side effects.
2363****************************************************************************/
2364void div_word(u16 s)
2365{
2366	u32 dvd, div, mod;
2367
2368	dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;
2369	if (s == 0) {
2370		x86emu_intr_raise(0);
2371        return;
2372    }
2373	div = dvd / (u16)s;
2374	mod = dvd % (u16)s;
2375	if (abs(div) > 0xffff) {
2376		x86emu_intr_raise(0);
2377		return;
2378	}
2379	CLEAR_FLAG(F_CF);
2380	CLEAR_FLAG(F_SF);
2381	CONDITIONAL_SET_FLAG(div == 0, F_ZF);
2382	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2383
2384	M.x86.R_AX = (u16)div;
2385	M.x86.R_DX = (u16)mod;
2386}
2387
2388/****************************************************************************
2389REMARKS:
2390Implements the DIV instruction and side effects.
2391****************************************************************************/
2392void div_long(u32 s)
2393{
2394#ifdef	__HAS_LONG_LONG__
2395	u64 dvd, div, mod;
2396
2397	dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;
2398	if (s == 0) {
2399		x86emu_intr_raise(0);
2400		return;
2401	}
2402	div = dvd / (u32)s;
2403	mod = dvd % (u32)s;
2404	if (abs(div) > 0xffffffff) {
2405		x86emu_intr_raise(0);
2406		return;
2407	}
2408#else
2409	s32 div = 0, mod;
2410	s32 h_dvd = M.x86.R_EDX;
2411	u32 l_dvd = M.x86.R_EAX;
2412
2413	u32 h_s = s;
2414	u32 l_s = 0;
2415	int counter = 32;
2416	int carry;
2417
2418	if (s == 0) {
2419		x86emu_intr_raise(0);
2420		return;
2421	}
2422	do {
2423		div <<= 1;
2424		carry = (l_dvd >= l_s) ? 0 : 1;
2425
2426		if (h_dvd < (h_s + carry)) {
2427			h_s >>= 1;
2428			l_s = s << (--counter);
2429			continue;
2430		} else {
2431			h_dvd -= (h_s + carry);
2432			l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
2433				: (l_dvd - l_s);
2434			h_s >>= 1;
2435			l_s = s << (--counter);
2436			div |= 1;
2437			continue;
2438		}
2439
2440	} while (counter > -1);
2441	/* overflow */
2442	if (h_dvd || (l_dvd > s)) {
2443		x86emu_intr_raise(0);
2444		return;
2445	}
2446	mod = l_dvd;
2447#endif
2448	CLEAR_FLAG(F_CF);
2449	CLEAR_FLAG(F_AF);
2450	CLEAR_FLAG(F_SF);
2451	SET_FLAG(F_ZF);
2452	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
2453
2454	M.x86.R_EAX = (u32)div;
2455	M.x86.R_EDX = (u32)mod;
2456}
2457
2458#endif	/* __HAVE_INLINE_ASSEMBLER__ */
2459
2460/****************************************************************************
2461REMARKS:
2462Implements the IN string instruction and side effects.
2463****************************************************************************/
2464void ins(int size)
2465{
2466	int inc = size;
2467
2468	if (ACCESS_FLAG(F_DF)) {
2469		inc = -size;
2470	}
2471	if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2472        /* dont care whether REPE or REPNE */
2473        /* in until CX is ZERO. */
2474		u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2475					 M.x86.R_ECX : M.x86.R_CX);
2476        switch (size) {
2477          case 1:
2478            while (count--) {
2479				store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2480									(*sys_inb)(M.x86.R_DX));
2481				M.x86.R_DI += inc;
2482            }
2483            break;
2484
2485          case 2:
2486            while (count--) {
2487				store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2488									(*sys_inw)(M.x86.R_DX));
2489				M.x86.R_DI += inc;
2490            }
2491            break;
2492          case 4:
2493            while (count--) {
2494				store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2495									(*sys_inl)(M.x86.R_DX));
2496				M.x86.R_DI += inc;
2497                break;
2498            }
2499        }
2500		M.x86.R_CX = 0;
2501		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2502			M.x86.R_ECX = 0;
2503        }
2504		M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2505    } else {
2506        switch (size) {
2507          case 1:
2508			store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
2509								(*sys_inb)(M.x86.R_DX));
2510            break;
2511          case 2:
2512			store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
2513								(*sys_inw)(M.x86.R_DX));
2514            break;
2515          case 4:
2516			store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
2517								(*sys_inl)(M.x86.R_DX));
2518            break;
2519        }
2520		M.x86.R_DI += inc;
2521    }
2522}
2523
2524/****************************************************************************
2525REMARKS:
2526Implements the OUT string instruction and side effects.
2527****************************************************************************/
2528void outs(int size)
2529{
2530    int inc = size;
2531
2532	if (ACCESS_FLAG(F_DF)) {
2533        inc = -size;
2534    }
2535	if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2536        /* dont care whether REPE or REPNE */
2537        /* out until CX is ZERO. */
2538		u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
2539					 M.x86.R_ECX : M.x86.R_CX);
2540        switch (size) {
2541          case 1:
2542            while (count--) {
2543				(*sys_outb)(M.x86.R_DX,
2544						 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2545				M.x86.R_SI += inc;
2546            }
2547            break;
2548
2549          case 2:
2550            while (count--) {
2551				(*sys_outw)(M.x86.R_DX,
2552						 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2553				M.x86.R_SI += inc;
2554            }
2555            break;
2556          case 4:
2557            while (count--) {
2558				(*sys_outl)(M.x86.R_DX,
2559						 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2560				M.x86.R_SI += inc;
2561                break;
2562            }
2563        }
2564		M.x86.R_CX = 0;
2565		if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2566			M.x86.R_ECX = 0;
2567        }
2568		M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2569    } else {
2570        switch (size) {
2571          case 1:
2572			(*sys_outb)(M.x86.R_DX,
2573					 fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
2574            break;
2575          case 2:
2576			(*sys_outw)(M.x86.R_DX,
2577					 fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
2578            break;
2579          case 4:
2580			(*sys_outl)(M.x86.R_DX,
2581					 fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
2582            break;
2583        }
2584		M.x86.R_SI += inc;
2585    }
2586}
2587
2588/****************************************************************************
2589PARAMETERS:
2590addr	- Address to fetch word from
2591
2592REMARKS:
2593Fetches a word from emulator memory using an absolute address.
2594****************************************************************************/
2595u16 mem_access_word(int addr)
2596{
2597DB(	if (CHECK_MEM_ACCESS())
2598	  x86emu_check_mem_access(addr);)
2599	return (*sys_rdw)(addr);
2600}
2601
2602/****************************************************************************
2603REMARKS:
2604Pushes a word onto the stack.
2605
2606NOTE: Do not inline this, as (*sys_wrX) is already inline!
2607****************************************************************************/
2608void push_word(u16 w)
2609{
2610DB(	if (CHECK_SP_ACCESS())
2611	  x86emu_check_sp_access();)
2612	M.x86.R_SP -= 2;
2613	(*sys_wrw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);
2614}
2615
2616/****************************************************************************
2617REMARKS:
2618Pushes a long onto the stack.
2619
2620NOTE: Do not inline this, as (*sys_wrX) is already inline!
2621****************************************************************************/
2622void push_long(u32 w)
2623{
2624DB(	if (CHECK_SP_ACCESS())
2625	  x86emu_check_sp_access();)
2626	M.x86.R_SP -= 4;
2627	(*sys_wrl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);
2628}
2629
2630/****************************************************************************
2631REMARKS:
2632Pops a word from the stack.
2633
2634NOTE: Do not inline this, as (*sys_rdX) is already inline!
2635****************************************************************************/
2636u16 pop_word(void)
2637{
2638	register u16 res;
2639
2640DB(	if (CHECK_SP_ACCESS())
2641	  x86emu_check_sp_access();)
2642	res = (*sys_rdw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);
2643	M.x86.R_SP += 2;
2644	return res;
2645}
2646
2647/****************************************************************************
2648REMARKS:
2649Pops a long from the stack.
2650
2651NOTE: Do not inline this, as (*sys_rdX) is already inline!
2652****************************************************************************/
2653u32 pop_long(void)
2654{
2655    register u32 res;
2656
2657DB(	if (CHECK_SP_ACCESS())
2658	  x86emu_check_sp_access();)
2659	res = (*sys_rdl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);
2660	M.x86.R_SP += 4;
2661    return res;
2662}
2663
2664#ifdef	__HAVE_INLINE_ASSEMBLER__
2665
2666u16 aaa_word (u16 d)
2667{ return aaa_word_asm(&M.x86.R_EFLG,d); }
2668
2669u16 aas_word (u16 d)
2670{ return aas_word_asm(&M.x86.R_EFLG,d); }
2671
2672u16 aad_word (u16 d)
2673{ return aad_word_asm(&M.x86.R_EFLG,d); }
2674
2675u16 aam_word (u8 d)
2676{ return aam_word_asm(&M.x86.R_EFLG,d); }
2677
2678u8 adc_byte (u8 d, u8 s)
2679{ return adc_byte_asm(&M.x86.R_EFLG,d,s); }
2680
2681u16 adc_word (u16 d, u16 s)
2682{ return adc_word_asm(&M.x86.R_EFLG,d,s); }
2683
2684u32 adc_long (u32 d, u32 s)
2685{ return adc_long_asm(&M.x86.R_EFLG,d,s); }
2686
2687u8 add_byte (u8 d, u8 s)
2688{ return add_byte_asm(&M.x86.R_EFLG,d,s); }
2689
2690u16 add_word (u16 d, u16 s)
2691{ return add_word_asm(&M.x86.R_EFLG,d,s); }
2692
2693u32 add_long (u32 d, u32 s)
2694{ return add_long_asm(&M.x86.R_EFLG,d,s); }
2695
2696u8 and_byte (u8 d, u8 s)
2697{ return and_byte_asm(&M.x86.R_EFLG,d,s); }
2698
2699u16 and_word (u16 d, u16 s)
2700{ return and_word_asm(&M.x86.R_EFLG,d,s); }
2701
2702u32 and_long (u32 d, u32 s)
2703{ return and_long_asm(&M.x86.R_EFLG,d,s); }
2704
2705u8 cmp_byte (u8 d, u8 s)
2706{ return cmp_byte_asm(&M.x86.R_EFLG,d,s); }
2707
2708u16 cmp_word (u16 d, u16 s)
2709{ return cmp_word_asm(&M.x86.R_EFLG,d,s); }
2710
2711u32 cmp_long (u32 d, u32 s)
2712{ return cmp_long_asm(&M.x86.R_EFLG,d,s); }
2713
2714u8 daa_byte (u8 d)
2715{ return daa_byte_asm(&M.x86.R_EFLG,d); }
2716
2717u8 das_byte (u8 d)
2718{ return das_byte_asm(&M.x86.R_EFLG,d); }
2719
2720u8 dec_byte (u8 d)
2721{ return dec_byte_asm(&M.x86.R_EFLG,d); }
2722
2723u16 dec_word (u16 d)
2724{ return dec_word_asm(&M.x86.R_EFLG,d); }
2725
2726u32 dec_long (u32 d)
2727{ return dec_long_asm(&M.x86.R_EFLG,d); }
2728
2729u8 inc_byte (u8 d)
2730{ return inc_byte_asm(&M.x86.R_EFLG,d); }
2731
2732u16 inc_word (u16 d)
2733{ return inc_word_asm(&M.x86.R_EFLG,d); }
2734
2735u32 inc_long (u32 d)
2736{ return inc_long_asm(&M.x86.R_EFLG,d); }
2737
2738u8 or_byte (u8 d, u8 s)
2739{ return or_byte_asm(&M.x86.R_EFLG,d,s); }
2740
2741u16 or_word (u16 d, u16 s)
2742{ return or_word_asm(&M.x86.R_EFLG,d,s); }
2743
2744u32 or_long (u32 d, u32 s)
2745{ return or_long_asm(&M.x86.R_EFLG,d,s); }
2746
2747u8 neg_byte (u8 s)
2748{ return neg_byte_asm(&M.x86.R_EFLG,s); }
2749
2750u16 neg_word (u16 s)
2751{ return neg_word_asm(&M.x86.R_EFLG,s); }
2752
2753u32 neg_long (u32 s)
2754{ return neg_long_asm(&M.x86.R_EFLG,s); }
2755
2756u8 not_byte (u8 s)
2757{ return not_byte_asm(&M.x86.R_EFLG,s); }
2758
2759u16 not_word (u16 s)
2760{ return not_word_asm(&M.x86.R_EFLG,s); }
2761
2762u32 not_long (u32 s)
2763{ return not_long_asm(&M.x86.R_EFLG,s); }
2764
2765u8 rcl_byte (u8 d, u8 s)
2766{ return rcl_byte_asm(&M.x86.R_EFLG,d,s); }
2767
2768u16 rcl_word (u16 d, u8 s)
2769{ return rcl_word_asm(&M.x86.R_EFLG,d,s); }
2770
2771u32 rcl_long (u32 d, u8 s)
2772{ return rcl_long_asm(&M.x86.R_EFLG,d,s); }
2773
2774u8 rcr_byte (u8 d, u8 s)
2775{ return rcr_byte_asm(&M.x86.R_EFLG,d,s); }
2776
2777u16 rcr_word (u16 d, u8 s)
2778{ return rcr_word_asm(&M.x86.R_EFLG,d,s); }
2779
2780u32 rcr_long (u32 d, u8 s)
2781{ return rcr_long_asm(&M.x86.R_EFLG,d,s); }
2782
2783u8 rol_byte (u8 d, u8 s)
2784{ return rol_byte_asm(&M.x86.R_EFLG,d,s); }
2785
2786u16 rol_word (u16 d, u8 s)
2787{ return rol_word_asm(&M.x86.R_EFLG,d,s); }
2788
2789u32 rol_long (u32 d, u8 s)
2790{ return rol_long_asm(&M.x86.R_EFLG,d,s); }
2791
2792u8 ror_byte (u8 d, u8 s)
2793{ return ror_byte_asm(&M.x86.R_EFLG,d,s); }
2794
2795u16 ror_word (u16 d, u8 s)
2796{ return ror_word_asm(&M.x86.R_EFLG,d,s); }
2797
2798u32 ror_long (u32 d, u8 s)
2799{ return ror_long_asm(&M.x86.R_EFLG,d,s); }
2800
2801u8 shl_byte (u8 d, u8 s)
2802{ return shl_byte_asm(&M.x86.R_EFLG,d,s); }
2803
2804u16 shl_word (u16 d, u8 s)
2805{ return shl_word_asm(&M.x86.R_EFLG,d,s); }
2806
2807u32 shl_long (u32 d, u8 s)
2808{ return shl_long_asm(&M.x86.R_EFLG,d,s); }
2809
2810u8 shr_byte (u8 d, u8 s)
2811{ return shr_byte_asm(&M.x86.R_EFLG,d,s); }
2812
2813u16 shr_word (u16 d, u8 s)
2814{ return shr_word_asm(&M.x86.R_EFLG,d,s); }
2815
2816u32 shr_long (u32 d, u8 s)
2817{ return shr_long_asm(&M.x86.R_EFLG,d,s); }
2818
2819u8 sar_byte (u8 d, u8 s)
2820{ return sar_byte_asm(&M.x86.R_EFLG,d,s); }
2821
2822u16 sar_word (u16 d, u8 s)
2823{ return sar_word_asm(&M.x86.R_EFLG,d,s); }
2824
2825u32 sar_long (u32 d, u8 s)
2826{ return sar_long_asm(&M.x86.R_EFLG,d,s); }
2827
2828u16 shld_word (u16 d, u16 fill, u8 s)
2829{ return shld_word_asm(&M.x86.R_EFLG,d,fill,s); }
2830
2831u32 shld_long (u32 d, u32 fill, u8 s)
2832{ return shld_long_asm(&M.x86.R_EFLG,d,fill,s); }
2833
2834u16 shrd_word (u16 d, u16 fill, u8 s)
2835{ return shrd_word_asm(&M.x86.R_EFLG,d,fill,s); }
2836
2837u32 shrd_long (u32 d, u32 fill, u8 s)
2838{ return shrd_long_asm(&M.x86.R_EFLG,d,fill,s); }
2839
2840u8 sbb_byte (u8 d, u8 s)
2841{ return sbb_byte_asm(&M.x86.R_EFLG,d,s); }
2842
2843u16 sbb_word (u16 d, u16 s)
2844{ return sbb_word_asm(&M.x86.R_EFLG,d,s); }
2845
2846u32 sbb_long (u32 d, u32 s)
2847{ return sbb_long_asm(&M.x86.R_EFLG,d,s); }
2848
2849u8 sub_byte (u8 d, u8 s)
2850{ return sub_byte_asm(&M.x86.R_EFLG,d,s); }
2851
2852u16 sub_word (u16 d, u16 s)
2853{ return sub_word_asm(&M.x86.R_EFLG,d,s); }
2854
2855u32 sub_long (u32 d, u32 s)
2856{ return sub_long_asm(&M.x86.R_EFLG,d,s); }
2857
2858void test_byte (u8 d, u8 s)
2859{ test_byte_asm(&M.x86.R_EFLG,d,s); }
2860
2861void test_word (u16 d, u16 s)
2862{ test_word_asm(&M.x86.R_EFLG,d,s); }
2863
2864void test_long (u32 d, u32 s)
2865{ test_long_asm(&M.x86.R_EFLG,d,s); }
2866
2867u8 xor_byte (u8 d, u8 s)
2868{ return xor_byte_asm(&M.x86.R_EFLG,d,s); }
2869
2870u16 xor_word (u16 d, u16 s)
2871{ return xor_word_asm(&M.x86.R_EFLG,d,s); }
2872
2873u32 xor_long (u32 d, u32 s)
2874{ return xor_long_asm(&M.x86.R_EFLG,d,s); }
2875
2876void imul_byte (u8 s)
2877{ imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2878
2879void imul_word (u16 s)
2880{ imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2881
2882void imul_long (u32 s)
2883{ imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2884
2885void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
2886{ imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s); }
2887
2888void mul_byte (u8 s)
2889{ mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); }
2890
2891void mul_word (u16 s)
2892{ mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); }
2893
2894void mul_long (u32 s)
2895{ mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); }
2896
2897void idiv_byte (u8 s)
2898{ idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2899
2900void idiv_word (u16 s)
2901{ idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2902
2903void idiv_long (u32 s)
2904{ idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
2905
2906void div_byte (u8 s)
2907{ div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); }
2908
2909void div_word (u16 s)
2910{ div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); }
2911
2912void div_long (u32 s)
2913{ div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); }
2914
2915#endif
2916