Home | History | Annotate | Line # | Download | only in libx86emu
x86emu.c revision 1.10
      1  1.10     joerg /*	$NetBSD: x86emu.c,v 1.10 2014/08/04 21:41:44 joerg Exp $	*/
      2   1.1     joerg 
      3   1.1     joerg /****************************************************************************
      4   1.1     joerg *
      5   1.1     joerg *  Realmode X86 Emulator Library
      6   1.1     joerg *
      7   1.1     joerg *  Copyright (C) 1996-1999 SciTech Software, Inc.
      8   1.1     joerg *  Copyright (C) David Mosberger-Tang
      9   1.1     joerg *  Copyright (C) 1999 Egbert Eich
     10   1.1     joerg *  Copyright (C) 2007 Joerg Sonnenberger
     11   1.1     joerg *
     12   1.1     joerg *  ========================================================================
     13   1.1     joerg *
     14   1.1     joerg *  Permission to use, copy, modify, distribute, and sell this software and
     15   1.1     joerg *  its documentation for any purpose is hereby granted without fee,
     16   1.1     joerg *  provided that the above copyright notice appear in all copies and that
     17   1.1     joerg *  both that copyright notice and this permission notice appear in
     18   1.1     joerg *  supporting documentation, and that the name of the authors not be used
     19   1.1     joerg *  in advertising or publicity pertaining to distribution of the software
     20   1.1     joerg *  without specific, written prior permission.  The authors makes no
     21   1.1     joerg *  representations about the suitability of this software for any purpose.
     22   1.1     joerg *  It is provided "as is" without express or implied warranty.
     23   1.1     joerg *
     24   1.1     joerg *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     25   1.1     joerg *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     26   1.1     joerg *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     27   1.1     joerg *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     28   1.1     joerg *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     29   1.1     joerg *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     30   1.1     joerg *  PERFORMANCE OF THIS SOFTWARE.
     31   1.1     joerg *
     32   1.1     joerg ****************************************************************************/
     33   1.1     joerg 
     34   1.1     joerg #ifndef _KERNEL
     35   1.1     joerg #include <stdbool.h>
     36   1.1     joerg #endif
     37   1.1     joerg 
     38   1.2     joerg #include <x86emu/x86emu.h>
     39   1.2     joerg #include <x86emu/x86emu_regs.h>
     40   1.1     joerg 
     41   1.1     joerg static void 	x86emu_intr_raise (struct X86EMU *, uint8_t type);
     42   1.1     joerg 
     43   1.1     joerg static void	X86EMU_exec_one_byte(struct X86EMU *);
     44   1.1     joerg static void	X86EMU_exec_two_byte(struct X86EMU *);
     45   1.1     joerg 
     46   1.1     joerg static void	fetch_decode_modrm (struct X86EMU *);
     47   1.1     joerg static uint8_t	fetch_byte_imm (struct X86EMU *);
     48   1.1     joerg static uint16_t	fetch_word_imm (struct X86EMU *);
     49   1.1     joerg static uint32_t	fetch_long_imm (struct X86EMU *);
     50   1.1     joerg static uint8_t	fetch_data_byte (struct X86EMU *, uint32_t offset);
     51   1.1     joerg static uint8_t	fetch_byte (struct X86EMU *, uint segment, uint32_t offset);
     52   1.1     joerg static uint16_t	fetch_data_word (struct X86EMU *, uint32_t offset);
     53   1.1     joerg static uint16_t	fetch_word (struct X86EMU *, uint32_t segment, uint32_t offset);
     54   1.1     joerg static uint32_t	fetch_data_long (struct X86EMU *, uint32_t offset);
     55   1.1     joerg static uint32_t	fetch_long (struct X86EMU *, uint32_t segment, uint32_t offset);
     56   1.1     joerg static void	store_data_byte (struct X86EMU *, uint32_t offset, uint8_t val);
     57   1.1     joerg static void	store_byte (struct X86EMU *, uint32_t segment, uint32_t offset, uint8_t val);
     58   1.1     joerg static void	store_data_word (struct X86EMU *, uint32_t offset, uint16_t val);
     59   1.1     joerg static void	store_word (struct X86EMU *, uint32_t segment, uint32_t offset, uint16_t val);
     60   1.1     joerg static void	store_data_long (struct X86EMU *, uint32_t offset, uint32_t val);
     61   1.1     joerg static void	store_long (struct X86EMU *, uint32_t segment, uint32_t offset, uint32_t val);
     62   1.1     joerg static uint8_t*	decode_rl_byte_register(struct X86EMU *);
     63   1.1     joerg static uint16_t*	decode_rl_word_register(struct X86EMU *);
     64   1.1     joerg static uint32_t* 	decode_rl_long_register(struct X86EMU *);
     65   1.1     joerg static uint8_t* 	decode_rh_byte_register(struct X86EMU *);
     66   1.1     joerg static uint16_t* 	decode_rh_word_register(struct X86EMU *);
     67   1.1     joerg static uint32_t* 	decode_rh_long_register(struct X86EMU *);
     68   1.1     joerg static uint16_t* 	decode_rh_seg_register(struct X86EMU *);
     69   1.1     joerg static uint32_t	decode_rl_address(struct X86EMU *);
     70   1.1     joerg 
     71   1.1     joerg static uint8_t 	decode_and_fetch_byte(struct X86EMU *);
     72   1.1     joerg static uint16_t 	decode_and_fetch_word(struct X86EMU *);
     73   1.1     joerg static uint32_t 	decode_and_fetch_long(struct X86EMU *);
     74   1.1     joerg 
     75   1.1     joerg static uint8_t 	decode_and_fetch_byte_imm8(struct X86EMU *, uint8_t *);
     76   1.1     joerg static uint16_t 	decode_and_fetch_word_imm8(struct X86EMU *, uint8_t *);
     77   1.1     joerg static uint32_t 	decode_and_fetch_long_imm8(struct X86EMU *, uint8_t *);
     78   1.1     joerg 
     79   1.1     joerg static uint16_t 	decode_and_fetch_word_disp(struct X86EMU *, int16_t);
     80   1.1     joerg static uint32_t 	decode_and_fetch_long_disp(struct X86EMU *, int16_t);
     81   1.1     joerg 
     82   1.1     joerg static void	write_back_byte(struct X86EMU *, uint8_t);
     83   1.1     joerg static void	write_back_word(struct X86EMU *, uint16_t);
     84   1.1     joerg static void	write_back_long(struct X86EMU *, uint32_t);
     85   1.1     joerg 
     86   1.1     joerg static uint16_t	aaa_word (struct X86EMU *, uint16_t d);
     87   1.1     joerg static uint16_t	aas_word (struct X86EMU *, uint16_t d);
     88   1.1     joerg static uint16_t	aad_word (struct X86EMU *, uint16_t d);
     89   1.1     joerg static uint16_t	aam_word (struct X86EMU *, uint8_t d);
     90   1.1     joerg static uint8_t	adc_byte (struct X86EMU *, uint8_t d, uint8_t s);
     91   1.1     joerg static uint16_t	adc_word (struct X86EMU *, uint16_t d, uint16_t s);
     92   1.1     joerg static uint32_t	adc_long (struct X86EMU *, uint32_t d, uint32_t s);
     93   1.1     joerg static uint8_t	add_byte (struct X86EMU *, uint8_t d, uint8_t s);
     94   1.1     joerg static uint16_t	add_word (struct X86EMU *, uint16_t d, uint16_t s);
     95   1.1     joerg static uint32_t	add_long (struct X86EMU *, uint32_t d, uint32_t s);
     96   1.1     joerg static uint8_t	and_byte (struct X86EMU *, uint8_t d, uint8_t s);
     97   1.1     joerg static uint16_t	and_word (struct X86EMU *, uint16_t d, uint16_t s);
     98   1.1     joerg static uint32_t	and_long (struct X86EMU *, uint32_t d, uint32_t s);
     99   1.1     joerg static uint8_t	cmp_byte (struct X86EMU *, uint8_t d, uint8_t s);
    100   1.1     joerg static uint16_t	cmp_word (struct X86EMU *, uint16_t d, uint16_t s);
    101   1.1     joerg static uint32_t	cmp_long (struct X86EMU *, uint32_t d, uint32_t s);
    102   1.1     joerg static void	cmp_byte_no_return (struct X86EMU *, uint8_t d, uint8_t s);
    103   1.1     joerg static void	cmp_word_no_return (struct X86EMU *, uint16_t d, uint16_t s);
    104   1.1     joerg static void	cmp_long_no_return (struct X86EMU *, uint32_t d, uint32_t s);
    105   1.1     joerg static uint8_t	daa_byte (struct X86EMU *, uint8_t d);
    106   1.1     joerg static uint8_t	das_byte (struct X86EMU *, uint8_t d);
    107   1.1     joerg static uint8_t	dec_byte (struct X86EMU *, uint8_t d);
    108   1.1     joerg static uint16_t	dec_word (struct X86EMU *, uint16_t d);
    109   1.1     joerg static uint32_t	dec_long (struct X86EMU *, uint32_t d);
    110   1.1     joerg static uint8_t	inc_byte (struct X86EMU *, uint8_t d);
    111   1.1     joerg static uint16_t	inc_word (struct X86EMU *, uint16_t d);
    112   1.1     joerg static uint32_t	inc_long (struct X86EMU *, uint32_t d);
    113   1.1     joerg static uint8_t	or_byte (struct X86EMU *, uint8_t d, uint8_t s);
    114   1.1     joerg static uint16_t	or_word (struct X86EMU *, uint16_t d, uint16_t s);
    115   1.1     joerg static uint32_t	or_long (struct X86EMU *, uint32_t d, uint32_t s);
    116   1.1     joerg static uint8_t	neg_byte (struct X86EMU *, uint8_t s);
    117   1.1     joerg static uint16_t	neg_word (struct X86EMU *, uint16_t s);
    118   1.1     joerg static uint32_t	neg_long (struct X86EMU *, uint32_t s);
    119   1.1     joerg static uint8_t	rcl_byte (struct X86EMU *, uint8_t d, uint8_t s);
    120   1.1     joerg static uint16_t	rcl_word (struct X86EMU *, uint16_t d, uint8_t s);
    121   1.1     joerg static uint32_t	rcl_long (struct X86EMU *, uint32_t d, uint8_t s);
    122   1.1     joerg static uint8_t	rcr_byte (struct X86EMU *, uint8_t d, uint8_t s);
    123   1.1     joerg static uint16_t	rcr_word (struct X86EMU *, uint16_t d, uint8_t s);
    124   1.1     joerg static uint32_t	rcr_long (struct X86EMU *, uint32_t d, uint8_t s);
    125   1.1     joerg static uint8_t	rol_byte (struct X86EMU *, uint8_t d, uint8_t s);
    126   1.1     joerg static uint16_t	rol_word (struct X86EMU *, uint16_t d, uint8_t s);
    127   1.1     joerg static uint32_t	rol_long (struct X86EMU *, uint32_t d, uint8_t s);
    128   1.1     joerg static uint8_t	ror_byte (struct X86EMU *, uint8_t d, uint8_t s);
    129   1.1     joerg static uint16_t	ror_word (struct X86EMU *, uint16_t d, uint8_t s);
    130   1.1     joerg static uint32_t	ror_long (struct X86EMU *, uint32_t d, uint8_t s);
    131   1.1     joerg static uint8_t	shl_byte (struct X86EMU *, uint8_t d, uint8_t s);
    132   1.1     joerg static uint16_t	shl_word (struct X86EMU *, uint16_t d, uint8_t s);
    133   1.1     joerg static uint32_t	shl_long (struct X86EMU *, uint32_t d, uint8_t s);
    134   1.1     joerg static uint8_t	shr_byte (struct X86EMU *, uint8_t d, uint8_t s);
    135   1.1     joerg static uint16_t	shr_word (struct X86EMU *, uint16_t d, uint8_t s);
    136   1.1     joerg static uint32_t	shr_long (struct X86EMU *, uint32_t d, uint8_t s);
    137   1.1     joerg static uint8_t	sar_byte (struct X86EMU *, uint8_t d, uint8_t s);
    138   1.1     joerg static uint16_t	sar_word (struct X86EMU *, uint16_t d, uint8_t s);
    139   1.1     joerg static uint32_t	sar_long (struct X86EMU *, uint32_t d, uint8_t s);
    140   1.1     joerg static uint16_t	shld_word (struct X86EMU *, uint16_t d, uint16_t fill, uint8_t s);
    141   1.1     joerg static uint32_t	shld_long (struct X86EMU *, uint32_t d, uint32_t fill, uint8_t s);
    142   1.1     joerg static uint16_t	shrd_word (struct X86EMU *, uint16_t d, uint16_t fill, uint8_t s);
    143   1.1     joerg static uint32_t	shrd_long (struct X86EMU *, uint32_t d, uint32_t fill, uint8_t s);
    144   1.1     joerg static uint8_t	sbb_byte (struct X86EMU *, uint8_t d, uint8_t s);
    145   1.1     joerg static uint16_t	sbb_word (struct X86EMU *, uint16_t d, uint16_t s);
    146   1.1     joerg static uint32_t	sbb_long (struct X86EMU *, uint32_t d, uint32_t s);
    147   1.1     joerg static uint8_t	sub_byte (struct X86EMU *, uint8_t d, uint8_t s);
    148   1.1     joerg static uint16_t	sub_word (struct X86EMU *, uint16_t d, uint16_t s);
    149   1.1     joerg static uint32_t	sub_long (struct X86EMU *, uint32_t d, uint32_t s);
    150   1.1     joerg static void	test_byte (struct X86EMU *, uint8_t d, uint8_t s);
    151   1.1     joerg static void	test_word (struct X86EMU *, uint16_t d, uint16_t s);
    152   1.1     joerg static void	test_long (struct X86EMU *, uint32_t d, uint32_t s);
    153   1.1     joerg static uint8_t	xor_byte (struct X86EMU *, uint8_t d, uint8_t s);
    154   1.1     joerg static uint16_t	xor_word (struct X86EMU *, uint16_t d, uint16_t s);
    155   1.1     joerg static uint32_t	xor_long (struct X86EMU *, uint32_t d, uint32_t s);
    156   1.1     joerg static void	imul_byte (struct X86EMU *, uint8_t s);
    157   1.1     joerg static void	imul_word (struct X86EMU *, uint16_t s);
    158   1.1     joerg static void	imul_long (struct X86EMU *, uint32_t s);
    159   1.1     joerg static void	mul_byte (struct X86EMU *, uint8_t s);
    160   1.1     joerg static void	mul_word (struct X86EMU *, uint16_t s);
    161   1.1     joerg static void	mul_long (struct X86EMU *, uint32_t s);
    162   1.1     joerg static void	idiv_byte (struct X86EMU *, uint8_t s);
    163   1.1     joerg static void	idiv_word (struct X86EMU *, uint16_t s);
    164   1.1     joerg static void	idiv_long (struct X86EMU *, uint32_t s);
    165   1.1     joerg static void	div_byte (struct X86EMU *, uint8_t s);
    166   1.1     joerg static void	div_word (struct X86EMU *, uint16_t s);
    167   1.1     joerg static void	div_long (struct X86EMU *, uint32_t s);
    168   1.1     joerg static void	ins (struct X86EMU *, int size);
    169   1.1     joerg static void	outs (struct X86EMU *, int size);
    170   1.1     joerg static void	push_word (struct X86EMU *, uint16_t w);
    171   1.1     joerg static void	push_long (struct X86EMU *, uint32_t w);
    172   1.1     joerg static uint16_t	pop_word (struct X86EMU *);
    173   1.1     joerg static uint32_t	pop_long (struct X86EMU *);
    174   1.1     joerg 
    175   1.1     joerg /****************************************************************************
    176   1.1     joerg REMARKS:
    177   1.1     joerg Handles any pending asychronous interrupts.
    178   1.1     joerg ****************************************************************************/
    179   1.3     joerg static void
    180   1.3     joerg x86emu_intr_dispatch(struct X86EMU *emu, uint8_t intno)
    181   1.3     joerg {
    182   1.3     joerg 	if (emu->_X86EMU_intrTab[intno]) {
    183   1.3     joerg 		(*emu->_X86EMU_intrTab[intno]) (emu, intno);
    184   1.3     joerg 	} else {
    185   1.3     joerg 		push_word(emu, (uint16_t) emu->x86.R_FLG);
    186   1.3     joerg 		CLEAR_FLAG(F_IF);
    187   1.3     joerg 		CLEAR_FLAG(F_TF);
    188   1.3     joerg 		push_word(emu, emu->x86.R_CS);
    189   1.3     joerg 		emu->x86.R_CS = fetch_word(emu, 0, intno * 4 + 2);
    190   1.3     joerg 		push_word(emu, emu->x86.R_IP);
    191   1.3     joerg 		emu->x86.R_IP = fetch_word(emu, 0, intno * 4);
    192   1.3     joerg 	}
    193   1.3     joerg }
    194   1.3     joerg 
    195   1.1     joerg static void
    196   1.1     joerg x86emu_intr_handle(struct X86EMU *emu)
    197   1.1     joerg {
    198   1.1     joerg 	uint8_t intno;
    199   1.1     joerg 
    200   1.1     joerg 	if (emu->x86.intr & INTR_SYNCH) {
    201   1.1     joerg 		intno = emu->x86.intno;
    202   1.3     joerg 		emu->x86.intr = 0;
    203   1.3     joerg 		x86emu_intr_dispatch(emu, intno);
    204   1.1     joerg 	}
    205   1.1     joerg }
    206   1.1     joerg /****************************************************************************
    207   1.1     joerg PARAMETERS:
    208   1.1     joerg intrnum - Interrupt number to raise
    209   1.1     joerg 
    210   1.1     joerg REMARKS:
    211   1.1     joerg Raise the specified interrupt to be handled before the execution of the
    212   1.1     joerg next instruction.
    213   1.1     joerg ****************************************************************************/
    214   1.1     joerg void
    215   1.1     joerg x86emu_intr_raise(struct X86EMU *emu, uint8_t intrnum)
    216   1.1     joerg {
    217   1.1     joerg 	emu->x86.intno = intrnum;
    218   1.1     joerg 	emu->x86.intr |= INTR_SYNCH;
    219   1.1     joerg }
    220   1.1     joerg /****************************************************************************
    221   1.1     joerg REMARKS:
    222   1.1     joerg Main execution loop for the emulator. We return from here when the system
    223   1.1     joerg halts, which is normally caused by a stack fault when we return from the
    224   1.1     joerg original real mode call.
    225   1.1     joerg ****************************************************************************/
    226   1.1     joerg void
    227   1.1     joerg X86EMU_exec(struct X86EMU *emu)
    228   1.1     joerg {
    229   1.1     joerg 	emu->x86.intr = 0;
    230   1.1     joerg 
    231   1.1     joerg #ifdef _KERNEL
    232   1.1     joerg 	if (setjmp(&emu->exec_state))
    233   1.1     joerg 		return;
    234   1.1     joerg #else
    235   1.1     joerg 	if (setjmp(emu->exec_state))
    236   1.1     joerg 		return;
    237   1.1     joerg #endif
    238   1.1     joerg 
    239   1.1     joerg 	for (;;) {
    240   1.1     joerg 		if (emu->x86.intr) {
    241   1.1     joerg 			if (((emu->x86.intr & INTR_SYNCH) && (emu->x86.intno == 0 || emu->x86.intno == 2)) ||
    242   1.1     joerg 			    !ACCESS_FLAG(F_IF)) {
    243   1.1     joerg 				x86emu_intr_handle(emu);
    244   1.1     joerg 			}
    245   1.1     joerg 		}
    246   1.7     joerg 		if (emu->x86.R_CS == 0 && emu->x86.R_IP == 0)
    247   1.7     joerg 			return;
    248   1.1     joerg 		X86EMU_exec_one_byte(emu);
    249   1.1     joerg 		++emu->cur_cycles;
    250   1.1     joerg 	}
    251   1.1     joerg }
    252   1.1     joerg 
    253   1.1     joerg void
    254   1.1     joerg X86EMU_exec_call(struct X86EMU *emu, uint16_t seg, uint16_t off)
    255   1.1     joerg {
    256   1.1     joerg 	push_word(emu, 0);
    257   1.1     joerg 	push_word(emu, 0);
    258   1.1     joerg 	emu->x86.R_CS = seg;
    259   1.1     joerg 	emu->x86.R_IP = off;
    260   1.1     joerg 
    261   1.1     joerg 	X86EMU_exec(emu);
    262   1.1     joerg }
    263   1.1     joerg 
    264   1.1     joerg void
    265   1.1     joerg X86EMU_exec_intr(struct X86EMU *emu, uint8_t intr)
    266   1.1     joerg {
    267   1.1     joerg 	push_word(emu, emu->x86.R_FLG);
    268   1.1     joerg 	CLEAR_FLAG(F_IF);
    269   1.1     joerg 	CLEAR_FLAG(F_TF);
    270   1.1     joerg 	push_word(emu, 0);
    271   1.1     joerg 	push_word(emu, 0);
    272   1.1     joerg 	emu->x86.R_CS = (*emu->emu_rdw)(emu, intr * 4 + 2);
    273   1.1     joerg 	emu->x86.R_IP = (*emu->emu_rdw)(emu, intr * 4);
    274   1.1     joerg 	emu->x86.intr = 0;
    275   1.1     joerg 
    276   1.1     joerg 	X86EMU_exec(emu);
    277   1.1     joerg }
    278   1.1     joerg /****************************************************************************
    279   1.1     joerg REMARKS:
    280   1.1     joerg Halts the system by setting the halted system flag.
    281   1.1     joerg ****************************************************************************/
    282   1.1     joerg void
    283   1.1     joerg X86EMU_halt_sys(struct X86EMU *emu)
    284   1.1     joerg {
    285   1.1     joerg #ifdef _KERNEL
    286   1.1     joerg 	longjmp(&emu->exec_state);
    287   1.1     joerg #else
    288   1.1     joerg 	longjmp(emu->exec_state, 1);
    289   1.1     joerg #endif
    290   1.1     joerg }
    291   1.1     joerg /****************************************************************************
    292   1.1     joerg PARAMETERS:
    293   1.1     joerg mod		- Mod value from decoded byte
    294   1.1     joerg regh	- Reg h value from decoded byte
    295   1.1     joerg regl	- Reg l value from decoded byte
    296   1.1     joerg 
    297   1.1     joerg REMARKS:
    298   1.1     joerg Raise the specified interrupt to be handled before the execution of the
    299   1.1     joerg next instruction.
    300   1.1     joerg 
    301   1.1     joerg NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
    302   1.1     joerg ****************************************************************************/
    303   1.1     joerg static void
    304   1.1     joerg fetch_decode_modrm(struct X86EMU *emu)
    305   1.1     joerg {
    306   1.1     joerg 	int fetched;
    307   1.1     joerg 
    308   1.1     joerg 	fetched = fetch_byte_imm(emu);
    309   1.1     joerg 	emu->cur_mod = (fetched >> 6) & 0x03;
    310   1.1     joerg 	emu->cur_rh = (fetched >> 3) & 0x07;
    311   1.1     joerg 	emu->cur_rl = (fetched >> 0) & 0x07;
    312   1.1     joerg }
    313   1.1     joerg /****************************************************************************
    314   1.1     joerg RETURNS:
    315   1.1     joerg Immediate byte value read from instruction queue
    316   1.1     joerg 
    317   1.1     joerg REMARKS:
    318   1.1     joerg This function returns the immediate byte from the instruction queue, and
    319   1.1     joerg moves the instruction pointer to the next value.
    320   1.1     joerg 
    321   1.1     joerg NOTE: Do not inline this function, as (*emu->emu_rdb) is already inline!
    322   1.1     joerg ****************************************************************************/
    323   1.1     joerg static uint8_t
    324   1.1     joerg fetch_byte_imm(struct X86EMU *emu)
    325   1.1     joerg {
    326   1.1     joerg 	uint8_t fetched;
    327   1.1     joerg 
    328   1.1     joerg 	fetched = fetch_byte(emu, emu->x86.R_CS, emu->x86.R_IP);
    329   1.1     joerg 	emu->x86.R_IP++;
    330   1.1     joerg 	return fetched;
    331   1.1     joerg }
    332   1.1     joerg /****************************************************************************
    333   1.1     joerg RETURNS:
    334   1.1     joerg Immediate word value read from instruction queue
    335   1.1     joerg 
    336   1.1     joerg REMARKS:
    337   1.1     joerg This function returns the immediate byte from the instruction queue, and
    338   1.1     joerg moves the instruction pointer to the next value.
    339   1.1     joerg 
    340   1.1     joerg NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
    341   1.1     joerg ****************************************************************************/
    342   1.1     joerg static uint16_t
    343   1.1     joerg fetch_word_imm(struct X86EMU *emu)
    344   1.1     joerg {
    345   1.1     joerg 	uint16_t fetched;
    346   1.1     joerg 
    347   1.1     joerg 	fetched = fetch_word(emu, emu->x86.R_CS, emu->x86.R_IP);
    348   1.1     joerg 	emu->x86.R_IP += 2;
    349   1.1     joerg 	return fetched;
    350   1.1     joerg }
    351   1.1     joerg /****************************************************************************
    352   1.1     joerg RETURNS:
    353   1.1     joerg Immediate lone value read from instruction queue
    354   1.1     joerg 
    355   1.1     joerg REMARKS:
    356   1.1     joerg This function returns the immediate byte from the instruction queue, and
    357   1.1     joerg moves the instruction pointer to the next value.
    358   1.1     joerg 
    359   1.1     joerg NOTE: Do not inline this function, as (*emu->emu_rdw) is already inline!
    360   1.1     joerg ****************************************************************************/
    361   1.1     joerg static uint32_t
    362   1.1     joerg fetch_long_imm(struct X86EMU *emu)
    363   1.1     joerg {
    364   1.1     joerg 	uint32_t fetched;
    365   1.1     joerg 
    366   1.1     joerg 	fetched = fetch_long(emu, emu->x86.R_CS, emu->x86.R_IP);
    367   1.1     joerg 	emu->x86.R_IP += 4;
    368   1.1     joerg 	return fetched;
    369   1.1     joerg }
    370   1.1     joerg /****************************************************************************
    371   1.1     joerg RETURNS:
    372   1.1     joerg Value of the default data segment
    373   1.1     joerg 
    374   1.1     joerg REMARKS:
    375   1.1     joerg Inline function that returns the default data segment for the current
    376   1.1     joerg instruction.
    377   1.1     joerg 
    378   1.1     joerg On the x86 processor, the default segment is not always DS if there is
    379   1.1     joerg no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
    380   1.1     joerg addresses relative to SS (ie: on the stack). So, at the minimum, all
    381   1.1     joerg decodings of addressing modes would have to set/clear a bit describing
    382   1.1     joerg whether the access is relative to DS or SS.  That is the function of the
    383   1.1     joerg cpu-state-varible emu->x86.mode. There are several potential states:
    384   1.1     joerg 
    385   1.1     joerg 	repe prefix seen  (handled elsewhere)
    386   1.1     joerg 	repne prefix seen  (ditto)
    387   1.1     joerg 
    388   1.1     joerg 	cs segment override
    389   1.1     joerg 	ds segment override
    390   1.1     joerg 	es segment override
    391   1.1     joerg 	fs segment override
    392   1.1     joerg 	gs segment override
    393   1.1     joerg 	ss segment override
    394   1.1     joerg 
    395   1.1     joerg 	ds/ss select (in absense of override)
    396   1.1     joerg 
    397   1.1     joerg Each of the above 7 items are handled with a bit in the mode field.
    398   1.1     joerg ****************************************************************************/
    399   1.1     joerg static uint32_t
    400   1.1     joerg get_data_segment(struct X86EMU *emu)
    401   1.1     joerg {
    402   1.1     joerg 	switch (emu->x86.mode & SYSMODE_SEGMASK) {
    403   1.1     joerg 	case 0:		/* default case: use ds register */
    404   1.1     joerg 	case SYSMODE_SEGOVR_DS:
    405   1.1     joerg 	case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
    406   1.1     joerg 		return emu->x86.R_DS;
    407   1.1     joerg 	case SYSMODE_SEG_DS_SS:/* non-overridden, use ss register */
    408   1.1     joerg 		return emu->x86.R_SS;
    409   1.1     joerg 	case SYSMODE_SEGOVR_CS:
    410   1.1     joerg 	case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
    411   1.1     joerg 		return emu->x86.R_CS;
    412   1.1     joerg 	case SYSMODE_SEGOVR_ES:
    413   1.1     joerg 	case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
    414   1.1     joerg 		return emu->x86.R_ES;
    415   1.1     joerg 	case SYSMODE_SEGOVR_FS:
    416   1.1     joerg 	case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
    417   1.1     joerg 		return emu->x86.R_FS;
    418   1.1     joerg 	case SYSMODE_SEGOVR_GS:
    419   1.1     joerg 	case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
    420   1.1     joerg 		return emu->x86.R_GS;
    421   1.1     joerg 	case SYSMODE_SEGOVR_SS:
    422   1.1     joerg 	case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
    423   1.1     joerg 		return emu->x86.R_SS;
    424   1.1     joerg 	}
    425   1.1     joerg 	X86EMU_halt_sys(emu);
    426   1.1     joerg }
    427   1.1     joerg /****************************************************************************
    428   1.1     joerg PARAMETERS:
    429   1.1     joerg offset	- Offset to load data from
    430   1.1     joerg 
    431   1.1     joerg RETURNS:
    432   1.1     joerg Byte value read from the absolute memory location.
    433   1.1     joerg 
    434   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    435   1.1     joerg ****************************************************************************/
    436   1.1     joerg static uint8_t
    437   1.1     joerg fetch_data_byte(struct X86EMU *emu, uint32_t offset)
    438   1.1     joerg {
    439   1.1     joerg 	return fetch_byte(emu, get_data_segment(emu), offset);
    440   1.1     joerg }
    441   1.1     joerg /****************************************************************************
    442   1.1     joerg PARAMETERS:
    443   1.1     joerg offset	- Offset to load data from
    444   1.1     joerg 
    445   1.1     joerg RETURNS:
    446   1.1     joerg Word value read from the absolute memory location.
    447   1.1     joerg 
    448   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    449   1.1     joerg ****************************************************************************/
    450   1.1     joerg static uint16_t
    451   1.1     joerg fetch_data_word(struct X86EMU *emu, uint32_t offset)
    452   1.1     joerg {
    453   1.1     joerg 	return fetch_word(emu, get_data_segment(emu), offset);
    454   1.1     joerg }
    455   1.1     joerg /****************************************************************************
    456   1.1     joerg PARAMETERS:
    457   1.1     joerg offset	- Offset to load data from
    458   1.1     joerg 
    459   1.1     joerg RETURNS:
    460   1.1     joerg Long value read from the absolute memory location.
    461   1.1     joerg 
    462   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    463   1.1     joerg ****************************************************************************/
    464   1.1     joerg static uint32_t
    465   1.1     joerg fetch_data_long(struct X86EMU *emu, uint32_t offset)
    466   1.1     joerg {
    467   1.1     joerg 	return fetch_long(emu, get_data_segment(emu), offset);
    468   1.1     joerg }
    469   1.1     joerg /****************************************************************************
    470   1.1     joerg PARAMETERS:
    471   1.1     joerg segment	- Segment to load data from
    472   1.1     joerg offset	- Offset to load data from
    473   1.1     joerg 
    474   1.1     joerg RETURNS:
    475   1.1     joerg Byte value read from the absolute memory location.
    476   1.1     joerg 
    477   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    478   1.1     joerg ****************************************************************************/
    479   1.1     joerg static uint8_t
    480   1.1     joerg fetch_byte(struct X86EMU *emu, uint32_t segment, uint32_t offset)
    481   1.1     joerg {
    482   1.1     joerg 	return (*emu->emu_rdb) (emu, ((uint32_t) segment << 4) + offset);
    483   1.1     joerg }
    484   1.1     joerg /****************************************************************************
    485   1.1     joerg PARAMETERS:
    486   1.1     joerg segment	- Segment to load data from
    487   1.1     joerg offset	- Offset to load data from
    488   1.1     joerg 
    489   1.1     joerg RETURNS:
    490   1.1     joerg Word value read from the absolute memory location.
    491   1.1     joerg 
    492   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    493   1.1     joerg ****************************************************************************/
    494   1.1     joerg static uint16_t
    495   1.1     joerg fetch_word(struct X86EMU *emu, uint32_t segment, uint32_t offset)
    496   1.1     joerg {
    497   1.1     joerg 	return (*emu->emu_rdw) (emu, ((uint32_t) segment << 4) + offset);
    498   1.1     joerg }
    499   1.1     joerg /****************************************************************************
    500   1.1     joerg PARAMETERS:
    501   1.1     joerg segment	- Segment to load data from
    502   1.1     joerg offset	- Offset to load data from
    503   1.1     joerg 
    504   1.1     joerg RETURNS:
    505   1.1     joerg Long value read from the absolute memory location.
    506   1.1     joerg 
    507   1.1     joerg NOTE: Do not inline this function as (*emu->emu_rdX) is already inline!
    508   1.1     joerg ****************************************************************************/
    509   1.1     joerg static uint32_t
    510   1.1     joerg fetch_long(struct X86EMU *emu, uint32_t segment, uint32_t offset)
    511   1.1     joerg {
    512   1.1     joerg 	return (*emu->emu_rdl) (emu, ((uint32_t) segment << 4) + offset);
    513   1.1     joerg }
    514   1.1     joerg /****************************************************************************
    515   1.1     joerg PARAMETERS:
    516   1.1     joerg offset	- Offset to store data at
    517   1.1     joerg val		- Value to store
    518   1.1     joerg 
    519   1.1     joerg REMARKS:
    520   1.1     joerg Writes a word value to an segmented memory location. The segment used is
    521   1.1     joerg the current 'default' segment, which may have been overridden.
    522   1.1     joerg 
    523   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    524   1.1     joerg ****************************************************************************/
    525   1.1     joerg static void
    526   1.1     joerg store_data_byte(struct X86EMU *emu, uint32_t offset, uint8_t val)
    527   1.1     joerg {
    528   1.1     joerg 	store_byte(emu, get_data_segment(emu), offset, val);
    529   1.1     joerg }
    530   1.1     joerg /****************************************************************************
    531   1.1     joerg PARAMETERS:
    532   1.1     joerg offset	- Offset to store data at
    533   1.1     joerg val		- Value to store
    534   1.1     joerg 
    535   1.1     joerg REMARKS:
    536   1.1     joerg Writes a word value to an segmented memory location. The segment used is
    537   1.1     joerg the current 'default' segment, which may have been overridden.
    538   1.1     joerg 
    539   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    540   1.1     joerg ****************************************************************************/
    541   1.1     joerg static void
    542   1.1     joerg store_data_word(struct X86EMU *emu, uint32_t offset, uint16_t val)
    543   1.1     joerg {
    544   1.1     joerg 	store_word(emu, get_data_segment(emu), offset, val);
    545   1.1     joerg }
    546   1.1     joerg /****************************************************************************
    547   1.1     joerg PARAMETERS:
    548   1.1     joerg offset	- Offset to store data at
    549   1.1     joerg val		- Value to store
    550   1.1     joerg 
    551   1.1     joerg REMARKS:
    552   1.1     joerg Writes a long value to an segmented memory location. The segment used is
    553   1.1     joerg the current 'default' segment, which may have been overridden.
    554   1.1     joerg 
    555   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    556   1.1     joerg ****************************************************************************/
    557   1.1     joerg static void
    558   1.1     joerg store_data_long(struct X86EMU *emu, uint32_t offset, uint32_t val)
    559   1.1     joerg {
    560   1.1     joerg 	store_long(emu, get_data_segment(emu), offset, val);
    561   1.1     joerg }
    562   1.1     joerg /****************************************************************************
    563   1.1     joerg PARAMETERS:
    564   1.1     joerg segment	- Segment to store data at
    565   1.1     joerg offset	- Offset to store data at
    566   1.1     joerg val		- Value to store
    567   1.1     joerg 
    568   1.1     joerg REMARKS:
    569   1.1     joerg Writes a byte value to an absolute memory location.
    570   1.1     joerg 
    571   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    572   1.1     joerg ****************************************************************************/
    573   1.1     joerg static void
    574   1.1     joerg store_byte(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint8_t val)
    575   1.1     joerg {
    576   1.1     joerg 	(*emu->emu_wrb) (emu, ((uint32_t) segment << 4) + offset, val);
    577   1.1     joerg }
    578   1.1     joerg /****************************************************************************
    579   1.1     joerg PARAMETERS:
    580   1.1     joerg segment	- Segment to store data at
    581   1.1     joerg offset	- Offset to store data at
    582   1.1     joerg val		- Value to store
    583   1.1     joerg 
    584   1.1     joerg REMARKS:
    585   1.1     joerg Writes a word value to an absolute memory location.
    586   1.1     joerg 
    587   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    588   1.1     joerg ****************************************************************************/
    589   1.1     joerg static void
    590   1.1     joerg store_word(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint16_t val)
    591   1.1     joerg {
    592   1.1     joerg 	(*emu->emu_wrw) (emu, ((uint32_t) segment << 4) + offset, val);
    593   1.1     joerg }
    594   1.1     joerg /****************************************************************************
    595   1.1     joerg PARAMETERS:
    596   1.1     joerg segment	- Segment to store data at
    597   1.1     joerg offset	- Offset to store data at
    598   1.1     joerg val		- Value to store
    599   1.1     joerg 
    600   1.1     joerg REMARKS:
    601   1.1     joerg Writes a long value to an absolute memory location.
    602   1.1     joerg 
    603   1.1     joerg NOTE: Do not inline this function as (*emu->emu_wrX) is already inline!
    604   1.1     joerg ****************************************************************************/
    605   1.1     joerg static void
    606   1.1     joerg store_long(struct X86EMU *emu, uint32_t segment, uint32_t offset, uint32_t val)
    607   1.1     joerg {
    608   1.1     joerg 	(*emu->emu_wrl) (emu, ((uint32_t) segment << 4) + offset, val);
    609   1.1     joerg }
    610   1.1     joerg /****************************************************************************
    611   1.1     joerg PARAMETERS:
    612   1.1     joerg reg	- Register to decode
    613   1.1     joerg 
    614   1.1     joerg RETURNS:
    615   1.1     joerg Pointer to the appropriate register
    616   1.1     joerg 
    617   1.1     joerg REMARKS:
    618   1.1     joerg Return a pointer to the register given by the R/RM field of the
    619   1.1     joerg modrm byte, for byte operands. Also enables the decoding of instructions.
    620   1.1     joerg ****************************************************************************/
    621   1.1     joerg static uint8_t *
    622   1.1     joerg decode_rm_byte_register(struct X86EMU *emu, int reg)
    623   1.1     joerg {
    624   1.1     joerg 	switch (reg) {
    625   1.1     joerg 	case 0:
    626   1.1     joerg 		return &emu->x86.R_AL;
    627   1.1     joerg 	case 1:
    628   1.1     joerg 		return &emu->x86.R_CL;
    629   1.1     joerg 	case 2:
    630   1.1     joerg 		return &emu->x86.R_DL;
    631   1.1     joerg 	case 3:
    632   1.1     joerg 		return &emu->x86.R_BL;
    633   1.1     joerg 	case 4:
    634   1.1     joerg 		return &emu->x86.R_AH;
    635   1.1     joerg 	case 5:
    636   1.1     joerg 		return &emu->x86.R_CH;
    637   1.1     joerg 	case 6:
    638   1.1     joerg 		return &emu->x86.R_DH;
    639   1.1     joerg 	case 7:
    640   1.1     joerg 		return &emu->x86.R_BH;
    641   1.1     joerg 	default:
    642   1.1     joerg 		X86EMU_halt_sys(emu);
    643   1.1     joerg 	}
    644   1.1     joerg }
    645   1.1     joerg 
    646   1.1     joerg static uint8_t *
    647   1.1     joerg decode_rl_byte_register(struct X86EMU *emu)
    648   1.1     joerg {
    649   1.1     joerg 	return decode_rm_byte_register(emu, emu->cur_rl);
    650   1.1     joerg }
    651   1.1     joerg 
    652   1.1     joerg static uint8_t *
    653   1.1     joerg decode_rh_byte_register(struct X86EMU *emu)
    654   1.1     joerg {
    655   1.1     joerg 	return decode_rm_byte_register(emu, emu->cur_rh);
    656   1.1     joerg }
    657   1.1     joerg /****************************************************************************
    658   1.1     joerg PARAMETERS:
    659   1.1     joerg reg	- Register to decode
    660   1.1     joerg 
    661   1.1     joerg RETURNS:
    662   1.1     joerg Pointer to the appropriate register
    663   1.1     joerg 
    664   1.1     joerg REMARKS:
    665   1.1     joerg Return a pointer to the register given by the R/RM field of the
    666   1.1     joerg modrm byte, for word operands.  Also enables the decoding of instructions.
    667   1.1     joerg ****************************************************************************/
    668   1.1     joerg static uint16_t *
    669   1.1     joerg decode_rm_word_register(struct X86EMU *emu, int reg)
    670   1.1     joerg {
    671   1.1     joerg 	switch (reg) {
    672   1.1     joerg 	case 0:
    673   1.1     joerg 		return &emu->x86.R_AX;
    674   1.1     joerg 	case 1:
    675   1.1     joerg 		return &emu->x86.R_CX;
    676   1.1     joerg 	case 2:
    677   1.1     joerg 		return &emu->x86.R_DX;
    678   1.1     joerg 	case 3:
    679   1.1     joerg 		return &emu->x86.R_BX;
    680   1.1     joerg 	case 4:
    681   1.1     joerg 		return &emu->x86.R_SP;
    682   1.1     joerg 	case 5:
    683   1.1     joerg 		return &emu->x86.R_BP;
    684   1.1     joerg 	case 6:
    685   1.1     joerg 		return &emu->x86.R_SI;
    686   1.1     joerg 	case 7:
    687   1.1     joerg 		return &emu->x86.R_DI;
    688   1.1     joerg 	default:
    689   1.1     joerg 		X86EMU_halt_sys(emu);
    690   1.1     joerg 	}
    691   1.1     joerg }
    692   1.1     joerg 
    693   1.1     joerg static uint16_t *
    694   1.1     joerg decode_rl_word_register(struct X86EMU *emu)
    695   1.1     joerg {
    696   1.1     joerg 	return decode_rm_word_register(emu, emu->cur_rl);
    697   1.1     joerg }
    698   1.1     joerg 
    699   1.1     joerg static uint16_t *
    700   1.1     joerg decode_rh_word_register(struct X86EMU *emu)
    701   1.1     joerg {
    702   1.1     joerg 	return decode_rm_word_register(emu, emu->cur_rh);
    703   1.1     joerg }
    704   1.1     joerg /****************************************************************************
    705   1.1     joerg PARAMETERS:
    706   1.1     joerg reg	- Register to decode
    707   1.1     joerg 
    708   1.1     joerg RETURNS:
    709   1.1     joerg Pointer to the appropriate register
    710   1.1     joerg 
    711   1.1     joerg REMARKS:
    712   1.1     joerg Return a pointer to the register given by the R/RM field of the
    713   1.1     joerg modrm byte, for dword operands.  Also enables the decoding of instructions.
    714   1.1     joerg ****************************************************************************/
    715   1.1     joerg static uint32_t *
    716   1.1     joerg decode_rm_long_register(struct X86EMU *emu, int reg)
    717   1.1     joerg {
    718   1.1     joerg 	switch (reg) {
    719   1.1     joerg 	case 0:
    720   1.1     joerg 		return &emu->x86.R_EAX;
    721   1.1     joerg 	case 1:
    722   1.1     joerg 		return &emu->x86.R_ECX;
    723   1.1     joerg 	case 2:
    724   1.1     joerg 		return &emu->x86.R_EDX;
    725   1.1     joerg 	case 3:
    726   1.1     joerg 		return &emu->x86.R_EBX;
    727   1.1     joerg 	case 4:
    728   1.1     joerg 		return &emu->x86.R_ESP;
    729   1.1     joerg 	case 5:
    730   1.1     joerg 		return &emu->x86.R_EBP;
    731   1.1     joerg 	case 6:
    732   1.1     joerg 		return &emu->x86.R_ESI;
    733   1.1     joerg 	case 7:
    734   1.1     joerg 		return &emu->x86.R_EDI;
    735   1.1     joerg 	default:
    736   1.1     joerg 		X86EMU_halt_sys(emu);
    737   1.1     joerg 	}
    738   1.1     joerg }
    739   1.1     joerg 
    740   1.1     joerg static uint32_t *
    741   1.1     joerg decode_rl_long_register(struct X86EMU *emu)
    742   1.1     joerg {
    743   1.1     joerg 	return decode_rm_long_register(emu, emu->cur_rl);
    744   1.1     joerg }
    745   1.1     joerg 
    746   1.1     joerg static uint32_t *
    747   1.1     joerg decode_rh_long_register(struct X86EMU *emu)
    748   1.1     joerg {
    749   1.1     joerg 	return decode_rm_long_register(emu, emu->cur_rh);
    750   1.1     joerg }
    751   1.1     joerg 
    752   1.1     joerg /****************************************************************************
    753   1.1     joerg PARAMETERS:
    754   1.1     joerg reg	- Register to decode
    755   1.1     joerg 
    756   1.1     joerg RETURNS:
    757   1.1     joerg Pointer to the appropriate register
    758   1.1     joerg 
    759   1.1     joerg REMARKS:
    760   1.1     joerg Return a pointer to the register given by the R/RM field of the
    761   1.1     joerg modrm byte, for word operands, modified from above for the weirdo
    762   1.1     joerg special case of segreg operands.  Also enables the decoding of instructions.
    763   1.1     joerg ****************************************************************************/
    764   1.1     joerg static uint16_t *
    765   1.1     joerg decode_rh_seg_register(struct X86EMU *emu)
    766   1.1     joerg {
    767   1.1     joerg 	switch (emu->cur_rh) {
    768   1.1     joerg 	case 0:
    769   1.1     joerg 		return &emu->x86.R_ES;
    770   1.1     joerg 	case 1:
    771   1.1     joerg 		return &emu->x86.R_CS;
    772   1.1     joerg 	case 2:
    773   1.1     joerg 		return &emu->x86.R_SS;
    774   1.1     joerg 	case 3:
    775   1.1     joerg 		return &emu->x86.R_DS;
    776   1.1     joerg 	case 4:
    777   1.1     joerg 		return &emu->x86.R_FS;
    778   1.1     joerg 	case 5:
    779   1.1     joerg 		return &emu->x86.R_GS;
    780   1.1     joerg 	default:
    781   1.1     joerg 		X86EMU_halt_sys(emu);
    782   1.1     joerg 	}
    783   1.1     joerg }
    784   1.1     joerg /*
    785   1.1     joerg  *
    786   1.1     joerg  * return offset from the SIB Byte
    787   1.1     joerg  */
    788   1.1     joerg static uint32_t
    789   1.1     joerg decode_sib_address(struct X86EMU *emu, int sib, int mod)
    790   1.1     joerg {
    791   1.1     joerg 	uint32_t base = 0, i = 0, scale = 1;
    792   1.1     joerg 
    793   1.1     joerg 	switch (sib & 0x07) {
    794   1.1     joerg 	case 0:
    795   1.1     joerg 		base = emu->x86.R_EAX;
    796   1.1     joerg 		break;
    797   1.1     joerg 	case 1:
    798   1.1     joerg 		base = emu->x86.R_ECX;
    799   1.1     joerg 		break;
    800   1.1     joerg 	case 2:
    801   1.1     joerg 		base = emu->x86.R_EDX;
    802   1.1     joerg 		break;
    803   1.1     joerg 	case 3:
    804   1.1     joerg 		base = emu->x86.R_EBX;
    805   1.1     joerg 		break;
    806   1.1     joerg 	case 4:
    807   1.1     joerg 		base = emu->x86.R_ESP;
    808   1.1     joerg 		emu->x86.mode |= SYSMODE_SEG_DS_SS;
    809   1.1     joerg 		break;
    810   1.1     joerg 	case 5:
    811   1.1     joerg 		if (mod == 0) {
    812   1.1     joerg 			base = fetch_long_imm(emu);
    813   1.1     joerg 		} else {
    814   1.6     joerg 			base = emu->x86.R_EBP;
    815   1.1     joerg 			emu->x86.mode |= SYSMODE_SEG_DS_SS;
    816   1.1     joerg 		}
    817   1.1     joerg 		break;
    818   1.1     joerg 	case 6:
    819   1.1     joerg 		base = emu->x86.R_ESI;
    820   1.1     joerg 		break;
    821   1.1     joerg 	case 7:
    822   1.1     joerg 		base = emu->x86.R_EDI;
    823   1.1     joerg 		break;
    824   1.1     joerg 	}
    825   1.1     joerg 	switch ((sib >> 3) & 0x07) {
    826   1.1     joerg 	case 0:
    827   1.1     joerg 		i = emu->x86.R_EAX;
    828   1.1     joerg 		break;
    829   1.1     joerg 	case 1:
    830   1.1     joerg 		i = emu->x86.R_ECX;
    831   1.1     joerg 		break;
    832   1.1     joerg 	case 2:
    833   1.1     joerg 		i = emu->x86.R_EDX;
    834   1.1     joerg 		break;
    835   1.1     joerg 	case 3:
    836   1.1     joerg 		i = emu->x86.R_EBX;
    837   1.1     joerg 		break;
    838   1.1     joerg 	case 4:
    839   1.1     joerg 		i = 0;
    840   1.1     joerg 		break;
    841   1.1     joerg 	case 5:
    842   1.1     joerg 		i = emu->x86.R_EBP;
    843   1.1     joerg 		break;
    844   1.1     joerg 	case 6:
    845   1.1     joerg 		i = emu->x86.R_ESI;
    846   1.1     joerg 		break;
    847   1.1     joerg 	case 7:
    848   1.1     joerg 		i = emu->x86.R_EDI;
    849   1.1     joerg 		break;
    850   1.1     joerg 	}
    851   1.1     joerg 	scale = 1 << ((sib >> 6) & 0x03);
    852   1.1     joerg 	return base + (i * scale);
    853   1.1     joerg }
    854   1.1     joerg /****************************************************************************
    855   1.1     joerg PARAMETERS:
    856   1.1     joerg rm	- RM value to decode
    857   1.1     joerg 
    858   1.1     joerg RETURNS:
    859   1.1     joerg Offset in memory for the address decoding
    860   1.1     joerg 
    861   1.1     joerg REMARKS:
    862   1.1     joerg Return the offset given by mod=00, mod=01 or mod=10 addressing.
    863   1.1     joerg Also enables the decoding of instructions.
    864   1.1     joerg ****************************************************************************/
    865   1.1     joerg static uint32_t
    866   1.1     joerg decode_rl_address(struct X86EMU *emu)
    867   1.1     joerg {
    868   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
    869   1.1     joerg 		uint32_t offset, sib;
    870   1.1     joerg 		/* 32-bit addressing */
    871   1.1     joerg 		switch (emu->cur_rl) {
    872   1.1     joerg 		case 0:
    873   1.1     joerg 			offset = emu->x86.R_EAX;
    874   1.1     joerg 			break;
    875   1.1     joerg 		case 1:
    876   1.1     joerg 			offset = emu->x86.R_ECX;
    877   1.1     joerg 			break;
    878   1.1     joerg 		case 2:
    879   1.1     joerg 			offset = emu->x86.R_EDX;
    880   1.1     joerg 			break;
    881   1.1     joerg 		case 3:
    882   1.1     joerg 			offset = emu->x86.R_EBX;
    883   1.1     joerg 			break;
    884   1.1     joerg 		case 4:
    885   1.1     joerg 			sib = fetch_byte_imm(emu);
    886   1.1     joerg 			offset = decode_sib_address(emu, sib, 0);
    887   1.1     joerg 			break;
    888   1.1     joerg 		case 5:
    889   1.6     joerg 			if (emu->cur_mod == 0) {
    890   1.1     joerg 				offset = fetch_long_imm(emu);
    891   1.6     joerg 			} else {
    892   1.6     joerg 				emu->x86.mode |= SYSMODE_SEG_DS_SS;
    893   1.1     joerg 				offset = emu->x86.R_EBP;
    894   1.6     joerg 			}
    895   1.1     joerg 			break;
    896   1.1     joerg 		case 6:
    897   1.1     joerg 			offset = emu->x86.R_ESI;
    898   1.1     joerg 			break;
    899   1.1     joerg 		case 7:
    900   1.1     joerg 			offset = emu->x86.R_EDI;
    901   1.1     joerg 			break;
    902   1.1     joerg 		default:
    903   1.1     joerg 			X86EMU_halt_sys(emu);
    904   1.1     joerg 		}
    905   1.1     joerg 		if (emu->cur_mod == 1)
    906   1.1     joerg 			offset += (int8_t)fetch_byte_imm(emu);
    907   1.1     joerg 		else if (emu->cur_mod == 2)
    908   1.1     joerg 			offset += fetch_long_imm(emu);
    909   1.1     joerg 		return offset;
    910   1.1     joerg 	} else {
    911   1.1     joerg 		uint16_t offset;
    912   1.1     joerg 
    913   1.1     joerg 		/* 16-bit addressing */
    914   1.1     joerg 		switch (emu->cur_rl) {
    915   1.1     joerg 		case 0:
    916   1.1     joerg 			offset = emu->x86.R_BX + emu->x86.R_SI;
    917   1.1     joerg 			break;
    918   1.1     joerg 		case 1:
    919   1.1     joerg 			offset = emu->x86.R_BX + emu->x86.R_DI;
    920   1.1     joerg 			break;
    921   1.1     joerg 		case 2:
    922   1.1     joerg 			emu->x86.mode |= SYSMODE_SEG_DS_SS;
    923   1.1     joerg 			offset = emu->x86.R_BP + emu->x86.R_SI;
    924   1.1     joerg 			break;
    925   1.1     joerg 		case 3:
    926   1.1     joerg 			emu->x86.mode |= SYSMODE_SEG_DS_SS;
    927   1.1     joerg 			offset = emu->x86.R_BP + emu->x86.R_DI;
    928   1.1     joerg 			break;
    929   1.1     joerg 		case 4:
    930   1.1     joerg 			offset = emu->x86.R_SI;
    931   1.1     joerg 			break;
    932   1.1     joerg 		case 5:
    933   1.1     joerg 			offset = emu->x86.R_DI;
    934   1.1     joerg 			break;
    935   1.1     joerg 		case 6:
    936   1.6     joerg 			if (emu->cur_mod == 0) {
    937   1.1     joerg 				offset = fetch_word_imm(emu);
    938   1.6     joerg 			} else {
    939   1.6     joerg 				emu->x86.mode |= SYSMODE_SEG_DS_SS;
    940   1.1     joerg 				offset = emu->x86.R_BP;
    941   1.6     joerg 			}
    942   1.1     joerg 			break;
    943   1.1     joerg 		case 7:
    944   1.1     joerg 			offset = emu->x86.R_BX;
    945   1.1     joerg 			break;
    946   1.1     joerg 		default:
    947   1.1     joerg 			X86EMU_halt_sys(emu);
    948   1.1     joerg 		}
    949   1.1     joerg 		if (emu->cur_mod == 1)
    950   1.1     joerg 			offset += (int8_t)fetch_byte_imm(emu);
    951   1.1     joerg 		else if (emu->cur_mod == 2)
    952   1.1     joerg 			offset += fetch_word_imm(emu);
    953   1.1     joerg 		return offset;
    954   1.1     joerg 	}
    955   1.1     joerg }
    956   1.1     joerg 
    957   1.1     joerg static uint8_t
    958   1.1     joerg decode_and_fetch_byte(struct X86EMU *emu)
    959   1.1     joerg {
    960   1.1     joerg 	if (emu->cur_mod != 3) {
    961   1.1     joerg 		emu->cur_offset = decode_rl_address(emu);
    962   1.1     joerg 		return fetch_data_byte(emu, emu->cur_offset);
    963   1.1     joerg 	} else {
    964   1.1     joerg 		return *decode_rl_byte_register(emu);
    965   1.1     joerg 	}
    966   1.1     joerg }
    967   1.1     joerg 
    968   1.1     joerg static uint16_t
    969   1.1     joerg decode_and_fetch_word_disp(struct X86EMU *emu, int16_t disp)
    970   1.1     joerg {
    971   1.1     joerg 	if (emu->cur_mod != 3) {
    972   1.1     joerg 		/* TODO: A20 gate emulation */
    973   1.1     joerg 		emu->cur_offset = decode_rl_address(emu) + disp;
    974   1.1     joerg 		if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
    975   1.1     joerg 			emu->cur_offset &= 0xffff;
    976   1.1     joerg 		return fetch_data_word(emu, emu->cur_offset);
    977   1.1     joerg 	} else {
    978   1.1     joerg 		return *decode_rl_word_register(emu);
    979   1.1     joerg 	}
    980   1.1     joerg }
    981   1.1     joerg 
    982   1.1     joerg static uint32_t
    983   1.1     joerg decode_and_fetch_long_disp(struct X86EMU *emu, int16_t disp)
    984   1.1     joerg {
    985   1.1     joerg 	if (emu->cur_mod != 3) {
    986   1.1     joerg 		/* TODO: A20 gate emulation */
    987   1.1     joerg 		emu->cur_offset = decode_rl_address(emu) + disp;
    988   1.1     joerg 		if ((emu->x86.mode & SYSMODE_PREFIX_ADDR) == 0)
    989   1.1     joerg 			emu->cur_offset &= 0xffff;
    990   1.1     joerg 		return fetch_data_long(emu, emu->cur_offset);
    991   1.1     joerg 	} else {
    992   1.1     joerg 		return *decode_rl_long_register(emu);
    993   1.1     joerg 	}
    994   1.1     joerg }
    995   1.1     joerg 
    996   1.1     joerg uint16_t
    997   1.1     joerg decode_and_fetch_word(struct X86EMU *emu)
    998   1.1     joerg {
    999   1.1     joerg 	return decode_and_fetch_word_disp(emu, 0);
   1000   1.1     joerg }
   1001   1.1     joerg 
   1002   1.1     joerg uint32_t
   1003   1.1     joerg decode_and_fetch_long(struct X86EMU *emu)
   1004   1.1     joerg {
   1005   1.1     joerg 	return decode_and_fetch_long_disp(emu, 0);
   1006   1.1     joerg }
   1007   1.1     joerg 
   1008   1.1     joerg uint8_t
   1009   1.1     joerg decode_and_fetch_byte_imm8(struct X86EMU *emu, uint8_t *imm)
   1010   1.1     joerg {
   1011   1.1     joerg 	if (emu->cur_mod != 3) {
   1012   1.1     joerg 		emu->cur_offset = decode_rl_address(emu);
   1013   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1014   1.1     joerg 		return fetch_data_byte(emu, emu->cur_offset);
   1015   1.1     joerg 	} else {
   1016   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1017   1.1     joerg 		return *decode_rl_byte_register(emu);
   1018   1.1     joerg 	}
   1019   1.1     joerg }
   1020   1.1     joerg 
   1021   1.1     joerg static uint16_t
   1022   1.1     joerg decode_and_fetch_word_imm8(struct X86EMU *emu, uint8_t *imm)
   1023   1.1     joerg {
   1024   1.1     joerg 	if (emu->cur_mod != 3) {
   1025   1.1     joerg 		emu->cur_offset = decode_rl_address(emu);
   1026   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1027   1.1     joerg 		return fetch_data_word(emu, emu->cur_offset);
   1028   1.1     joerg 	} else {
   1029   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1030   1.1     joerg 		return *decode_rl_word_register(emu);
   1031   1.1     joerg 	}
   1032   1.1     joerg }
   1033   1.1     joerg 
   1034   1.1     joerg static uint32_t
   1035   1.1     joerg decode_and_fetch_long_imm8(struct X86EMU *emu, uint8_t *imm)
   1036   1.1     joerg {
   1037   1.1     joerg 	if (emu->cur_mod != 3) {
   1038   1.1     joerg 		emu->cur_offset = decode_rl_address(emu);
   1039   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1040   1.1     joerg 		return fetch_data_long(emu, emu->cur_offset);
   1041   1.1     joerg 	} else {
   1042   1.1     joerg 		*imm = fetch_byte_imm(emu);
   1043   1.1     joerg 		return *decode_rl_long_register(emu);
   1044   1.1     joerg 	}
   1045   1.1     joerg }
   1046   1.1     joerg 
   1047   1.1     joerg static void
   1048   1.1     joerg write_back_byte(struct X86EMU *emu, uint8_t val)
   1049   1.1     joerg {
   1050   1.1     joerg 	if (emu->cur_mod != 3)
   1051   1.1     joerg 		store_data_byte(emu, emu->cur_offset, val);
   1052   1.1     joerg 	else
   1053   1.1     joerg 		*decode_rl_byte_register(emu) = val;
   1054   1.1     joerg }
   1055   1.1     joerg 
   1056   1.1     joerg static void
   1057   1.1     joerg write_back_word(struct X86EMU *emu, uint16_t val)
   1058   1.1     joerg {
   1059   1.1     joerg 	if (emu->cur_mod != 3)
   1060   1.1     joerg 		store_data_word(emu, emu->cur_offset, val);
   1061   1.1     joerg 	else
   1062   1.1     joerg 		*decode_rl_word_register(emu) = val;
   1063   1.1     joerg }
   1064   1.1     joerg 
   1065   1.1     joerg static void
   1066   1.1     joerg write_back_long(struct X86EMU *emu, uint32_t val)
   1067   1.1     joerg {
   1068   1.1     joerg 	if (emu->cur_mod != 3)
   1069   1.1     joerg 		store_data_long(emu, emu->cur_offset, val);
   1070   1.1     joerg 	else
   1071   1.1     joerg 		*decode_rl_long_register(emu) = val;
   1072   1.1     joerg }
   1073   1.1     joerg 
   1074   1.1     joerg static void
   1075   1.1     joerg common_inc_word_long(struct X86EMU *emu, union X86EMU_register *reg)
   1076   1.1     joerg {
   1077   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1078   1.1     joerg 		reg->I32_reg.e_reg = inc_long(emu, reg->I32_reg.e_reg);
   1079   1.1     joerg 	else
   1080   1.1     joerg 		reg->I16_reg.x_reg = inc_word(emu, reg->I16_reg.x_reg);
   1081   1.1     joerg }
   1082   1.1     joerg 
   1083   1.1     joerg static void
   1084   1.1     joerg common_dec_word_long(struct X86EMU *emu, union X86EMU_register *reg)
   1085   1.1     joerg {
   1086   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1087   1.1     joerg 		reg->I32_reg.e_reg = dec_long(emu, reg->I32_reg.e_reg);
   1088   1.1     joerg 	else
   1089   1.1     joerg 		reg->I16_reg.x_reg = dec_word(emu, reg->I16_reg.x_reg);
   1090   1.1     joerg }
   1091   1.1     joerg 
   1092   1.1     joerg static void
   1093   1.1     joerg common_binop_byte_rm_r(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
   1094   1.1     joerg {
   1095   1.1     joerg 	uint32_t destoffset;
   1096   1.1     joerg 	uint8_t *destreg, srcval;
   1097   1.1     joerg 	uint8_t destval;
   1098   1.1     joerg 
   1099   1.1     joerg 	fetch_decode_modrm(emu);
   1100   1.1     joerg 	srcval = *decode_rh_byte_register(emu);
   1101   1.1     joerg 	if (emu->cur_mod != 3) {
   1102   1.1     joerg 		destoffset = decode_rl_address(emu);
   1103   1.1     joerg 		destval = fetch_data_byte(emu, destoffset);
   1104   1.1     joerg 		destval = (*binop)(emu, destval, srcval);
   1105   1.1     joerg 		store_data_byte(emu, destoffset, destval);
   1106   1.1     joerg 	} else {
   1107   1.1     joerg 		destreg = decode_rl_byte_register(emu);
   1108   1.1     joerg 		*destreg = (*binop)(emu, *destreg, srcval);
   1109   1.1     joerg 	}
   1110   1.1     joerg }
   1111   1.1     joerg 
   1112   1.1     joerg static void
   1113   1.1     joerg common_binop_ns_byte_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint8_t, uint8_t))
   1114   1.1     joerg {
   1115   1.1     joerg 	uint32_t destoffset;
   1116   1.1     joerg 	uint8_t destval, srcval;
   1117   1.1     joerg 
   1118   1.1     joerg 	fetch_decode_modrm(emu);
   1119   1.1     joerg 	srcval = *decode_rh_byte_register(emu);
   1120   1.1     joerg 	if (emu->cur_mod != 3) {
   1121   1.1     joerg 		destoffset = decode_rl_address(emu);
   1122   1.1     joerg 		destval = fetch_data_byte(emu, destoffset);
   1123   1.1     joerg 	} else {
   1124   1.1     joerg 		destval = *decode_rl_byte_register(emu);
   1125   1.1     joerg 	}
   1126   1.1     joerg 	(*binop)(emu, destval, srcval);
   1127   1.1     joerg }
   1128   1.1     joerg 
   1129   1.1     joerg static void
   1130   1.1     joerg common_binop_word_rm_r(struct X86EMU *emu, uint16_t (*binop)(struct X86EMU *, uint16_t, uint16_t))
   1131   1.1     joerg {
   1132   1.1     joerg 	uint32_t destoffset;
   1133   1.1     joerg 	uint16_t destval, *destreg, srcval;
   1134   1.1     joerg 
   1135   1.1     joerg 	fetch_decode_modrm(emu);
   1136   1.1     joerg 	srcval = *decode_rh_word_register(emu);
   1137   1.1     joerg 	if (emu->cur_mod != 3) {
   1138   1.1     joerg 		destoffset = decode_rl_address(emu);
   1139   1.1     joerg 		destval = fetch_data_word(emu, destoffset);
   1140   1.1     joerg 		destval = (*binop)(emu, destval, srcval);
   1141   1.1     joerg 		store_data_word(emu, destoffset, destval);
   1142   1.1     joerg 	} else {
   1143   1.1     joerg 		destreg = decode_rl_word_register(emu);
   1144   1.1     joerg 		*destreg = (*binop)(emu, *destreg, srcval);
   1145   1.1     joerg 	}
   1146   1.1     joerg }
   1147   1.1     joerg 
   1148   1.1     joerg static void
   1149   1.1     joerg common_binop_byte_r_rm(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
   1150   1.1     joerg {
   1151   1.1     joerg 	uint8_t *destreg, srcval;
   1152   1.1     joerg 	uint32_t srcoffset;
   1153   1.1     joerg 
   1154   1.1     joerg 	fetch_decode_modrm(emu);
   1155   1.1     joerg 	destreg = decode_rh_byte_register(emu);
   1156   1.1     joerg 	if (emu->cur_mod != 3) {
   1157   1.1     joerg 		srcoffset = decode_rl_address(emu);
   1158   1.1     joerg 		srcval = fetch_data_byte(emu, srcoffset);
   1159   1.1     joerg 	} else {
   1160   1.1     joerg 		srcval = *decode_rl_byte_register(emu);
   1161   1.1     joerg 	}
   1162   1.1     joerg 	*destreg = (*binop)(emu, *destreg, srcval);
   1163   1.1     joerg }
   1164   1.1     joerg 
   1165   1.1     joerg static void
   1166   1.1     joerg common_binop_long_rm_r(struct X86EMU *emu, uint32_t (*binop)(struct X86EMU *, uint32_t, uint32_t))
   1167   1.1     joerg {
   1168   1.1     joerg 	uint32_t destoffset;
   1169   1.1     joerg 	uint32_t destval, *destreg, srcval;
   1170   1.1     joerg 
   1171   1.1     joerg 	fetch_decode_modrm(emu);
   1172   1.1     joerg 	srcval = *decode_rh_long_register(emu);
   1173   1.1     joerg 	if (emu->cur_mod != 3) {
   1174   1.1     joerg 		destoffset = decode_rl_address(emu);
   1175   1.1     joerg 		destval = fetch_data_long(emu, destoffset);
   1176   1.1     joerg 		destval = (*binop)(emu, destval, srcval);
   1177   1.1     joerg 		store_data_long(emu, destoffset, destval);
   1178   1.1     joerg 	} else {
   1179   1.1     joerg 		destreg = decode_rl_long_register(emu);
   1180   1.1     joerg 		*destreg = (*binop)(emu, *destreg, srcval);
   1181   1.1     joerg 	}
   1182   1.1     joerg }
   1183   1.1     joerg 
   1184   1.1     joerg static void
   1185   1.1     joerg common_binop_word_long_rm_r(struct X86EMU *emu,
   1186   1.1     joerg     uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
   1187   1.1     joerg {
   1188   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1189   1.1     joerg 		common_binop_long_rm_r(emu, binop32);
   1190   1.1     joerg 	else
   1191   1.1     joerg 		common_binop_word_rm_r(emu, binop16);
   1192   1.1     joerg }
   1193   1.1     joerg 
   1194   1.1     joerg static void
   1195   1.1     joerg common_binop_ns_word_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint16_t, uint16_t))
   1196   1.1     joerg {
   1197   1.1     joerg 	uint32_t destoffset;
   1198   1.1     joerg 	uint16_t destval, srcval;
   1199   1.1     joerg 
   1200   1.1     joerg 	fetch_decode_modrm(emu);
   1201   1.1     joerg 	srcval = *decode_rh_word_register(emu);
   1202   1.1     joerg 	if (emu->cur_mod != 3) {
   1203   1.1     joerg 		destoffset = decode_rl_address(emu);
   1204   1.1     joerg 		destval = fetch_data_word(emu, destoffset);
   1205   1.1     joerg 	} else {
   1206   1.1     joerg 		destval = *decode_rl_word_register(emu);
   1207   1.1     joerg 	}
   1208   1.1     joerg 	(*binop)(emu, destval, srcval);
   1209   1.1     joerg }
   1210   1.1     joerg 
   1211   1.1     joerg 
   1212   1.1     joerg static void
   1213   1.1     joerg common_binop_ns_long_rm_r(struct X86EMU *emu, void (*binop)(struct X86EMU *, uint32_t, uint32_t))
   1214   1.1     joerg {
   1215   1.1     joerg 	uint32_t destoffset;
   1216   1.1     joerg 	uint32_t destval, srcval;
   1217   1.1     joerg 
   1218   1.1     joerg 	fetch_decode_modrm(emu);
   1219   1.1     joerg 	srcval = *decode_rh_long_register(emu);
   1220   1.1     joerg 	if (emu->cur_mod != 3) {
   1221   1.1     joerg 		destoffset = decode_rl_address(emu);
   1222   1.1     joerg 		destval = fetch_data_long(emu, destoffset);
   1223   1.1     joerg 	} else {
   1224   1.1     joerg 		destval = *decode_rl_long_register(emu);
   1225   1.1     joerg 	}
   1226   1.1     joerg 	(*binop)(emu, destval, srcval);
   1227   1.1     joerg }
   1228   1.1     joerg 
   1229   1.1     joerg static void
   1230   1.1     joerg common_binop_ns_word_long_rm_r(struct X86EMU *emu,
   1231   1.1     joerg     void (*binop16)(struct X86EMU *, uint16_t, uint16_t), void (*binop32)(struct X86EMU *, uint32_t, uint32_t))
   1232   1.1     joerg {
   1233   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1234   1.1     joerg 		common_binop_ns_long_rm_r(emu, binop32);
   1235   1.1     joerg 	else
   1236   1.1     joerg 		common_binop_ns_word_rm_r(emu, binop16);
   1237   1.1     joerg }
   1238   1.1     joerg 
   1239   1.1     joerg static void
   1240   1.1     joerg common_binop_long_r_rm(struct X86EMU *emu, uint32_t (*binop)(struct X86EMU *, uint32_t, uint32_t))
   1241   1.1     joerg {
   1242   1.1     joerg 	uint32_t srcoffset;
   1243   1.1     joerg 	uint32_t *destreg, srcval;
   1244   1.1     joerg 
   1245   1.1     joerg 	fetch_decode_modrm(emu);
   1246   1.1     joerg 	destreg = decode_rh_long_register(emu);
   1247   1.1     joerg 	if (emu->cur_mod != 3) {
   1248   1.1     joerg 		srcoffset = decode_rl_address(emu);
   1249   1.1     joerg 		srcval = fetch_data_long(emu, srcoffset);
   1250   1.1     joerg 	} else {
   1251   1.1     joerg 		srcval = *decode_rl_long_register(emu);
   1252   1.1     joerg 	}
   1253   1.1     joerg 	*destreg = (*binop)(emu, *destreg, srcval);
   1254   1.1     joerg }
   1255   1.1     joerg 
   1256   1.1     joerg static void
   1257   1.1     joerg common_binop_word_r_rm(struct X86EMU *emu, uint16_t (*binop)(struct X86EMU *, uint16_t, uint16_t))
   1258   1.1     joerg {
   1259   1.1     joerg 	uint32_t srcoffset;
   1260   1.1     joerg 	uint16_t *destreg, srcval;
   1261   1.1     joerg 
   1262   1.1     joerg 	fetch_decode_modrm(emu);
   1263   1.1     joerg 	destreg = decode_rh_word_register(emu);
   1264   1.1     joerg 	if (emu->cur_mod != 3) {
   1265   1.1     joerg 		srcoffset = decode_rl_address(emu);
   1266   1.1     joerg 		srcval = fetch_data_word(emu, srcoffset);
   1267   1.1     joerg 	} else {
   1268   1.1     joerg 		srcval = *decode_rl_word_register(emu);
   1269   1.1     joerg 	}
   1270   1.1     joerg 	*destreg = (*binop)(emu, *destreg, srcval);
   1271   1.1     joerg }
   1272   1.1     joerg 
   1273   1.1     joerg static void
   1274   1.1     joerg common_binop_word_long_r_rm(struct X86EMU *emu,
   1275   1.1     joerg     uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
   1276   1.1     joerg {
   1277   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1278   1.1     joerg 		common_binop_long_r_rm(emu, binop32);
   1279   1.1     joerg 	else
   1280   1.1     joerg 		common_binop_word_r_rm(emu, binop16);
   1281   1.1     joerg }
   1282   1.1     joerg 
   1283   1.1     joerg static void
   1284   1.1     joerg common_binop_byte_imm(struct X86EMU *emu, uint8_t (*binop)(struct X86EMU *, uint8_t, uint8_t))
   1285   1.1     joerg {
   1286   1.1     joerg 	uint8_t srcval;
   1287   1.1     joerg 
   1288   1.1     joerg 	srcval = fetch_byte_imm(emu);
   1289   1.1     joerg 	emu->x86.R_AL = (*binop)(emu, emu->x86.R_AL, srcval);
   1290   1.1     joerg }
   1291   1.1     joerg 
   1292   1.1     joerg static void
   1293   1.1     joerg common_binop_word_long_imm(struct X86EMU *emu,
   1294   1.1     joerg     uint16_t (*binop16)(struct X86EMU *, uint16_t, uint16_t), uint32_t (*binop32)(struct X86EMU *, uint32_t, uint32_t))
   1295   1.1     joerg {
   1296   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1297   1.1     joerg 		uint32_t srcval;
   1298   1.1     joerg 
   1299   1.1     joerg 		srcval = fetch_long_imm(emu);
   1300   1.1     joerg 		emu->x86.R_EAX = (*binop32)(emu, emu->x86.R_EAX, srcval);
   1301   1.1     joerg 	} else {
   1302   1.1     joerg 		uint16_t srcval;
   1303   1.1     joerg 
   1304   1.1     joerg 		srcval = fetch_word_imm(emu);
   1305   1.1     joerg 		emu->x86.R_AX = (*binop16)(emu, emu->x86.R_AX, srcval);
   1306   1.1     joerg 	}
   1307   1.1     joerg }
   1308   1.1     joerg 
   1309   1.1     joerg static void
   1310   1.1     joerg common_push_word_long(struct X86EMU *emu, union X86EMU_register *reg)
   1311   1.1     joerg {
   1312   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1313   1.1     joerg 		push_long(emu, reg->I32_reg.e_reg);
   1314   1.1     joerg 	else
   1315   1.1     joerg 		push_word(emu, reg->I16_reg.x_reg);
   1316   1.1     joerg }
   1317   1.1     joerg 
   1318   1.1     joerg static void
   1319   1.1     joerg common_pop_word_long(struct X86EMU *emu, union X86EMU_register *reg)
   1320   1.1     joerg {
   1321   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1322   1.1     joerg 		reg->I32_reg.e_reg = pop_long(emu);
   1323   1.1     joerg 	else
   1324   1.1     joerg 		reg->I16_reg.x_reg = pop_word(emu);
   1325   1.1     joerg }
   1326   1.1     joerg 
   1327   1.1     joerg static void
   1328   1.1     joerg common_imul_long_IMM(struct X86EMU *emu, bool byte_imm)
   1329   1.1     joerg {
   1330   1.1     joerg 	uint32_t srcoffset;
   1331   1.1     joerg 	uint32_t *destreg, srcval;
   1332   1.1     joerg 	int32_t imm;
   1333   1.1     joerg 	uint64_t res;
   1334   1.1     joerg 
   1335   1.1     joerg 	fetch_decode_modrm(emu);
   1336   1.1     joerg 	destreg = decode_rh_long_register(emu);
   1337   1.1     joerg 	if (emu->cur_mod != 3) {
   1338   1.1     joerg 		srcoffset = decode_rl_address(emu);
   1339   1.1     joerg 		srcval = fetch_data_long(emu, srcoffset);
   1340   1.1     joerg 	} else {
   1341   1.1     joerg 		srcval = *decode_rl_long_register(emu);
   1342   1.1     joerg 	}
   1343   1.1     joerg 
   1344   1.1     joerg 	if (byte_imm)
   1345   1.1     joerg 		imm = (int8_t)fetch_byte_imm(emu);
   1346   1.1     joerg 	else
   1347   1.1     joerg 		imm = fetch_long_imm(emu);
   1348   1.1     joerg 	res = (int32_t)srcval * imm;
   1349   1.1     joerg 
   1350   1.1     joerg 	if (res > 0xffffffff) {
   1351   1.1     joerg 		SET_FLAG(F_CF);
   1352   1.1     joerg 		SET_FLAG(F_OF);
   1353   1.1     joerg 	} else {
   1354   1.1     joerg 		CLEAR_FLAG(F_CF);
   1355   1.1     joerg 		CLEAR_FLAG(F_OF);
   1356   1.1     joerg 	}
   1357   1.1     joerg 	*destreg = (uint32_t)res;
   1358   1.1     joerg }
   1359   1.1     joerg 
   1360   1.1     joerg static void
   1361   1.1     joerg common_imul_word_IMM(struct X86EMU *emu, bool byte_imm)
   1362   1.1     joerg {
   1363   1.1     joerg 	uint32_t srcoffset;
   1364   1.1     joerg 	uint16_t *destreg, srcval;
   1365   1.1     joerg 	int16_t imm;
   1366   1.1     joerg 	uint32_t res;
   1367   1.1     joerg 
   1368   1.1     joerg 	fetch_decode_modrm(emu);
   1369   1.1     joerg 	destreg = decode_rh_word_register(emu);
   1370   1.1     joerg 	if (emu->cur_mod != 3) {
   1371   1.1     joerg 		srcoffset = decode_rl_address(emu);
   1372   1.1     joerg 		srcval = fetch_data_word(emu, srcoffset);
   1373   1.1     joerg 	} else {
   1374   1.1     joerg 		srcval = *decode_rl_word_register(emu);
   1375   1.1     joerg 	}
   1376   1.1     joerg 
   1377   1.1     joerg 	if (byte_imm)
   1378   1.1     joerg 		imm = (int8_t)fetch_byte_imm(emu);
   1379   1.1     joerg 	else
   1380   1.1     joerg 		imm = fetch_word_imm(emu);
   1381   1.1     joerg 	res = (int16_t)srcval * imm;
   1382   1.1     joerg 
   1383   1.1     joerg 	if (res > 0xffff) {
   1384   1.1     joerg 		SET_FLAG(F_CF);
   1385   1.1     joerg 		SET_FLAG(F_OF);
   1386   1.1     joerg 	} else {
   1387   1.1     joerg 		CLEAR_FLAG(F_CF);
   1388   1.1     joerg 		CLEAR_FLAG(F_OF);
   1389   1.1     joerg 	}
   1390   1.1     joerg 	*destreg = (uint16_t) res;
   1391   1.1     joerg }
   1392   1.1     joerg 
   1393   1.1     joerg static void
   1394   1.1     joerg common_imul_imm(struct X86EMU *emu, bool byte_imm)
   1395   1.1     joerg {
   1396   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1397   1.1     joerg 		common_imul_long_IMM(emu, byte_imm);
   1398   1.1     joerg 	else
   1399   1.1     joerg 		common_imul_word_IMM(emu, byte_imm);
   1400   1.1     joerg }
   1401   1.1     joerg 
   1402   1.1     joerg static void
   1403   1.1     joerg common_jmp_near(struct X86EMU *emu, bool cond)
   1404   1.1     joerg {
   1405   1.1     joerg 	int8_t offset;
   1406   1.1     joerg 	uint16_t target;
   1407   1.1     joerg 
   1408   1.1     joerg 	offset = (int8_t) fetch_byte_imm(emu);
   1409   1.1     joerg 	target = (uint16_t) (emu->x86.R_IP + (int16_t) offset);
   1410   1.1     joerg 	if (cond)
   1411   1.1     joerg 		emu->x86.R_IP = target;
   1412   1.1     joerg }
   1413   1.1     joerg 
   1414   1.1     joerg static void
   1415   1.1     joerg common_load_far_pointer(struct X86EMU *emu, uint16_t *seg)
   1416   1.1     joerg {
   1417   1.1     joerg 	uint16_t *dstreg;
   1418   1.1     joerg 	uint32_t srcoffset;
   1419   1.1     joerg 
   1420   1.1     joerg 	fetch_decode_modrm(emu);
   1421   1.1     joerg 	if (emu->cur_mod == 3)
   1422   1.1     joerg 		X86EMU_halt_sys(emu);
   1423   1.1     joerg 
   1424   1.1     joerg 	dstreg = decode_rh_word_register(emu);
   1425   1.1     joerg 	srcoffset = decode_rl_address(emu);
   1426   1.1     joerg 	*dstreg = fetch_data_word(emu, srcoffset);
   1427   1.1     joerg 	*seg = fetch_data_word(emu, srcoffset + 2);
   1428   1.1     joerg }
   1429   1.1     joerg 
   1430   1.1     joerg /*----------------------------- Implementation ----------------------------*/
   1431   1.1     joerg /****************************************************************************
   1432   1.1     joerg REMARKS:
   1433   1.1     joerg Handles opcode 0x3a
   1434   1.1     joerg ****************************************************************************/
   1435   1.1     joerg static void
   1436   1.1     joerg x86emuOp_cmp_byte_R_RM(struct X86EMU *emu)
   1437   1.1     joerg {
   1438   1.1     joerg 	uint8_t *destreg, srcval;
   1439   1.1     joerg 
   1440   1.1     joerg 	fetch_decode_modrm(emu);
   1441   1.1     joerg 	destreg = decode_rh_byte_register(emu);
   1442   1.1     joerg 	srcval = decode_and_fetch_byte(emu);
   1443   1.1     joerg 	cmp_byte(emu, *destreg, srcval);
   1444   1.1     joerg }
   1445   1.1     joerg /****************************************************************************
   1446   1.1     joerg REMARKS:
   1447   1.1     joerg Handles opcode 0x3b
   1448   1.1     joerg ****************************************************************************/
   1449   1.1     joerg static void
   1450   1.1     joerg x86emuOp32_cmp_word_R_RM(struct X86EMU *emu)
   1451   1.1     joerg {
   1452   1.1     joerg 	uint32_t srcval, *destreg;
   1453   1.1     joerg 
   1454   1.1     joerg 	fetch_decode_modrm(emu);
   1455   1.1     joerg 	destreg = decode_rh_long_register(emu);
   1456   1.1     joerg 	srcval = decode_and_fetch_long(emu);
   1457   1.1     joerg 	cmp_long(emu, *destreg, srcval);
   1458   1.1     joerg }
   1459   1.1     joerg 
   1460   1.1     joerg static void
   1461   1.1     joerg x86emuOp16_cmp_word_R_RM(struct X86EMU *emu)
   1462   1.1     joerg {
   1463   1.1     joerg 	uint16_t srcval, *destreg;
   1464   1.1     joerg 
   1465   1.1     joerg 	fetch_decode_modrm(emu);
   1466   1.1     joerg 	destreg = decode_rh_word_register(emu);
   1467   1.1     joerg 	srcval = decode_and_fetch_word(emu);
   1468   1.1     joerg 	cmp_word(emu, *destreg, srcval);
   1469   1.1     joerg }
   1470   1.1     joerg 
   1471   1.1     joerg static void
   1472   1.1     joerg x86emuOp_cmp_word_R_RM(struct X86EMU *emu)
   1473   1.1     joerg {
   1474   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1475   1.1     joerg 		x86emuOp32_cmp_word_R_RM(emu);
   1476   1.1     joerg 	else
   1477   1.1     joerg 		x86emuOp16_cmp_word_R_RM(emu);
   1478   1.1     joerg }
   1479   1.1     joerg /****************************************************************************
   1480   1.1     joerg REMARKS:
   1481   1.1     joerg Handles opcode 0x3c
   1482   1.1     joerg ****************************************************************************/
   1483   1.1     joerg static void
   1484   1.1     joerg x86emuOp_cmp_byte_AL_IMM(struct X86EMU *emu)
   1485   1.1     joerg {
   1486   1.1     joerg 	uint8_t srcval;
   1487   1.1     joerg 
   1488   1.1     joerg 	srcval = fetch_byte_imm(emu);
   1489   1.1     joerg 	cmp_byte(emu, emu->x86.R_AL, srcval);
   1490   1.1     joerg }
   1491   1.1     joerg /****************************************************************************
   1492   1.1     joerg REMARKS:
   1493   1.1     joerg Handles opcode 0x3d
   1494   1.1     joerg ****************************************************************************/
   1495   1.1     joerg static void
   1496   1.1     joerg x86emuOp32_cmp_word_AX_IMM(struct X86EMU *emu)
   1497   1.1     joerg {
   1498   1.1     joerg 	uint32_t srcval;
   1499   1.1     joerg 
   1500   1.1     joerg 	srcval = fetch_long_imm(emu);
   1501   1.1     joerg 	cmp_long(emu, emu->x86.R_EAX, srcval);
   1502   1.1     joerg }
   1503   1.1     joerg 
   1504   1.1     joerg static void
   1505   1.1     joerg x86emuOp16_cmp_word_AX_IMM(struct X86EMU *emu)
   1506   1.1     joerg {
   1507   1.1     joerg 	uint16_t srcval;
   1508   1.1     joerg 
   1509   1.1     joerg 	srcval = fetch_word_imm(emu);
   1510   1.1     joerg 	cmp_word(emu, emu->x86.R_AX, srcval);
   1511   1.1     joerg }
   1512   1.1     joerg 
   1513   1.1     joerg static void
   1514   1.1     joerg x86emuOp_cmp_word_AX_IMM(struct X86EMU *emu)
   1515   1.1     joerg {
   1516   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1517   1.1     joerg 		x86emuOp32_cmp_word_AX_IMM(emu);
   1518   1.1     joerg 	else
   1519   1.1     joerg 		x86emuOp16_cmp_word_AX_IMM(emu);
   1520   1.1     joerg }
   1521   1.1     joerg /****************************************************************************
   1522   1.1     joerg REMARKS:
   1523   1.1     joerg Handles opcode 0x60
   1524   1.1     joerg ****************************************************************************/
   1525   1.1     joerg static void
   1526   1.1     joerg x86emuOp_push_all(struct X86EMU *emu)
   1527   1.1     joerg {
   1528   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1529   1.1     joerg 		uint32_t old_sp = emu->x86.R_ESP;
   1530   1.1     joerg 
   1531   1.1     joerg 		push_long(emu, emu->x86.R_EAX);
   1532   1.1     joerg 		push_long(emu, emu->x86.R_ECX);
   1533   1.1     joerg 		push_long(emu, emu->x86.R_EDX);
   1534   1.1     joerg 		push_long(emu, emu->x86.R_EBX);
   1535   1.1     joerg 		push_long(emu, old_sp);
   1536   1.1     joerg 		push_long(emu, emu->x86.R_EBP);
   1537   1.1     joerg 		push_long(emu, emu->x86.R_ESI);
   1538   1.1     joerg 		push_long(emu, emu->x86.R_EDI);
   1539   1.1     joerg 	} else {
   1540   1.1     joerg 		uint16_t old_sp = emu->x86.R_SP;
   1541   1.1     joerg 
   1542   1.1     joerg 		push_word(emu, emu->x86.R_AX);
   1543   1.1     joerg 		push_word(emu, emu->x86.R_CX);
   1544   1.1     joerg 		push_word(emu, emu->x86.R_DX);
   1545   1.1     joerg 		push_word(emu, emu->x86.R_BX);
   1546   1.1     joerg 		push_word(emu, old_sp);
   1547   1.1     joerg 		push_word(emu, emu->x86.R_BP);
   1548   1.1     joerg 		push_word(emu, emu->x86.R_SI);
   1549   1.1     joerg 		push_word(emu, emu->x86.R_DI);
   1550   1.1     joerg 	}
   1551   1.1     joerg }
   1552   1.1     joerg /****************************************************************************
   1553   1.1     joerg REMARKS:
   1554   1.1     joerg Handles opcode 0x61
   1555   1.1     joerg ****************************************************************************/
   1556   1.1     joerg static void
   1557   1.1     joerg x86emuOp_pop_all(struct X86EMU *emu)
   1558   1.1     joerg {
   1559   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1560   1.1     joerg 		emu->x86.R_EDI = pop_long(emu);
   1561   1.1     joerg 		emu->x86.R_ESI = pop_long(emu);
   1562   1.1     joerg 		emu->x86.R_EBP = pop_long(emu);
   1563   1.1     joerg 		emu->x86.R_ESP += 4;	/* skip ESP */
   1564   1.1     joerg 		emu->x86.R_EBX = pop_long(emu);
   1565   1.1     joerg 		emu->x86.R_EDX = pop_long(emu);
   1566   1.1     joerg 		emu->x86.R_ECX = pop_long(emu);
   1567   1.1     joerg 		emu->x86.R_EAX = pop_long(emu);
   1568   1.1     joerg 	} else {
   1569   1.1     joerg 		emu->x86.R_DI = pop_word(emu);
   1570   1.1     joerg 		emu->x86.R_SI = pop_word(emu);
   1571   1.1     joerg 		emu->x86.R_BP = pop_word(emu);
   1572   1.1     joerg 		emu->x86.R_SP += 2;/* skip SP */
   1573   1.1     joerg 		emu->x86.R_BX = pop_word(emu);
   1574   1.1     joerg 		emu->x86.R_DX = pop_word(emu);
   1575   1.1     joerg 		emu->x86.R_CX = pop_word(emu);
   1576   1.1     joerg 		emu->x86.R_AX = pop_word(emu);
   1577   1.1     joerg 	}
   1578   1.1     joerg }
   1579   1.1     joerg /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
   1580   1.1     joerg /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
   1581   1.1     joerg 
   1582   1.1     joerg /****************************************************************************
   1583   1.1     joerg REMARKS:
   1584   1.1     joerg Handles opcode 0x68
   1585   1.1     joerg ****************************************************************************/
   1586   1.1     joerg static void
   1587   1.1     joerg x86emuOp_push_word_IMM(struct X86EMU *emu)
   1588   1.1     joerg {
   1589   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1590   1.1     joerg 		uint32_t imm;
   1591   1.1     joerg 
   1592   1.1     joerg 		imm = fetch_long_imm(emu);
   1593   1.1     joerg 		push_long(emu, imm);
   1594   1.1     joerg 	} else {
   1595   1.1     joerg 		uint16_t imm;
   1596   1.1     joerg 
   1597   1.1     joerg 		imm = fetch_word_imm(emu);
   1598   1.1     joerg 		push_word(emu, imm);
   1599   1.1     joerg 	}
   1600   1.1     joerg }
   1601   1.1     joerg /****************************************************************************
   1602   1.1     joerg REMARKS:
   1603   1.1     joerg Handles opcode 0x6a
   1604   1.1     joerg ****************************************************************************/
   1605   1.1     joerg static void
   1606   1.1     joerg x86emuOp_push_byte_IMM(struct X86EMU *emu)
   1607   1.1     joerg {
   1608   1.1     joerg 	int16_t imm;
   1609   1.1     joerg 
   1610   1.1     joerg 	imm = (int8_t) fetch_byte_imm(emu);
   1611   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1612   1.1     joerg 		push_long(emu, (int32_t) imm);
   1613   1.1     joerg 	} else {
   1614   1.1     joerg 		push_word(emu, imm);
   1615   1.1     joerg 	}
   1616   1.1     joerg }
   1617   1.1     joerg /****************************************************************************
   1618   1.1     joerg REMARKS:
   1619   1.1     joerg Handles opcode 0x6c
   1620   1.1     joerg ****************************************************************************/
   1621   1.1     joerg /****************************************************************************
   1622   1.1     joerg REMARKS:
   1623   1.1     joerg Handles opcode 0x6d
   1624   1.1     joerg ****************************************************************************/
   1625   1.1     joerg static void
   1626   1.1     joerg x86emuOp_ins_word(struct X86EMU *emu)
   1627   1.1     joerg {
   1628   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1629   1.1     joerg 		ins(emu, 4);
   1630   1.1     joerg 	} else {
   1631   1.1     joerg 		ins(emu, 2);
   1632   1.1     joerg 	}
   1633   1.1     joerg }
   1634   1.1     joerg /****************************************************************************
   1635   1.1     joerg REMARKS:
   1636   1.1     joerg Handles opcode 0x6f
   1637   1.1     joerg ****************************************************************************/
   1638   1.1     joerg static void
   1639   1.1     joerg x86emuOp_outs_word(struct X86EMU *emu)
   1640   1.1     joerg {
   1641   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   1642   1.1     joerg 		outs(emu, 4);
   1643   1.1     joerg 	} else {
   1644   1.1     joerg 		outs(emu, 2);
   1645   1.1     joerg 	}
   1646   1.1     joerg }
   1647   1.1     joerg /****************************************************************************
   1648   1.1     joerg REMARKS:
   1649   1.1     joerg Handles opcode 0x7c
   1650   1.1     joerg ****************************************************************************/
   1651   1.1     joerg static void
   1652   1.1     joerg x86emuOp_jump_near_L(struct X86EMU *emu)
   1653   1.1     joerg {
   1654   1.1     joerg 	bool sf, of;
   1655   1.1     joerg 
   1656   1.1     joerg 	sf = ACCESS_FLAG(F_SF) != 0;
   1657   1.1     joerg 	of = ACCESS_FLAG(F_OF) != 0;
   1658   1.1     joerg 
   1659   1.1     joerg 	common_jmp_near(emu, sf != of);
   1660   1.1     joerg }
   1661   1.1     joerg /****************************************************************************
   1662   1.1     joerg REMARKS:
   1663   1.1     joerg Handles opcode 0x7d
   1664   1.1     joerg ****************************************************************************/
   1665   1.1     joerg static void
   1666   1.1     joerg x86emuOp_jump_near_NL(struct X86EMU *emu)
   1667   1.1     joerg {
   1668   1.1     joerg 	bool sf, of;
   1669   1.1     joerg 
   1670   1.1     joerg 	sf = ACCESS_FLAG(F_SF) != 0;
   1671   1.1     joerg 	of = ACCESS_FLAG(F_OF) != 0;
   1672   1.1     joerg 
   1673   1.1     joerg 	common_jmp_near(emu, sf == of);
   1674   1.1     joerg }
   1675   1.1     joerg /****************************************************************************
   1676   1.1     joerg REMARKS:
   1677   1.1     joerg Handles opcode 0x7e
   1678   1.1     joerg ****************************************************************************/
   1679   1.1     joerg static void
   1680   1.1     joerg x86emuOp_jump_near_LE(struct X86EMU *emu)
   1681   1.1     joerg {
   1682   1.1     joerg 	bool sf, of;
   1683   1.1     joerg 
   1684   1.1     joerg 	sf = ACCESS_FLAG(F_SF) != 0;
   1685   1.1     joerg 	of = ACCESS_FLAG(F_OF) != 0;
   1686   1.1     joerg 
   1687   1.1     joerg 	common_jmp_near(emu, sf != of || ACCESS_FLAG(F_ZF));
   1688   1.1     joerg }
   1689   1.1     joerg /****************************************************************************
   1690   1.1     joerg REMARKS:
   1691   1.1     joerg Handles opcode 0x7f
   1692   1.1     joerg ****************************************************************************/
   1693   1.1     joerg static void
   1694   1.1     joerg x86emuOp_jump_near_NLE(struct X86EMU *emu)
   1695   1.1     joerg {
   1696   1.1     joerg 	bool sf, of;
   1697   1.1     joerg 
   1698   1.1     joerg 	sf = ACCESS_FLAG(F_SF) != 0;
   1699   1.1     joerg 	of = ACCESS_FLAG(F_OF) != 0;
   1700   1.1     joerg 
   1701   1.1     joerg 	common_jmp_near(emu, sf == of && !ACCESS_FLAG(F_ZF));
   1702   1.1     joerg }
   1703   1.1     joerg 
   1704   1.1     joerg static
   1705   1.1     joerg uint8_t(*const opc80_byte_operation[]) (struct X86EMU *, uint8_t d, uint8_t s) =
   1706   1.1     joerg {
   1707   1.1     joerg 	add_byte,		/* 00 */
   1708   1.1     joerg 	or_byte,		/* 01 */
   1709   1.1     joerg 	adc_byte,		/* 02 */
   1710   1.1     joerg 	sbb_byte,		/* 03 */
   1711   1.1     joerg 	and_byte,		/* 04 */
   1712   1.1     joerg 	sub_byte,		/* 05 */
   1713   1.1     joerg 	xor_byte,		/* 06 */
   1714   1.1     joerg 	cmp_byte,		/* 07 */
   1715   1.1     joerg };
   1716   1.1     joerg /****************************************************************************
   1717   1.1     joerg REMARKS:
   1718   1.1     joerg Handles opcode 0x80
   1719   1.1     joerg ****************************************************************************/
   1720   1.1     joerg static void
   1721   1.1     joerg x86emuOp_opc80_byte_RM_IMM(struct X86EMU *emu)
   1722   1.1     joerg {
   1723   1.1     joerg 	uint8_t imm, destval;
   1724   1.1     joerg 
   1725   1.1     joerg 	/*
   1726   1.1     joerg          * Weirdo special case instruction format.  Part of the opcode
   1727   1.1     joerg          * held below in "RH".  Doubly nested case would result, except
   1728   1.1     joerg          * that the decoded instruction
   1729   1.1     joerg          */
   1730   1.1     joerg 	fetch_decode_modrm(emu);
   1731   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   1732   1.1     joerg 	imm = fetch_byte_imm(emu);
   1733   1.1     joerg 	destval = (*opc80_byte_operation[emu->cur_rh]) (emu, destval, imm);
   1734   1.1     joerg 	if (emu->cur_rh != 7)
   1735   1.1     joerg 		write_back_byte(emu, destval);
   1736   1.1     joerg }
   1737   1.1     joerg 
   1738   1.1     joerg static
   1739   1.1     joerg uint16_t(* const opc81_word_operation[]) (struct X86EMU *, uint16_t d, uint16_t s) =
   1740   1.1     joerg {
   1741   1.1     joerg 	add_word,		/* 00 */
   1742   1.1     joerg 	or_word,		/* 01 */
   1743   1.1     joerg 	adc_word,		/* 02 */
   1744   1.1     joerg 	sbb_word,		/* 03 */
   1745   1.1     joerg 	and_word,		/* 04 */
   1746   1.1     joerg 	sub_word,		/* 05 */
   1747   1.1     joerg 	xor_word,		/* 06 */
   1748   1.1     joerg 	cmp_word,		/* 07 */
   1749   1.1     joerg };
   1750   1.1     joerg 
   1751   1.1     joerg static
   1752   1.1     joerg uint32_t(* const opc81_long_operation[]) (struct X86EMU *, uint32_t d, uint32_t s) =
   1753   1.1     joerg {
   1754   1.1     joerg 	add_long,		/* 00 */
   1755   1.1     joerg 	or_long,		/* 01 */
   1756   1.1     joerg 	adc_long,		/* 02 */
   1757   1.1     joerg 	sbb_long,		/* 03 */
   1758   1.1     joerg 	and_long,		/* 04 */
   1759   1.1     joerg 	sub_long,		/* 05 */
   1760   1.1     joerg 	xor_long,		/* 06 */
   1761   1.1     joerg 	cmp_long,		/* 07 */
   1762   1.1     joerg };
   1763   1.1     joerg /****************************************************************************
   1764   1.1     joerg REMARKS:
   1765   1.1     joerg Handles opcode 0x81
   1766   1.1     joerg ****************************************************************************/
   1767   1.1     joerg static void
   1768   1.1     joerg x86emuOp32_opc81_word_RM_IMM(struct X86EMU *emu)
   1769   1.1     joerg {
   1770   1.1     joerg 	uint32_t destval, imm;
   1771   1.1     joerg 
   1772   1.1     joerg 	/*
   1773   1.1     joerg          * Weirdo special case instruction format.  Part of the opcode
   1774   1.1     joerg          * held below in "RH".  Doubly nested case would result, except
   1775   1.1     joerg          * that the decoded instruction
   1776   1.1     joerg          */
   1777   1.1     joerg 	fetch_decode_modrm(emu);
   1778   1.1     joerg 	destval = decode_and_fetch_long(emu);
   1779   1.1     joerg 	imm = fetch_long_imm(emu);
   1780   1.1     joerg 	destval = (*opc81_long_operation[emu->cur_rh]) (emu, destval, imm);
   1781   1.1     joerg 	if (emu->cur_rh != 7)
   1782   1.1     joerg 		write_back_long(emu, destval);
   1783   1.1     joerg }
   1784   1.1     joerg 
   1785   1.1     joerg static void
   1786   1.1     joerg x86emuOp16_opc81_word_RM_IMM(struct X86EMU *emu)
   1787   1.1     joerg {
   1788   1.1     joerg 	uint16_t destval, imm;
   1789   1.1     joerg 
   1790   1.1     joerg 	/*
   1791   1.1     joerg          * Weirdo special case instruction format.  Part of the opcode
   1792   1.1     joerg          * held below in "RH".  Doubly nested case would result, except
   1793   1.1     joerg          * that the decoded instruction
   1794   1.1     joerg          */
   1795   1.1     joerg 	fetch_decode_modrm(emu);
   1796   1.1     joerg 	destval = decode_and_fetch_word(emu);
   1797   1.1     joerg 	imm = fetch_word_imm(emu);
   1798   1.1     joerg 	destval = (*opc81_word_operation[emu->cur_rh]) (emu, destval, imm);
   1799   1.1     joerg 	if (emu->cur_rh != 7)
   1800   1.1     joerg 		write_back_word(emu, destval);
   1801   1.1     joerg }
   1802   1.1     joerg 
   1803   1.1     joerg static void
   1804   1.1     joerg x86emuOp_opc81_word_RM_IMM(struct X86EMU *emu)
   1805   1.1     joerg {
   1806   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1807   1.1     joerg 		x86emuOp32_opc81_word_RM_IMM(emu);
   1808   1.1     joerg 	else
   1809   1.1     joerg 		x86emuOp16_opc81_word_RM_IMM(emu);
   1810   1.1     joerg }
   1811   1.1     joerg 
   1812   1.1     joerg static
   1813   1.1     joerg uint8_t(* const opc82_byte_operation[]) (struct X86EMU *, uint8_t s, uint8_t d) =
   1814   1.1     joerg {
   1815   1.1     joerg 	add_byte,		/* 00 */
   1816   1.1     joerg 	or_byte,		/* 01 *//* YYY UNUSED ???? */
   1817   1.1     joerg 	adc_byte,		/* 02 */
   1818   1.1     joerg 	sbb_byte,		/* 03 */
   1819   1.1     joerg 	and_byte,		/* 04 *//* YYY UNUSED ???? */
   1820   1.1     joerg 	sub_byte,		/* 05 */
   1821   1.1     joerg 	xor_byte,		/* 06 *//* YYY UNUSED ???? */
   1822   1.1     joerg 	cmp_byte,		/* 07 */
   1823   1.1     joerg };
   1824   1.1     joerg /****************************************************************************
   1825   1.1     joerg REMARKS:
   1826   1.1     joerg Handles opcode 0x82
   1827   1.1     joerg ****************************************************************************/
   1828   1.1     joerg static void
   1829   1.1     joerg x86emuOp_opc82_byte_RM_IMM(struct X86EMU *emu)
   1830   1.1     joerg {
   1831   1.1     joerg 	uint8_t imm, destval;
   1832   1.1     joerg 
   1833   1.1     joerg 	/*
   1834   1.1     joerg          * Weirdo special case instruction format.  Part of the opcode
   1835   1.1     joerg          * held below in "RH".  Doubly nested case would result, except
   1836   1.1     joerg          * that the decoded instruction Similar to opcode 81, except that
   1837   1.1     joerg          * the immediate byte is sign extended to a word length.
   1838   1.1     joerg          */
   1839   1.1     joerg 	fetch_decode_modrm(emu);
   1840   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   1841   1.1     joerg 	imm = fetch_byte_imm(emu);
   1842   1.1     joerg 	destval = (*opc82_byte_operation[emu->cur_rh]) (emu, destval, imm);
   1843   1.1     joerg 	if (emu->cur_rh != 7)
   1844   1.1     joerg 		write_back_byte(emu, destval);
   1845   1.1     joerg }
   1846   1.1     joerg 
   1847   1.1     joerg static
   1848   1.1     joerg uint16_t(* const opc83_word_operation[]) (struct X86EMU *, uint16_t s, uint16_t d) =
   1849   1.1     joerg {
   1850   1.1     joerg 	add_word,		/* 00 */
   1851   1.1     joerg 	or_word,		/* 01 *//* YYY UNUSED ???? */
   1852   1.1     joerg 	adc_word,		/* 02 */
   1853   1.1     joerg 	sbb_word,		/* 03 */
   1854   1.1     joerg 	and_word,		/* 04 *//* YYY UNUSED ???? */
   1855   1.1     joerg 	sub_word,		/* 05 */
   1856   1.1     joerg 	xor_word,		/* 06 *//* YYY UNUSED ???? */
   1857   1.1     joerg 	cmp_word,		/* 07 */
   1858   1.1     joerg };
   1859   1.1     joerg 
   1860   1.1     joerg static
   1861   1.1     joerg uint32_t(* const opc83_long_operation[]) (struct X86EMU *, uint32_t s, uint32_t d) =
   1862   1.1     joerg {
   1863   1.1     joerg 	add_long,		/* 00 */
   1864   1.1     joerg 	or_long,		/* 01 *//* YYY UNUSED ???? */
   1865   1.1     joerg 	adc_long,		/* 02 */
   1866   1.1     joerg 	sbb_long,		/* 03 */
   1867   1.1     joerg 	and_long,		/* 04 *//* YYY UNUSED ???? */
   1868   1.1     joerg 	sub_long,		/* 05 */
   1869   1.1     joerg 	xor_long,		/* 06 *//* YYY UNUSED ???? */
   1870   1.1     joerg 	cmp_long,		/* 07 */
   1871   1.1     joerg };
   1872   1.1     joerg /****************************************************************************
   1873   1.1     joerg REMARKS:
   1874   1.1     joerg Handles opcode 0x83
   1875   1.1     joerg ****************************************************************************/
   1876   1.1     joerg static void
   1877   1.1     joerg x86emuOp32_opc83_word_RM_IMM(struct X86EMU *emu)
   1878   1.1     joerg {
   1879   1.1     joerg 	uint32_t destval, imm;
   1880   1.1     joerg 
   1881   1.1     joerg 	fetch_decode_modrm(emu);
   1882   1.1     joerg 	destval = decode_and_fetch_long(emu);
   1883   1.1     joerg 	imm = (int8_t) fetch_byte_imm(emu);
   1884   1.1     joerg 	destval = (*opc83_long_operation[emu->cur_rh]) (emu, destval, imm);
   1885   1.1     joerg 	if (emu->cur_rh != 7)
   1886   1.1     joerg 		write_back_long(emu, destval);
   1887   1.1     joerg }
   1888   1.1     joerg 
   1889   1.1     joerg static void
   1890   1.1     joerg x86emuOp16_opc83_word_RM_IMM(struct X86EMU *emu)
   1891   1.1     joerg {
   1892   1.1     joerg 	uint16_t destval, imm;
   1893   1.1     joerg 
   1894   1.1     joerg 	fetch_decode_modrm(emu);
   1895   1.1     joerg 	destval = decode_and_fetch_word(emu);
   1896   1.1     joerg 	imm = (int8_t) fetch_byte_imm(emu);
   1897   1.1     joerg 	destval = (*opc83_word_operation[emu->cur_rh]) (emu, destval, imm);
   1898   1.1     joerg 	if (emu->cur_rh != 7)
   1899   1.1     joerg 		write_back_word(emu, destval);
   1900   1.1     joerg }
   1901   1.1     joerg 
   1902   1.1     joerg static void
   1903   1.1     joerg x86emuOp_opc83_word_RM_IMM(struct X86EMU *emu)
   1904   1.1     joerg {
   1905   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1906   1.1     joerg 		x86emuOp32_opc83_word_RM_IMM(emu);
   1907   1.1     joerg 	else
   1908   1.1     joerg 		x86emuOp16_opc83_word_RM_IMM(emu);
   1909   1.1     joerg }
   1910   1.1     joerg /****************************************************************************
   1911   1.1     joerg REMARKS:
   1912   1.1     joerg Handles opcode 0x86
   1913   1.1     joerg ****************************************************************************/
   1914   1.1     joerg static void
   1915   1.1     joerg x86emuOp_xchg_byte_RM_R(struct X86EMU *emu)
   1916   1.1     joerg {
   1917   1.1     joerg 	uint8_t *srcreg, destval, tmp;
   1918   1.1     joerg 
   1919   1.1     joerg 	fetch_decode_modrm(emu);
   1920   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   1921   1.1     joerg 	srcreg = decode_rh_byte_register(emu);
   1922   1.1     joerg 	tmp = destval;
   1923   1.1     joerg 	destval = *srcreg;
   1924   1.1     joerg 	*srcreg = tmp;
   1925   1.1     joerg 	write_back_byte(emu, destval);
   1926   1.1     joerg }
   1927   1.1     joerg /****************************************************************************
   1928   1.1     joerg REMARKS:
   1929   1.1     joerg Handles opcode 0x87
   1930   1.1     joerg ****************************************************************************/
   1931   1.1     joerg static void
   1932   1.1     joerg x86emuOp32_xchg_word_RM_R(struct X86EMU *emu)
   1933   1.1     joerg {
   1934   1.1     joerg 	uint32_t *srcreg, destval, tmp;
   1935   1.1     joerg 
   1936   1.1     joerg 	fetch_decode_modrm(emu);
   1937   1.1     joerg 	destval = decode_and_fetch_long(emu);
   1938   1.1     joerg 	srcreg = decode_rh_long_register(emu);
   1939   1.1     joerg 	tmp = destval;
   1940   1.1     joerg 	destval = *srcreg;
   1941   1.1     joerg 	*srcreg = tmp;
   1942   1.1     joerg 	write_back_long(emu, destval);
   1943   1.1     joerg }
   1944   1.1     joerg 
   1945   1.1     joerg static void
   1946   1.1     joerg x86emuOp16_xchg_word_RM_R(struct X86EMU *emu)
   1947   1.1     joerg {
   1948   1.1     joerg 	uint16_t *srcreg, destval, tmp;
   1949   1.1     joerg 
   1950   1.1     joerg 	fetch_decode_modrm(emu);
   1951   1.1     joerg 	destval = decode_and_fetch_word(emu);
   1952   1.1     joerg 	srcreg = decode_rh_word_register(emu);
   1953   1.1     joerg 	tmp = destval;
   1954   1.1     joerg 	destval = *srcreg;
   1955   1.1     joerg 	*srcreg = tmp;
   1956   1.1     joerg 	write_back_word(emu, destval);
   1957   1.1     joerg }
   1958   1.1     joerg 
   1959   1.1     joerg static void
   1960   1.1     joerg x86emuOp_xchg_word_RM_R(struct X86EMU *emu)
   1961   1.1     joerg {
   1962   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   1963   1.1     joerg 		x86emuOp32_xchg_word_RM_R(emu);
   1964   1.1     joerg 	else
   1965   1.1     joerg 		x86emuOp16_xchg_word_RM_R(emu);
   1966   1.1     joerg }
   1967   1.1     joerg /****************************************************************************
   1968   1.1     joerg REMARKS:
   1969   1.1     joerg Handles opcode 0x88
   1970   1.1     joerg ****************************************************************************/
   1971   1.1     joerg static void
   1972   1.1     joerg x86emuOp_mov_byte_RM_R(struct X86EMU *emu)
   1973   1.1     joerg {
   1974   1.1     joerg 	uint8_t *destreg, *srcreg;
   1975   1.1     joerg 	uint32_t destoffset;
   1976   1.1     joerg 
   1977   1.1     joerg 	fetch_decode_modrm(emu);
   1978   1.1     joerg 	srcreg = decode_rh_byte_register(emu);
   1979   1.1     joerg 	if (emu->cur_mod != 3) {
   1980   1.1     joerg 		destoffset = decode_rl_address(emu);
   1981   1.1     joerg 		store_data_byte(emu, destoffset, *srcreg);
   1982   1.1     joerg 	} else {
   1983   1.1     joerg 		destreg = decode_rl_byte_register(emu);
   1984   1.1     joerg 		*destreg = *srcreg;
   1985   1.1     joerg 	}
   1986   1.1     joerg }
   1987   1.1     joerg /****************************************************************************
   1988   1.1     joerg REMARKS:
   1989   1.1     joerg Handles opcode 0x89
   1990   1.1     joerg ****************************************************************************/
   1991   1.1     joerg static void
   1992   1.1     joerg x86emuOp32_mov_word_RM_R(struct X86EMU *emu)
   1993   1.1     joerg {
   1994   1.1     joerg 	uint32_t destoffset;
   1995   1.1     joerg 	uint32_t *destreg, srcval;
   1996   1.1     joerg 
   1997   1.1     joerg 	fetch_decode_modrm(emu);
   1998   1.1     joerg 	srcval = *decode_rh_long_register(emu);
   1999   1.1     joerg 	if (emu->cur_mod != 3) {
   2000   1.1     joerg 		destoffset = decode_rl_address(emu);
   2001   1.1     joerg 		store_data_long(emu, destoffset, srcval);
   2002   1.1     joerg 	} else {
   2003   1.1     joerg 		destreg = decode_rl_long_register(emu);
   2004   1.1     joerg 		*destreg = srcval;
   2005   1.1     joerg 	}
   2006   1.1     joerg }
   2007   1.1     joerg 
   2008   1.1     joerg static void
   2009   1.1     joerg x86emuOp16_mov_word_RM_R(struct X86EMU *emu)
   2010   1.1     joerg {
   2011   1.1     joerg 	uint32_t destoffset;
   2012   1.1     joerg 	uint16_t *destreg, srcval;
   2013   1.1     joerg 
   2014   1.1     joerg 	fetch_decode_modrm(emu);
   2015   1.1     joerg 	srcval = *decode_rh_word_register(emu);
   2016   1.1     joerg 	if (emu->cur_mod != 3) {
   2017   1.1     joerg 		destoffset = decode_rl_address(emu);
   2018   1.1     joerg 		store_data_word(emu, destoffset, srcval);
   2019   1.1     joerg 	} else {
   2020   1.1     joerg 		destreg = decode_rl_word_register(emu);
   2021   1.1     joerg 		*destreg = srcval;
   2022   1.1     joerg 	}
   2023   1.1     joerg }
   2024   1.1     joerg 
   2025   1.1     joerg static void
   2026   1.1     joerg x86emuOp_mov_word_RM_R(struct X86EMU *emu)
   2027   1.1     joerg {
   2028   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2029   1.1     joerg 		x86emuOp32_mov_word_RM_R(emu);
   2030   1.1     joerg 	else
   2031   1.1     joerg 		x86emuOp16_mov_word_RM_R(emu);
   2032   1.1     joerg }
   2033   1.1     joerg /****************************************************************************
   2034   1.1     joerg REMARKS:
   2035   1.1     joerg Handles opcode 0x8a
   2036   1.1     joerg ****************************************************************************/
   2037   1.1     joerg static void
   2038   1.1     joerg x86emuOp_mov_byte_R_RM(struct X86EMU *emu)
   2039   1.1     joerg {
   2040   1.1     joerg 	uint8_t *destreg;
   2041   1.1     joerg 
   2042   1.1     joerg 	fetch_decode_modrm(emu);
   2043   1.1     joerg 	destreg = decode_rh_byte_register(emu);
   2044   1.1     joerg 	*destreg = decode_and_fetch_byte(emu);
   2045   1.1     joerg }
   2046   1.1     joerg /****************************************************************************
   2047   1.1     joerg REMARKS:
   2048   1.1     joerg Handles opcode 0x8b
   2049   1.1     joerg ****************************************************************************/
   2050   1.1     joerg static void
   2051   1.1     joerg x86emuOp_mov_word_R_RM(struct X86EMU *emu)
   2052   1.1     joerg {
   2053   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2054   1.1     joerg 		uint32_t *destreg;
   2055   1.1     joerg 
   2056   1.1     joerg 		fetch_decode_modrm(emu);
   2057   1.1     joerg 		destreg = decode_rh_long_register(emu);
   2058   1.1     joerg 		*destreg = decode_and_fetch_long(emu);
   2059   1.1     joerg 	} else {
   2060   1.1     joerg 		uint16_t *destreg;
   2061   1.1     joerg 
   2062   1.1     joerg 		fetch_decode_modrm(emu);
   2063   1.1     joerg 		destreg = decode_rh_word_register(emu);
   2064   1.1     joerg 		*destreg = decode_and_fetch_word(emu);
   2065   1.1     joerg 	}
   2066   1.1     joerg }
   2067   1.1     joerg /****************************************************************************
   2068   1.1     joerg REMARKS:
   2069   1.1     joerg Handles opcode 0x8c
   2070   1.1     joerg ****************************************************************************/
   2071   1.1     joerg static void
   2072   1.1     joerg x86emuOp_mov_word_RM_SR(struct X86EMU *emu)
   2073   1.1     joerg {
   2074   1.1     joerg 	uint16_t *destreg, srcval;
   2075   1.1     joerg 	uint32_t destoffset;
   2076   1.1     joerg 
   2077   1.1     joerg 	fetch_decode_modrm(emu);
   2078   1.1     joerg 	srcval = *decode_rh_seg_register(emu);
   2079   1.1     joerg 	if (emu->cur_mod != 3) {
   2080   1.1     joerg 		destoffset = decode_rl_address(emu);
   2081   1.1     joerg 		store_data_word(emu, destoffset, srcval);
   2082   1.1     joerg 	} else {
   2083   1.1     joerg 		destreg = decode_rl_word_register(emu);
   2084   1.1     joerg 		*destreg = srcval;
   2085   1.1     joerg 	}
   2086   1.1     joerg }
   2087   1.1     joerg /****************************************************************************
   2088   1.1     joerg REMARKS:
   2089   1.1     joerg Handles opcode 0x8d
   2090   1.1     joerg ****************************************************************************/
   2091   1.1     joerg static void
   2092   1.1     joerg x86emuOp_lea_word_R_M(struct X86EMU *emu)
   2093   1.1     joerg {
   2094   1.1     joerg 	uint32_t destoffset;
   2095   1.1     joerg 
   2096   1.1     joerg 	fetch_decode_modrm(emu);
   2097   1.1     joerg 	if (emu->cur_mod == 3)
   2098   1.1     joerg 		X86EMU_halt_sys(emu);
   2099   1.1     joerg 
   2100   1.1     joerg 	destoffset = decode_rl_address(emu);
   2101   1.9     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
   2102   1.9     joerg 		uint32_t *srcreg;
   2103   1.9     joerg 
   2104   1.9     joerg 		srcreg = decode_rh_long_register(emu);
   2105   1.9     joerg 		*srcreg = (uint32_t) destoffset;
   2106   1.9     joerg 	} else {
   2107   1.9     joerg 		uint16_t *srcreg;
   2108   1.9     joerg 
   2109   1.9     joerg 		srcreg = decode_rh_word_register(emu);
   2110   1.9     joerg 		*srcreg = (uint16_t) destoffset;
   2111   1.9     joerg 	}
   2112   1.1     joerg }
   2113   1.1     joerg /****************************************************************************
   2114   1.1     joerg REMARKS:
   2115   1.1     joerg Handles opcode 0x8e
   2116   1.1     joerg ****************************************************************************/
   2117   1.1     joerg static void
   2118   1.1     joerg x86emuOp_mov_word_SR_RM(struct X86EMU *emu)
   2119   1.1     joerg {
   2120   1.1     joerg 	uint16_t *destreg;
   2121   1.1     joerg 
   2122   1.1     joerg 	fetch_decode_modrm(emu);
   2123   1.1     joerg 	destreg = decode_rh_seg_register(emu);
   2124   1.1     joerg 	*destreg = decode_and_fetch_word(emu);
   2125   1.1     joerg 	/*
   2126   1.1     joerg          * Clean up, and reset all the R_xSP pointers to the correct
   2127   1.1     joerg          * locations.  This is about 3x too much overhead (doing all the
   2128   1.1     joerg          * segreg ptrs when only one is needed, but this instruction
   2129   1.1     joerg          * *cannot* be that common, and this isn't too much work anyway.
   2130   1.1     joerg          */
   2131   1.1     joerg }
   2132   1.1     joerg /****************************************************************************
   2133   1.1     joerg REMARKS:
   2134   1.1     joerg Handles opcode 0x8f
   2135   1.1     joerg ****************************************************************************/
   2136   1.1     joerg static void
   2137   1.1     joerg x86emuOp32_pop_RM(struct X86EMU *emu)
   2138   1.1     joerg {
   2139   1.1     joerg 	uint32_t destoffset;
   2140   1.1     joerg 	uint32_t destval, *destreg;
   2141   1.1     joerg 
   2142   1.1     joerg 	fetch_decode_modrm(emu);
   2143   1.1     joerg 	if (emu->cur_mod != 3) {
   2144   1.1     joerg 		destoffset = decode_rl_address(emu);
   2145   1.1     joerg 		destval = pop_long(emu);
   2146   1.1     joerg 		store_data_long(emu, destoffset, destval);
   2147   1.1     joerg 	} else {
   2148   1.1     joerg 		destreg = decode_rl_long_register(emu);
   2149   1.1     joerg 		*destreg = pop_long(emu);
   2150   1.1     joerg 	}
   2151   1.1     joerg }
   2152   1.1     joerg 
   2153   1.1     joerg static void
   2154   1.1     joerg x86emuOp16_pop_RM(struct X86EMU *emu)
   2155   1.1     joerg {
   2156   1.1     joerg 	uint32_t destoffset;
   2157   1.1     joerg 	uint16_t destval, *destreg;
   2158   1.1     joerg 
   2159   1.1     joerg 	fetch_decode_modrm(emu);
   2160   1.1     joerg 	if (emu->cur_mod != 3) {
   2161   1.1     joerg 		destoffset = decode_rl_address(emu);
   2162   1.1     joerg 		destval = pop_word(emu);
   2163   1.1     joerg 		store_data_word(emu, destoffset, destval);
   2164   1.1     joerg 	} else {
   2165   1.1     joerg 		destreg = decode_rl_word_register(emu);
   2166   1.1     joerg 		*destreg = pop_word(emu);
   2167   1.1     joerg 	}
   2168   1.1     joerg }
   2169   1.1     joerg 
   2170   1.1     joerg static void
   2171   1.1     joerg x86emuOp_pop_RM(struct X86EMU *emu)
   2172   1.1     joerg {
   2173   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2174   1.1     joerg 		x86emuOp32_pop_RM(emu);
   2175   1.1     joerg 	else
   2176   1.1     joerg 		x86emuOp16_pop_RM(emu);
   2177   1.1     joerg }
   2178   1.1     joerg /****************************************************************************
   2179   1.1     joerg REMARKS:
   2180   1.1     joerg Handles opcode 0x91
   2181   1.1     joerg ****************************************************************************/
   2182   1.1     joerg static void
   2183   1.1     joerg x86emuOp_xchg_word_AX_CX(struct X86EMU *emu)
   2184   1.1     joerg {
   2185   1.1     joerg 	uint32_t tmp;
   2186   1.1     joerg 
   2187   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2188   1.1     joerg 		tmp = emu->x86.R_EAX;
   2189   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_ECX;
   2190   1.1     joerg 		emu->x86.R_ECX = tmp;
   2191   1.1     joerg 	} else {
   2192   1.1     joerg 		tmp = emu->x86.R_AX;
   2193   1.1     joerg 		emu->x86.R_AX = emu->x86.R_CX;
   2194   1.1     joerg 		emu->x86.R_CX = (uint16_t) tmp;
   2195   1.1     joerg 	}
   2196   1.1     joerg }
   2197   1.1     joerg /****************************************************************************
   2198   1.1     joerg REMARKS:
   2199   1.1     joerg Handles opcode 0x92
   2200   1.1     joerg ****************************************************************************/
   2201   1.1     joerg static void
   2202   1.1     joerg x86emuOp_xchg_word_AX_DX(struct X86EMU *emu)
   2203   1.1     joerg {
   2204   1.1     joerg 	uint32_t tmp;
   2205   1.1     joerg 
   2206   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2207   1.1     joerg 		tmp = emu->x86.R_EAX;
   2208   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_EDX;
   2209   1.1     joerg 		emu->x86.R_EDX = tmp;
   2210   1.1     joerg 	} else {
   2211   1.1     joerg 		tmp = emu->x86.R_AX;
   2212   1.1     joerg 		emu->x86.R_AX = emu->x86.R_DX;
   2213   1.1     joerg 		emu->x86.R_DX = (uint16_t) tmp;
   2214   1.1     joerg 	}
   2215   1.1     joerg }
   2216   1.1     joerg /****************************************************************************
   2217   1.1     joerg REMARKS:
   2218   1.1     joerg Handles opcode 0x93
   2219   1.1     joerg ****************************************************************************/
   2220   1.1     joerg static void
   2221   1.1     joerg x86emuOp_xchg_word_AX_BX(struct X86EMU *emu)
   2222   1.1     joerg {
   2223   1.1     joerg 	uint32_t tmp;
   2224   1.1     joerg 
   2225   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2226   1.1     joerg 		tmp = emu->x86.R_EAX;
   2227   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_EBX;
   2228   1.1     joerg 		emu->x86.R_EBX = tmp;
   2229   1.1     joerg 	} else {
   2230   1.1     joerg 		tmp = emu->x86.R_AX;
   2231   1.1     joerg 		emu->x86.R_AX = emu->x86.R_BX;
   2232   1.1     joerg 		emu->x86.R_BX = (uint16_t) tmp;
   2233   1.1     joerg 	}
   2234   1.1     joerg }
   2235   1.1     joerg /****************************************************************************
   2236   1.1     joerg REMARKS:
   2237   1.1     joerg Handles opcode 0x94
   2238   1.1     joerg ****************************************************************************/
   2239   1.1     joerg static void
   2240   1.1     joerg x86emuOp_xchg_word_AX_SP(struct X86EMU *emu)
   2241   1.1     joerg {
   2242   1.1     joerg 	uint32_t tmp;
   2243   1.1     joerg 
   2244   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2245   1.1     joerg 		tmp = emu->x86.R_EAX;
   2246   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_ESP;
   2247   1.1     joerg 		emu->x86.R_ESP = tmp;
   2248   1.1     joerg 	} else {
   2249   1.1     joerg 		tmp = emu->x86.R_AX;
   2250   1.1     joerg 		emu->x86.R_AX = emu->x86.R_SP;
   2251   1.1     joerg 		emu->x86.R_SP = (uint16_t) tmp;
   2252   1.1     joerg 	}
   2253   1.1     joerg }
   2254   1.1     joerg /****************************************************************************
   2255   1.1     joerg REMARKS:
   2256   1.1     joerg Handles opcode 0x95
   2257   1.1     joerg ****************************************************************************/
   2258   1.1     joerg static void
   2259   1.1     joerg x86emuOp_xchg_word_AX_BP(struct X86EMU *emu)
   2260   1.1     joerg {
   2261   1.1     joerg 	uint32_t tmp;
   2262   1.1     joerg 
   2263   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2264   1.1     joerg 		tmp = emu->x86.R_EAX;
   2265   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_EBP;
   2266   1.1     joerg 		emu->x86.R_EBP = tmp;
   2267   1.1     joerg 	} else {
   2268   1.1     joerg 		tmp = emu->x86.R_AX;
   2269   1.1     joerg 		emu->x86.R_AX = emu->x86.R_BP;
   2270   1.1     joerg 		emu->x86.R_BP = (uint16_t) tmp;
   2271   1.1     joerg 	}
   2272   1.1     joerg }
   2273   1.1     joerg /****************************************************************************
   2274   1.1     joerg REMARKS:
   2275   1.1     joerg Handles opcode 0x96
   2276   1.1     joerg ****************************************************************************/
   2277   1.1     joerg static void
   2278   1.1     joerg x86emuOp_xchg_word_AX_SI(struct X86EMU *emu)
   2279   1.1     joerg {
   2280   1.1     joerg 	uint32_t tmp;
   2281   1.1     joerg 
   2282   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2283   1.1     joerg 		tmp = emu->x86.R_EAX;
   2284   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_ESI;
   2285   1.1     joerg 		emu->x86.R_ESI = tmp;
   2286   1.1     joerg 	} else {
   2287   1.1     joerg 		tmp = emu->x86.R_AX;
   2288   1.1     joerg 		emu->x86.R_AX = emu->x86.R_SI;
   2289   1.1     joerg 		emu->x86.R_SI = (uint16_t) tmp;
   2290   1.1     joerg 	}
   2291   1.1     joerg }
   2292   1.1     joerg /****************************************************************************
   2293   1.1     joerg REMARKS:
   2294   1.1     joerg Handles opcode 0x97
   2295   1.1     joerg ****************************************************************************/
   2296   1.1     joerg static void
   2297   1.1     joerg x86emuOp_xchg_word_AX_DI(struct X86EMU *emu)
   2298   1.1     joerg {
   2299   1.1     joerg 	uint32_t tmp;
   2300   1.1     joerg 
   2301   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2302   1.1     joerg 		tmp = emu->x86.R_EAX;
   2303   1.1     joerg 		emu->x86.R_EAX = emu->x86.R_EDI;
   2304   1.1     joerg 		emu->x86.R_EDI = tmp;
   2305   1.1     joerg 	} else {
   2306   1.1     joerg 		tmp = emu->x86.R_AX;
   2307   1.1     joerg 		emu->x86.R_AX = emu->x86.R_DI;
   2308   1.1     joerg 		emu->x86.R_DI = (uint16_t) tmp;
   2309   1.1     joerg 	}
   2310   1.1     joerg }
   2311   1.1     joerg /****************************************************************************
   2312   1.1     joerg REMARKS:
   2313   1.1     joerg Handles opcode 0x98
   2314   1.1     joerg ****************************************************************************/
   2315   1.1     joerg static void
   2316   1.1     joerg x86emuOp_cbw(struct X86EMU *emu)
   2317   1.1     joerg {
   2318   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2319   1.1     joerg 		if (emu->x86.R_AX & 0x8000) {
   2320   1.1     joerg 			emu->x86.R_EAX |= 0xffff0000;
   2321   1.1     joerg 		} else {
   2322   1.1     joerg 			emu->x86.R_EAX &= 0x0000ffff;
   2323   1.1     joerg 		}
   2324   1.1     joerg 	} else {
   2325   1.1     joerg 		if (emu->x86.R_AL & 0x80) {
   2326   1.1     joerg 			emu->x86.R_AH = 0xff;
   2327   1.1     joerg 		} else {
   2328   1.1     joerg 			emu->x86.R_AH = 0x0;
   2329   1.1     joerg 		}
   2330   1.1     joerg 	}
   2331   1.1     joerg }
   2332   1.1     joerg /****************************************************************************
   2333   1.1     joerg REMARKS:
   2334   1.1     joerg Handles opcode 0x99
   2335   1.1     joerg ****************************************************************************/
   2336   1.1     joerg static void
   2337   1.1     joerg x86emuOp_cwd(struct X86EMU *emu)
   2338   1.1     joerg {
   2339   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2340   1.1     joerg 		if (emu->x86.R_EAX & 0x80000000) {
   2341   1.1     joerg 			emu->x86.R_EDX = 0xffffffff;
   2342   1.1     joerg 		} else {
   2343   1.1     joerg 			emu->x86.R_EDX = 0x0;
   2344   1.1     joerg 		}
   2345   1.1     joerg 	} else {
   2346   1.1     joerg 		if (emu->x86.R_AX & 0x8000) {
   2347   1.1     joerg 			emu->x86.R_DX = 0xffff;
   2348   1.1     joerg 		} else {
   2349   1.1     joerg 			emu->x86.R_DX = 0x0;
   2350   1.1     joerg 		}
   2351   1.1     joerg 	}
   2352   1.1     joerg }
   2353   1.1     joerg /****************************************************************************
   2354   1.1     joerg REMARKS:
   2355   1.1     joerg Handles opcode 0x9a
   2356   1.1     joerg ****************************************************************************/
   2357   1.1     joerg static void
   2358   1.1     joerg x86emuOp_call_far_IMM(struct X86EMU *emu)
   2359   1.1     joerg {
   2360   1.1     joerg 	uint16_t farseg, faroff;
   2361   1.1     joerg 
   2362   1.1     joerg 	faroff = fetch_word_imm(emu);
   2363   1.1     joerg 	farseg = fetch_word_imm(emu);
   2364   1.1     joerg 	/* XXX
   2365   1.1     joerg 	 *
   2366   1.1     joerg 	 * Hooked interrupt vectors calling into our "BIOS" will cause problems
   2367   1.1     joerg 	 * unless all intersegment stuff is checked for BIOS access.  Check
   2368   1.1     joerg 	 * needed here.  For moment, let it alone. */
   2369   1.1     joerg 	push_word(emu, emu->x86.R_CS);
   2370   1.1     joerg 	emu->x86.R_CS = farseg;
   2371   1.1     joerg 	push_word(emu, emu->x86.R_IP);
   2372   1.1     joerg 	emu->x86.R_IP = faroff;
   2373   1.1     joerg }
   2374   1.1     joerg /****************************************************************************
   2375   1.1     joerg REMARKS:
   2376   1.1     joerg Handles opcode 0x9c
   2377   1.1     joerg ****************************************************************************/
   2378   1.1     joerg static void
   2379   1.1     joerg x86emuOp_pushf_word(struct X86EMU *emu)
   2380   1.1     joerg {
   2381   1.1     joerg 	uint32_t flags;
   2382   1.1     joerg 
   2383   1.1     joerg 	/* clear out *all* bits not representing flags, and turn on real bits */
   2384   1.1     joerg 	flags = (emu->x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
   2385   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2386   1.1     joerg 		push_long(emu, flags);
   2387   1.1     joerg 	} else {
   2388   1.1     joerg 		push_word(emu, (uint16_t) flags);
   2389   1.1     joerg 	}
   2390   1.1     joerg }
   2391   1.1     joerg /****************************************************************************
   2392   1.1     joerg REMARKS:
   2393   1.1     joerg Handles opcode 0x9d
   2394   1.1     joerg ****************************************************************************/
   2395   1.1     joerg static void
   2396   1.1     joerg x86emuOp_popf_word(struct X86EMU *emu)
   2397   1.1     joerg {
   2398   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2399   1.1     joerg 		emu->x86.R_EFLG = pop_long(emu);
   2400   1.1     joerg 	} else {
   2401   1.1     joerg 		emu->x86.R_FLG = pop_word(emu);
   2402   1.1     joerg 	}
   2403   1.1     joerg }
   2404   1.1     joerg /****************************************************************************
   2405   1.1     joerg REMARKS:
   2406   1.1     joerg Handles opcode 0x9e
   2407   1.1     joerg ****************************************************************************/
   2408   1.1     joerg static void
   2409   1.1     joerg x86emuOp_sahf(struct X86EMU *emu)
   2410   1.1     joerg {
   2411   1.1     joerg 	/* clear the lower bits of the flag register */
   2412   1.1     joerg 	emu->x86.R_FLG &= 0xffffff00;
   2413   1.1     joerg 	/* or in the AH register into the flags register */
   2414   1.1     joerg 	emu->x86.R_FLG |= emu->x86.R_AH;
   2415   1.1     joerg }
   2416   1.1     joerg /****************************************************************************
   2417   1.1     joerg REMARKS:
   2418   1.1     joerg Handles opcode 0x9f
   2419   1.1     joerg ****************************************************************************/
   2420   1.1     joerg static void
   2421   1.1     joerg x86emuOp_lahf(struct X86EMU *emu)
   2422   1.1     joerg {
   2423   1.1     joerg 	emu->x86.R_AH = (uint8_t) (emu->x86.R_FLG & 0xff);
   2424   1.1     joerg 	/* undocumented TC++ behavior??? Nope.  It's documented, but you have
   2425   1.1     joerg 	 * too look real hard to notice it. */
   2426   1.1     joerg 	emu->x86.R_AH |= 0x2;
   2427   1.1     joerg }
   2428   1.1     joerg /****************************************************************************
   2429   1.1     joerg REMARKS:
   2430   1.1     joerg Handles opcode 0xa0
   2431   1.1     joerg ****************************************************************************/
   2432   1.1     joerg static void
   2433   1.1     joerg x86emuOp_mov_AL_M_IMM(struct X86EMU *emu)
   2434   1.1     joerg {
   2435   1.1     joerg 	uint16_t offset;
   2436   1.1     joerg 
   2437   1.1     joerg 	offset = fetch_word_imm(emu);
   2438   1.1     joerg 	emu->x86.R_AL = fetch_data_byte(emu, offset);
   2439   1.1     joerg }
   2440   1.1     joerg /****************************************************************************
   2441   1.1     joerg REMARKS:
   2442   1.1     joerg Handles opcode 0xa1
   2443   1.1     joerg ****************************************************************************/
   2444   1.1     joerg static void
   2445   1.1     joerg x86emuOp_mov_AX_M_IMM(struct X86EMU *emu)
   2446   1.1     joerg {
   2447   1.1     joerg 	uint16_t offset;
   2448   1.1     joerg 
   2449   1.1     joerg 	offset = fetch_word_imm(emu);
   2450   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2451   1.1     joerg 		emu->x86.R_EAX = fetch_data_long(emu, offset);
   2452   1.1     joerg 	} else {
   2453   1.1     joerg 		emu->x86.R_AX = fetch_data_word(emu, offset);
   2454   1.1     joerg 	}
   2455   1.1     joerg }
   2456   1.1     joerg /****************************************************************************
   2457   1.1     joerg REMARKS:
   2458   1.1     joerg Handles opcode 0xa2
   2459   1.1     joerg ****************************************************************************/
   2460   1.1     joerg static void
   2461   1.1     joerg x86emuOp_mov_M_AL_IMM(struct X86EMU *emu)
   2462   1.1     joerg {
   2463   1.1     joerg 	uint16_t offset;
   2464   1.1     joerg 
   2465   1.1     joerg 	offset = fetch_word_imm(emu);
   2466   1.1     joerg 	store_data_byte(emu, offset, emu->x86.R_AL);
   2467   1.1     joerg }
   2468   1.1     joerg /****************************************************************************
   2469   1.1     joerg REMARKS:
   2470   1.1     joerg Handles opcode 0xa3
   2471   1.1     joerg ****************************************************************************/
   2472   1.1     joerg static void
   2473   1.1     joerg x86emuOp_mov_M_AX_IMM(struct X86EMU *emu)
   2474   1.1     joerg {
   2475   1.1     joerg 	uint16_t offset;
   2476   1.1     joerg 
   2477   1.1     joerg 	offset = fetch_word_imm(emu);
   2478   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2479   1.1     joerg 		store_data_long(emu, offset, emu->x86.R_EAX);
   2480   1.1     joerg 	} else {
   2481   1.1     joerg 		store_data_word(emu, offset, emu->x86.R_AX);
   2482   1.1     joerg 	}
   2483   1.1     joerg }
   2484   1.1     joerg /****************************************************************************
   2485   1.1     joerg REMARKS:
   2486   1.1     joerg Handles opcode 0xa4
   2487   1.1     joerg ****************************************************************************/
   2488   1.1     joerg static void
   2489   1.1     joerg x86emuOp_movs_byte(struct X86EMU *emu)
   2490   1.1     joerg {
   2491   1.1     joerg 	uint8_t val;
   2492   1.1     joerg 	uint32_t count;
   2493   1.1     joerg 	int inc;
   2494   1.1     joerg 
   2495   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2496   1.1     joerg 		inc = -1;
   2497   1.1     joerg 	else
   2498   1.1     joerg 		inc = 1;
   2499   1.1     joerg 	count = 1;
   2500   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2501   1.1     joerg 		/* dont care whether REPE or REPNE */
   2502   1.1     joerg 		/* move them until CX is ZERO. */
   2503   1.1     joerg 		count = emu->x86.R_CX;
   2504   1.1     joerg 		emu->x86.R_CX = 0;
   2505   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2506   1.1     joerg 	}
   2507   1.1     joerg 	while (count--) {
   2508   1.1     joerg 		val = fetch_data_byte(emu, emu->x86.R_SI);
   2509   1.1     joerg 		store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, val);
   2510   1.1     joerg 		emu->x86.R_SI += inc;
   2511   1.1     joerg 		emu->x86.R_DI += inc;
   2512   1.1     joerg 	}
   2513   1.1     joerg }
   2514   1.1     joerg /****************************************************************************
   2515   1.1     joerg REMARKS:
   2516   1.1     joerg Handles opcode 0xa5
   2517   1.1     joerg ****************************************************************************/
   2518   1.1     joerg static void
   2519   1.1     joerg x86emuOp_movs_word(struct X86EMU *emu)
   2520   1.1     joerg {
   2521   1.1     joerg 	uint32_t val;
   2522   1.1     joerg 	int inc;
   2523   1.1     joerg 	uint32_t count;
   2524   1.1     joerg 
   2525   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2526   1.1     joerg 		inc = 4;
   2527   1.1     joerg 	else
   2528   1.1     joerg 		inc = 2;
   2529   1.1     joerg 
   2530   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2531   1.1     joerg 		inc = -inc;
   2532   1.1     joerg 
   2533   1.1     joerg 	count = 1;
   2534   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2535   1.1     joerg 		/* dont care whether REPE or REPNE */
   2536   1.1     joerg 		/* move them until CX is ZERO. */
   2537   1.1     joerg 		count = emu->x86.R_CX;
   2538   1.1     joerg 		emu->x86.R_CX = 0;
   2539   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2540   1.1     joerg 	}
   2541   1.1     joerg 	while (count--) {
   2542   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2543   1.1     joerg 			val = fetch_data_long(emu, emu->x86.R_SI);
   2544   1.1     joerg 			store_long(emu, emu->x86.R_ES, emu->x86.R_DI, val);
   2545   1.1     joerg 		} else {
   2546   1.1     joerg 			val = fetch_data_word(emu, emu->x86.R_SI);
   2547   1.1     joerg 			store_word(emu, emu->x86.R_ES, emu->x86.R_DI, (uint16_t) val);
   2548   1.1     joerg 		}
   2549   1.1     joerg 		emu->x86.R_SI += inc;
   2550   1.1     joerg 		emu->x86.R_DI += inc;
   2551   1.1     joerg 	}
   2552   1.1     joerg }
   2553   1.1     joerg /****************************************************************************
   2554   1.1     joerg REMARKS:
   2555   1.1     joerg Handles opcode 0xa6
   2556   1.1     joerg ****************************************************************************/
   2557   1.1     joerg static void
   2558   1.1     joerg x86emuOp_cmps_byte(struct X86EMU *emu)
   2559   1.1     joerg {
   2560   1.1     joerg 	int8_t val1, val2;
   2561   1.1     joerg 	int inc;
   2562   1.1     joerg 
   2563   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2564   1.1     joerg 		inc = -1;
   2565   1.1     joerg 	else
   2566   1.1     joerg 		inc = 1;
   2567   1.1     joerg 
   2568   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
   2569   1.1     joerg 		/* REPE  */
   2570   1.1     joerg 		/* move them until CX is ZERO. */
   2571   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2572   1.1     joerg 			val1 = fetch_data_byte(emu, emu->x86.R_SI);
   2573   1.1     joerg 			val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2574   1.1     joerg 			cmp_byte(emu, val1, val2);
   2575   1.1     joerg 			emu->x86.R_CX -= 1;
   2576   1.1     joerg 			emu->x86.R_SI += inc;
   2577   1.1     joerg 			emu->x86.R_DI += inc;
   2578   1.1     joerg 			if (ACCESS_FLAG(F_ZF) == 0)
   2579   1.1     joerg 				break;
   2580   1.1     joerg 		}
   2581   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
   2582   1.1     joerg 	} else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
   2583   1.1     joerg 		/* REPNE  */
   2584   1.1     joerg 		/* move them until CX is ZERO. */
   2585   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2586   1.1     joerg 			val1 = fetch_data_byte(emu, emu->x86.R_SI);
   2587   1.1     joerg 			val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2588   1.1     joerg 			cmp_byte(emu, val1, val2);
   2589   1.1     joerg 			emu->x86.R_CX -= 1;
   2590   1.1     joerg 			emu->x86.R_SI += inc;
   2591   1.1     joerg 			emu->x86.R_DI += inc;
   2592   1.1     joerg 			if (ACCESS_FLAG(F_ZF))
   2593   1.1     joerg 				break;	/* zero flag set means equal */
   2594   1.1     joerg 		}
   2595   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
   2596   1.1     joerg 	} else {
   2597   1.1     joerg 		val1 = fetch_data_byte(emu, emu->x86.R_SI);
   2598   1.1     joerg 		val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2599   1.1     joerg 		cmp_byte(emu, val1, val2);
   2600   1.1     joerg 		emu->x86.R_SI += inc;
   2601   1.1     joerg 		emu->x86.R_DI += inc;
   2602   1.1     joerg 	}
   2603   1.1     joerg }
   2604   1.1     joerg /****************************************************************************
   2605   1.1     joerg REMARKS:
   2606   1.1     joerg Handles opcode 0xa7
   2607   1.1     joerg ****************************************************************************/
   2608   1.1     joerg static void
   2609   1.1     joerg x86emuOp_cmps_word(struct X86EMU *emu)
   2610   1.1     joerg {
   2611   1.1     joerg 	uint32_t val1, val2;
   2612   1.1     joerg 	int inc;
   2613   1.1     joerg 
   2614   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2615   1.1     joerg 		if (ACCESS_FLAG(F_DF))	/* down */
   2616   1.1     joerg 			inc = -4;
   2617   1.1     joerg 		else
   2618   1.1     joerg 			inc = 4;
   2619   1.1     joerg 	} else {
   2620   1.1     joerg 		if (ACCESS_FLAG(F_DF))	/* down */
   2621   1.1     joerg 			inc = -2;
   2622   1.1     joerg 		else
   2623   1.1     joerg 			inc = 2;
   2624   1.1     joerg 	}
   2625   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
   2626   1.1     joerg 		/* REPE  */
   2627   1.1     joerg 		/* move them until CX is ZERO. */
   2628   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2629   1.1     joerg 			if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2630   1.1     joerg 				val1 = fetch_data_long(emu, emu->x86.R_SI);
   2631   1.1     joerg 				val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2632   1.1     joerg 				cmp_long(emu, val1, val2);
   2633   1.1     joerg 			} else {
   2634   1.1     joerg 				val1 = fetch_data_word(emu, emu->x86.R_SI);
   2635   1.1     joerg 				val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2636   1.1     joerg 				cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
   2637   1.1     joerg 			}
   2638   1.1     joerg 			emu->x86.R_CX -= 1;
   2639   1.1     joerg 			emu->x86.R_SI += inc;
   2640   1.1     joerg 			emu->x86.R_DI += inc;
   2641   1.1     joerg 			if (ACCESS_FLAG(F_ZF) == 0)
   2642   1.1     joerg 				break;
   2643   1.1     joerg 		}
   2644   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
   2645   1.1     joerg 	} else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
   2646   1.1     joerg 		/* REPNE  */
   2647   1.1     joerg 		/* move them until CX is ZERO. */
   2648   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2649   1.1     joerg 			if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2650   1.1     joerg 				val1 = fetch_data_long(emu, emu->x86.R_SI);
   2651   1.1     joerg 				val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2652   1.1     joerg 				cmp_long(emu, val1, val2);
   2653   1.1     joerg 			} else {
   2654   1.1     joerg 				val1 = fetch_data_word(emu, emu->x86.R_SI);
   2655   1.1     joerg 				val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2656   1.1     joerg 				cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
   2657   1.1     joerg 			}
   2658   1.1     joerg 			emu->x86.R_CX -= 1;
   2659   1.1     joerg 			emu->x86.R_SI += inc;
   2660   1.1     joerg 			emu->x86.R_DI += inc;
   2661   1.1     joerg 			if (ACCESS_FLAG(F_ZF))
   2662   1.1     joerg 				break;	/* zero flag set means equal */
   2663   1.1     joerg 		}
   2664   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
   2665   1.1     joerg 	} else {
   2666   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2667   1.1     joerg 			val1 = fetch_data_long(emu, emu->x86.R_SI);
   2668   1.1     joerg 			val2 = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2669   1.1     joerg 			cmp_long(emu, val1, val2);
   2670   1.1     joerg 		} else {
   2671   1.1     joerg 			val1 = fetch_data_word(emu, emu->x86.R_SI);
   2672   1.1     joerg 			val2 = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2673   1.1     joerg 			cmp_word(emu, (uint16_t) val1, (uint16_t) val2);
   2674   1.1     joerg 		}
   2675   1.1     joerg 		emu->x86.R_SI += inc;
   2676   1.1     joerg 		emu->x86.R_DI += inc;
   2677   1.1     joerg 	}
   2678   1.1     joerg }
   2679   1.1     joerg /****************************************************************************
   2680   1.1     joerg REMARKS:
   2681   1.1     joerg Handles opcode 0xa9
   2682   1.1     joerg ****************************************************************************/
   2683   1.1     joerg static void
   2684   1.1     joerg x86emuOp_test_AX_IMM(struct X86EMU *emu)
   2685   1.1     joerg {
   2686   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2687   1.1     joerg 		test_long(emu, emu->x86.R_EAX, fetch_long_imm(emu));
   2688   1.1     joerg 	} else {
   2689   1.1     joerg 		test_word(emu, emu->x86.R_AX, fetch_word_imm(emu));
   2690   1.1     joerg 	}
   2691   1.1     joerg }
   2692   1.1     joerg /****************************************************************************
   2693   1.1     joerg REMARKS:
   2694   1.1     joerg Handles opcode 0xaa
   2695   1.1     joerg ****************************************************************************/
   2696   1.1     joerg static void
   2697   1.1     joerg x86emuOp_stos_byte(struct X86EMU *emu)
   2698   1.1     joerg {
   2699   1.1     joerg 	int inc;
   2700   1.1     joerg 
   2701   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2702   1.1     joerg 		inc = -1;
   2703   1.1     joerg 	else
   2704   1.1     joerg 		inc = 1;
   2705   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2706   1.1     joerg 		/* dont care whether REPE or REPNE */
   2707   1.1     joerg 		/* move them until CX is ZERO. */
   2708   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2709   1.1     joerg 			store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
   2710   1.1     joerg 			emu->x86.R_CX -= 1;
   2711   1.1     joerg 			emu->x86.R_DI += inc;
   2712   1.1     joerg 		}
   2713   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2714   1.1     joerg 	} else {
   2715   1.1     joerg 		store_byte(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AL);
   2716   1.1     joerg 		emu->x86.R_DI += inc;
   2717   1.1     joerg 	}
   2718   1.1     joerg }
   2719   1.1     joerg /****************************************************************************
   2720   1.1     joerg REMARKS:
   2721   1.1     joerg Handles opcode 0xab
   2722   1.1     joerg ****************************************************************************/
   2723   1.1     joerg static void
   2724   1.1     joerg x86emuOp_stos_word(struct X86EMU *emu)
   2725   1.1     joerg {
   2726   1.1     joerg 	int inc;
   2727   1.1     joerg 	uint32_t count;
   2728   1.1     joerg 
   2729   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2730   1.1     joerg 		inc = 4;
   2731   1.1     joerg 	else
   2732   1.1     joerg 		inc = 2;
   2733   1.1     joerg 
   2734   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2735   1.1     joerg 		inc = -inc;
   2736   1.1     joerg 
   2737   1.1     joerg 	count = 1;
   2738   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2739   1.1     joerg 		/* dont care whether REPE or REPNE */
   2740   1.1     joerg 		/* move them until CX is ZERO. */
   2741   1.1     joerg 		count = emu->x86.R_CX;
   2742   1.1     joerg 		emu->x86.R_CX = 0;
   2743   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2744   1.1     joerg 	}
   2745   1.1     joerg 	while (count--) {
   2746   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2747   1.1     joerg 			store_long(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_EAX);
   2748   1.1     joerg 		} else {
   2749   1.1     joerg 			store_word(emu, emu->x86.R_ES, emu->x86.R_DI, emu->x86.R_AX);
   2750   1.1     joerg 		}
   2751   1.1     joerg 		emu->x86.R_DI += inc;
   2752   1.1     joerg 	}
   2753   1.1     joerg }
   2754   1.1     joerg /****************************************************************************
   2755   1.1     joerg REMARKS:
   2756   1.1     joerg Handles opcode 0xac
   2757   1.1     joerg ****************************************************************************/
   2758   1.1     joerg static void
   2759   1.1     joerg x86emuOp_lods_byte(struct X86EMU *emu)
   2760   1.1     joerg {
   2761   1.1     joerg 	int inc;
   2762   1.1     joerg 
   2763   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2764   1.1     joerg 		inc = -1;
   2765   1.1     joerg 	else
   2766   1.1     joerg 		inc = 1;
   2767   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2768   1.1     joerg 		/* dont care whether REPE or REPNE */
   2769   1.1     joerg 		/* move them until CX is ZERO. */
   2770   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2771   1.1     joerg 			emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
   2772   1.1     joerg 			emu->x86.R_CX -= 1;
   2773   1.1     joerg 			emu->x86.R_SI += inc;
   2774   1.1     joerg 		}
   2775   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2776   1.1     joerg 	} else {
   2777   1.1     joerg 		emu->x86.R_AL = fetch_data_byte(emu, emu->x86.R_SI);
   2778   1.1     joerg 		emu->x86.R_SI += inc;
   2779   1.1     joerg 	}
   2780   1.1     joerg }
   2781   1.1     joerg /****************************************************************************
   2782   1.1     joerg REMARKS:
   2783   1.1     joerg Handles opcode 0xad
   2784   1.1     joerg ****************************************************************************/
   2785   1.1     joerg static void
   2786   1.1     joerg x86emuOp_lods_word(struct X86EMU *emu)
   2787   1.1     joerg {
   2788   1.1     joerg 	int inc;
   2789   1.1     joerg 	uint32_t count;
   2790   1.1     joerg 
   2791   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2792   1.1     joerg 		inc = 4;
   2793   1.1     joerg 	else
   2794   1.1     joerg 		inc = 2;
   2795   1.1     joerg 
   2796   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2797   1.1     joerg 		inc = -inc;
   2798   1.1     joerg 
   2799   1.1     joerg 	count = 1;
   2800   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   2801   1.1     joerg 		/* dont care whether REPE or REPNE */
   2802   1.1     joerg 		/* move them until CX is ZERO. */
   2803   1.1     joerg 		count = emu->x86.R_CX;
   2804   1.1     joerg 		emu->x86.R_CX = 0;
   2805   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   2806   1.1     joerg 	}
   2807   1.1     joerg 	while (count--) {
   2808   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2809   1.1     joerg 			emu->x86.R_EAX = fetch_data_long(emu, emu->x86.R_SI);
   2810   1.1     joerg 		} else {
   2811   1.1     joerg 			emu->x86.R_AX = fetch_data_word(emu, emu->x86.R_SI);
   2812   1.1     joerg 		}
   2813   1.1     joerg 		emu->x86.R_SI += inc;
   2814   1.1     joerg 	}
   2815   1.1     joerg }
   2816   1.1     joerg /****************************************************************************
   2817   1.1     joerg REMARKS:
   2818   1.1     joerg Handles opcode 0xae
   2819   1.1     joerg ****************************************************************************/
   2820   1.1     joerg static void
   2821   1.1     joerg x86emuOp_scas_byte(struct X86EMU *emu)
   2822   1.1     joerg {
   2823   1.1     joerg 	int8_t val2;
   2824   1.1     joerg 	int inc;
   2825   1.1     joerg 
   2826   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2827   1.1     joerg 		inc = -1;
   2828   1.1     joerg 	else
   2829   1.1     joerg 		inc = 1;
   2830   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
   2831   1.1     joerg 		/* REPE  */
   2832   1.1     joerg 		/* move them until CX is ZERO. */
   2833   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2834   1.1     joerg 			val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2835   1.1     joerg 			cmp_byte(emu, emu->x86.R_AL, val2);
   2836   1.1     joerg 			emu->x86.R_CX -= 1;
   2837   1.1     joerg 			emu->x86.R_DI += inc;
   2838   1.1     joerg 			if (ACCESS_FLAG(F_ZF) == 0)
   2839   1.1     joerg 				break;
   2840   1.1     joerg 		}
   2841   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
   2842   1.1     joerg 	} else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
   2843   1.1     joerg 		/* REPNE  */
   2844   1.1     joerg 		/* move them until CX is ZERO. */
   2845   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2846   1.1     joerg 			val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2847   1.1     joerg 			cmp_byte(emu, emu->x86.R_AL, val2);
   2848   1.1     joerg 			emu->x86.R_CX -= 1;
   2849   1.1     joerg 			emu->x86.R_DI += inc;
   2850   1.1     joerg 			if (ACCESS_FLAG(F_ZF))
   2851   1.1     joerg 				break;	/* zero flag set means equal */
   2852   1.1     joerg 		}
   2853   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
   2854   1.1     joerg 	} else {
   2855   1.1     joerg 		val2 = fetch_byte(emu, emu->x86.R_ES, emu->x86.R_DI);
   2856   1.1     joerg 		cmp_byte(emu, emu->x86.R_AL, val2);
   2857   1.1     joerg 		emu->x86.R_DI += inc;
   2858   1.1     joerg 	}
   2859   1.1     joerg }
   2860   1.1     joerg /****************************************************************************
   2861   1.1     joerg REMARKS:
   2862   1.1     joerg Handles opcode 0xaf
   2863   1.1     joerg ****************************************************************************/
   2864   1.1     joerg static void
   2865   1.1     joerg x86emuOp_scas_word(struct X86EMU *emu)
   2866   1.1     joerg {
   2867   1.1     joerg 	int inc;
   2868   1.1     joerg 	uint32_t val;
   2869   1.1     joerg 
   2870   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2871   1.1     joerg 		inc = 4;
   2872   1.1     joerg 	else
   2873   1.1     joerg 		inc = 2;
   2874   1.1     joerg 
   2875   1.1     joerg 	if (ACCESS_FLAG(F_DF))	/* down */
   2876   1.1     joerg 		inc = -inc;
   2877   1.1     joerg 
   2878   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_REPE) {
   2879   1.1     joerg 		/* REPE  */
   2880   1.1     joerg 		/* move them until CX is ZERO. */
   2881   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2882   1.1     joerg 			if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2883   1.1     joerg 				val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2884   1.1     joerg 				cmp_long(emu, emu->x86.R_EAX, val);
   2885   1.1     joerg 			} else {
   2886   1.1     joerg 				val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2887   1.1     joerg 				cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
   2888   1.1     joerg 			}
   2889   1.1     joerg 			emu->x86.R_CX -= 1;
   2890   1.1     joerg 			emu->x86.R_DI += inc;
   2891   1.1     joerg 			if (ACCESS_FLAG(F_ZF) == 0)
   2892   1.1     joerg 				break;
   2893   1.1     joerg 		}
   2894   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPE;
   2895   1.1     joerg 	} else if (emu->x86.mode & SYSMODE_PREFIX_REPNE) {
   2896   1.1     joerg 		/* REPNE  */
   2897   1.1     joerg 		/* move them until CX is ZERO. */
   2898   1.1     joerg 		while (emu->x86.R_CX != 0) {
   2899   1.1     joerg 			if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2900   1.1     joerg 				val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2901   1.1     joerg 				cmp_long(emu, emu->x86.R_EAX, val);
   2902   1.1     joerg 			} else {
   2903   1.1     joerg 				val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2904   1.1     joerg 				cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
   2905   1.1     joerg 			}
   2906   1.1     joerg 			emu->x86.R_CX -= 1;
   2907   1.1     joerg 			emu->x86.R_DI += inc;
   2908   1.1     joerg 			if (ACCESS_FLAG(F_ZF))
   2909   1.1     joerg 				break;	/* zero flag set means equal */
   2910   1.1     joerg 		}
   2911   1.1     joerg 		emu->x86.mode &= ~SYSMODE_PREFIX_REPNE;
   2912   1.1     joerg 	} else {
   2913   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   2914   1.1     joerg 			val = fetch_long(emu, emu->x86.R_ES, emu->x86.R_DI);
   2915   1.1     joerg 			cmp_long(emu, emu->x86.R_EAX, val);
   2916   1.1     joerg 		} else {
   2917   1.1     joerg 			val = fetch_word(emu, emu->x86.R_ES, emu->x86.R_DI);
   2918   1.1     joerg 			cmp_word(emu, emu->x86.R_AX, (uint16_t) val);
   2919   1.1     joerg 		}
   2920   1.1     joerg 		emu->x86.R_DI += inc;
   2921   1.1     joerg 	}
   2922   1.1     joerg }
   2923   1.1     joerg /****************************************************************************
   2924   1.1     joerg REMARKS:
   2925   1.1     joerg Handles opcode 0xb8
   2926   1.1     joerg ****************************************************************************/
   2927   1.1     joerg static void
   2928   1.1     joerg x86emuOp_mov_word_AX_IMM(struct X86EMU *emu)
   2929   1.1     joerg {
   2930   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2931   1.1     joerg 		emu->x86.R_EAX = fetch_long_imm(emu);
   2932   1.1     joerg 	else
   2933   1.1     joerg 		emu->x86.R_AX = fetch_word_imm(emu);
   2934   1.1     joerg }
   2935   1.1     joerg /****************************************************************************
   2936   1.1     joerg REMARKS:
   2937   1.1     joerg Handles opcode 0xb9
   2938   1.1     joerg ****************************************************************************/
   2939   1.1     joerg static void
   2940   1.1     joerg x86emuOp_mov_word_CX_IMM(struct X86EMU *emu)
   2941   1.1     joerg {
   2942   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2943   1.1     joerg 		emu->x86.R_ECX = fetch_long_imm(emu);
   2944   1.1     joerg 	else
   2945   1.1     joerg 		emu->x86.R_CX = fetch_word_imm(emu);
   2946   1.1     joerg }
   2947   1.1     joerg /****************************************************************************
   2948   1.1     joerg REMARKS:
   2949   1.1     joerg Handles opcode 0xba
   2950   1.1     joerg ****************************************************************************/
   2951   1.1     joerg static void
   2952   1.1     joerg x86emuOp_mov_word_DX_IMM(struct X86EMU *emu)
   2953   1.1     joerg {
   2954   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2955   1.1     joerg 		emu->x86.R_EDX = fetch_long_imm(emu);
   2956   1.1     joerg 	else
   2957   1.1     joerg 		emu->x86.R_DX = fetch_word_imm(emu);
   2958   1.1     joerg }
   2959   1.1     joerg /****************************************************************************
   2960   1.1     joerg REMARKS:
   2961   1.1     joerg Handles opcode 0xbb
   2962   1.1     joerg ****************************************************************************/
   2963   1.1     joerg static void
   2964   1.1     joerg x86emuOp_mov_word_BX_IMM(struct X86EMU *emu)
   2965   1.1     joerg {
   2966   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2967   1.1     joerg 		emu->x86.R_EBX = fetch_long_imm(emu);
   2968   1.1     joerg 	else
   2969   1.1     joerg 		emu->x86.R_BX = fetch_word_imm(emu);
   2970   1.1     joerg }
   2971   1.1     joerg /****************************************************************************
   2972   1.1     joerg REMARKS:
   2973   1.1     joerg Handles opcode 0xbc
   2974   1.1     joerg ****************************************************************************/
   2975   1.1     joerg static void
   2976   1.1     joerg x86emuOp_mov_word_SP_IMM(struct X86EMU *emu)
   2977   1.1     joerg {
   2978   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2979   1.1     joerg 		emu->x86.R_ESP = fetch_long_imm(emu);
   2980   1.1     joerg 	else
   2981   1.1     joerg 		emu->x86.R_SP = fetch_word_imm(emu);
   2982   1.1     joerg }
   2983   1.1     joerg /****************************************************************************
   2984   1.1     joerg REMARKS:
   2985   1.1     joerg Handles opcode 0xbd
   2986   1.1     joerg ****************************************************************************/
   2987   1.1     joerg static void
   2988   1.1     joerg x86emuOp_mov_word_BP_IMM(struct X86EMU *emu)
   2989   1.1     joerg {
   2990   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   2991   1.1     joerg 		emu->x86.R_EBP = fetch_long_imm(emu);
   2992   1.1     joerg 	else
   2993   1.1     joerg 		emu->x86.R_BP = fetch_word_imm(emu);
   2994   1.1     joerg }
   2995   1.1     joerg /****************************************************************************
   2996   1.1     joerg REMARKS:
   2997   1.1     joerg Handles opcode 0xbe
   2998   1.1     joerg ****************************************************************************/
   2999   1.1     joerg static void
   3000   1.1     joerg x86emuOp_mov_word_SI_IMM(struct X86EMU *emu)
   3001   1.1     joerg {
   3002   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   3003   1.1     joerg 		emu->x86.R_ESI = fetch_long_imm(emu);
   3004   1.1     joerg 	else
   3005   1.1     joerg 		emu->x86.R_SI = fetch_word_imm(emu);
   3006   1.1     joerg }
   3007   1.1     joerg /****************************************************************************
   3008   1.1     joerg REMARKS:
   3009   1.1     joerg Handles opcode 0xbf
   3010   1.1     joerg ****************************************************************************/
   3011   1.1     joerg static void
   3012   1.1     joerg x86emuOp_mov_word_DI_IMM(struct X86EMU *emu)
   3013   1.1     joerg {
   3014   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   3015   1.1     joerg 		emu->x86.R_EDI = fetch_long_imm(emu);
   3016   1.1     joerg 	else
   3017   1.1     joerg 		emu->x86.R_DI = fetch_word_imm(emu);
   3018   1.1     joerg }
   3019   1.1     joerg /* used by opcodes c0, d0, and d2. */
   3020   1.1     joerg static
   3021   1.1     joerg uint8_t(* const opcD0_byte_operation[]) (struct X86EMU *, uint8_t d, uint8_t s) =
   3022   1.1     joerg {
   3023   1.1     joerg 	rol_byte,
   3024   1.1     joerg 	ror_byte,
   3025   1.1     joerg 	rcl_byte,
   3026   1.1     joerg 	rcr_byte,
   3027   1.1     joerg 	shl_byte,
   3028   1.1     joerg 	shr_byte,
   3029   1.1     joerg 	shl_byte,		/* sal_byte === shl_byte  by definition */
   3030   1.1     joerg 	sar_byte,
   3031   1.1     joerg };
   3032   1.1     joerg /****************************************************************************
   3033   1.1     joerg REMARKS:
   3034   1.1     joerg Handles opcode 0xc0
   3035   1.1     joerg ****************************************************************************/
   3036   1.1     joerg static void
   3037   1.1     joerg x86emuOp_opcC0_byte_RM_MEM(struct X86EMU *emu)
   3038   1.1     joerg {
   3039   1.1     joerg 	uint8_t destval, amt;
   3040   1.1     joerg 
   3041   1.1     joerg 	/*
   3042   1.1     joerg          * Yet another weirdo special case instruction format.  Part of
   3043   1.1     joerg          * the opcode held below in "RH".  Doubly nested case would
   3044   1.1     joerg          * result, except that the decoded instruction
   3045   1.1     joerg          */
   3046   1.1     joerg 	fetch_decode_modrm(emu);
   3047   1.1     joerg 	/* know operation, decode the mod byte to find the addressing mode. */
   3048   1.1     joerg 	destval = decode_and_fetch_byte_imm8(emu, &amt);
   3049   1.1     joerg 	destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, amt);
   3050   1.1     joerg 	write_back_byte(emu, destval);
   3051   1.1     joerg }
   3052   1.1     joerg /* used by opcodes c1, d1, and d3. */
   3053   1.1     joerg static
   3054   1.1     joerg uint16_t(* const opcD1_word_operation[]) (struct X86EMU *, uint16_t s, uint8_t d) =
   3055   1.1     joerg {
   3056   1.1     joerg 	rol_word,
   3057   1.1     joerg 	ror_word,
   3058   1.1     joerg 	rcl_word,
   3059   1.1     joerg 	rcr_word,
   3060   1.1     joerg 	shl_word,
   3061   1.1     joerg 	shr_word,
   3062   1.1     joerg 	shl_word,		/* sal_byte === shl_byte  by definition */
   3063   1.1     joerg 	sar_word,
   3064   1.1     joerg };
   3065   1.1     joerg /* used by opcodes c1, d1, and d3. */
   3066   1.1     joerg static
   3067   1.1     joerg uint32_t(* const opcD1_long_operation[]) (struct X86EMU *, uint32_t s, uint8_t d) =
   3068   1.1     joerg {
   3069   1.1     joerg 	rol_long,
   3070   1.1     joerg 	ror_long,
   3071   1.1     joerg 	rcl_long,
   3072   1.1     joerg 	rcr_long,
   3073   1.1     joerg 	shl_long,
   3074   1.1     joerg 	shr_long,
   3075   1.1     joerg 	shl_long,		/* sal_byte === shl_byte  by definition */
   3076   1.1     joerg 	sar_long,
   3077   1.1     joerg };
   3078   1.1     joerg /****************************************************************************
   3079   1.1     joerg REMARKS:
   3080   1.1     joerg Handles opcode 0xc1
   3081   1.1     joerg ****************************************************************************/
   3082   1.1     joerg static void
   3083   1.1     joerg x86emuOp_opcC1_word_RM_MEM(struct X86EMU *emu)
   3084   1.1     joerg {
   3085   1.1     joerg 	uint8_t amt;
   3086   1.1     joerg 
   3087   1.1     joerg 	/*
   3088   1.1     joerg          * Yet another weirdo special case instruction format.  Part of
   3089   1.1     joerg          * the opcode held below in "RH".  Doubly nested case would
   3090   1.1     joerg          * result, except that the decoded instruction
   3091   1.1     joerg          */
   3092   1.1     joerg 	fetch_decode_modrm(emu);
   3093   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3094   1.1     joerg 		uint32_t destval;
   3095   1.1     joerg 
   3096   1.1     joerg 		destval = decode_and_fetch_long_imm8(emu, &amt);
   3097   1.1     joerg 		destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, amt);
   3098   1.1     joerg 		write_back_long(emu, destval);
   3099   1.1     joerg 	} else {
   3100   1.1     joerg 		uint16_t destval;
   3101   1.1     joerg 
   3102   1.1     joerg 		destval = decode_and_fetch_word_imm8(emu, &amt);
   3103   1.1     joerg 		destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, amt);
   3104   1.1     joerg 		write_back_word(emu, destval);
   3105   1.1     joerg 	}
   3106   1.1     joerg }
   3107   1.1     joerg /****************************************************************************
   3108   1.1     joerg REMARKS:
   3109   1.1     joerg Handles opcode 0xc2
   3110   1.1     joerg ****************************************************************************/
   3111   1.1     joerg static void
   3112   1.1     joerg x86emuOp_ret_near_IMM(struct X86EMU *emu)
   3113   1.1     joerg {
   3114   1.1     joerg 	uint16_t imm;
   3115   1.1     joerg 
   3116   1.1     joerg 	imm = fetch_word_imm(emu);
   3117   1.1     joerg 	emu->x86.R_IP = pop_word(emu);
   3118   1.1     joerg 	emu->x86.R_SP += imm;
   3119   1.1     joerg }
   3120   1.1     joerg /****************************************************************************
   3121   1.1     joerg REMARKS:
   3122   1.1     joerg Handles opcode 0xc6
   3123   1.1     joerg ****************************************************************************/
   3124   1.1     joerg static void
   3125   1.1     joerg x86emuOp_mov_byte_RM_IMM(struct X86EMU *emu)
   3126   1.1     joerg {
   3127   1.1     joerg 	uint8_t *destreg;
   3128   1.1     joerg 	uint32_t destoffset;
   3129   1.1     joerg 	uint8_t imm;
   3130   1.1     joerg 
   3131   1.1     joerg 	fetch_decode_modrm(emu);
   3132   1.1     joerg 	if (emu->cur_rh != 0)
   3133   1.1     joerg 		X86EMU_halt_sys(emu);
   3134   1.1     joerg 	if (emu->cur_mod != 3) {
   3135   1.1     joerg 		destoffset = decode_rl_address(emu);
   3136   1.1     joerg 		imm = fetch_byte_imm(emu);
   3137   1.1     joerg 		store_data_byte(emu, destoffset, imm);
   3138   1.1     joerg 	} else {
   3139   1.1     joerg 		destreg = decode_rl_byte_register(emu);
   3140   1.1     joerg 		imm = fetch_byte_imm(emu);
   3141   1.1     joerg 		*destreg = imm;
   3142   1.1     joerg 	}
   3143   1.1     joerg }
   3144   1.1     joerg /****************************************************************************
   3145   1.1     joerg REMARKS:
   3146   1.1     joerg Handles opcode 0xc7
   3147   1.1     joerg ****************************************************************************/
   3148   1.1     joerg static void
   3149   1.1     joerg x86emuOp32_mov_word_RM_IMM(struct X86EMU *emu)
   3150   1.1     joerg {
   3151   1.1     joerg 	uint32_t destoffset;
   3152   1.1     joerg 	uint32_t imm, *destreg;
   3153   1.1     joerg 
   3154   1.1     joerg 	fetch_decode_modrm(emu);
   3155   1.1     joerg 	if (emu->cur_rh != 0)
   3156   1.1     joerg 		X86EMU_halt_sys(emu);
   3157   1.1     joerg 
   3158   1.1     joerg 	if (emu->cur_mod != 3) {
   3159   1.1     joerg 		destoffset = decode_rl_address(emu);
   3160   1.1     joerg 		imm = fetch_long_imm(emu);
   3161   1.1     joerg 		store_data_long(emu, destoffset, imm);
   3162   1.1     joerg 	} else {
   3163   1.1     joerg 		destreg = decode_rl_long_register(emu);
   3164   1.1     joerg 		imm = fetch_long_imm(emu);
   3165   1.1     joerg 		*destreg = imm;
   3166   1.1     joerg 	}
   3167   1.1     joerg }
   3168   1.1     joerg 
   3169   1.1     joerg static void
   3170   1.1     joerg x86emuOp16_mov_word_RM_IMM(struct X86EMU *emu)
   3171   1.1     joerg {
   3172   1.1     joerg 	uint32_t destoffset;
   3173   1.1     joerg 	uint16_t imm, *destreg;
   3174   1.1     joerg 
   3175   1.1     joerg 	fetch_decode_modrm(emu);
   3176   1.1     joerg 	if (emu->cur_rh != 0)
   3177   1.1     joerg 		X86EMU_halt_sys(emu);
   3178   1.1     joerg 
   3179   1.1     joerg 	if (emu->cur_mod != 3) {
   3180   1.1     joerg 		destoffset = decode_rl_address(emu);
   3181   1.1     joerg 		imm = fetch_word_imm(emu);
   3182   1.1     joerg 		store_data_word(emu, destoffset, imm);
   3183   1.1     joerg 	} else {
   3184   1.1     joerg 		destreg = decode_rl_word_register(emu);
   3185   1.1     joerg 		imm = fetch_word_imm(emu);
   3186   1.1     joerg 		*destreg = imm;
   3187   1.1     joerg 	}
   3188   1.1     joerg }
   3189   1.1     joerg 
   3190   1.1     joerg static void
   3191   1.1     joerg x86emuOp_mov_word_RM_IMM(struct X86EMU *emu)
   3192   1.1     joerg {
   3193   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   3194   1.1     joerg 		x86emuOp32_mov_word_RM_IMM(emu);
   3195   1.1     joerg 	else
   3196   1.1     joerg 		x86emuOp16_mov_word_RM_IMM(emu);
   3197   1.1     joerg }
   3198   1.1     joerg /****************************************************************************
   3199   1.1     joerg REMARKS:
   3200   1.1     joerg Handles opcode 0xc8
   3201   1.1     joerg ****************************************************************************/
   3202   1.1     joerg static void
   3203   1.1     joerg x86emuOp_enter(struct X86EMU *emu)
   3204   1.1     joerg {
   3205   1.1     joerg 	uint16_t local, frame_pointer;
   3206   1.1     joerg 	uint8_t nesting;
   3207   1.1     joerg 	int i;
   3208   1.1     joerg 
   3209   1.1     joerg 	local = fetch_word_imm(emu);
   3210   1.1     joerg 	nesting = fetch_byte_imm(emu);
   3211   1.1     joerg 	push_word(emu, emu->x86.R_BP);
   3212   1.1     joerg 	frame_pointer = emu->x86.R_SP;
   3213   1.1     joerg 	if (nesting > 0) {
   3214   1.1     joerg 		for (i = 1; i < nesting; i++) {
   3215   1.1     joerg 			emu->x86.R_BP -= 2;
   3216   1.1     joerg 			push_word(emu, fetch_word(emu, emu->x86.R_SS, emu->x86.R_BP));
   3217   1.1     joerg 		}
   3218   1.1     joerg 		push_word(emu, frame_pointer);
   3219   1.1     joerg 	}
   3220   1.1     joerg 	emu->x86.R_BP = frame_pointer;
   3221   1.1     joerg 	emu->x86.R_SP = (uint16_t) (emu->x86.R_SP - local);
   3222   1.1     joerg }
   3223   1.1     joerg /****************************************************************************
   3224   1.1     joerg REMARKS:
   3225   1.1     joerg Handles opcode 0xc9
   3226   1.1     joerg ****************************************************************************/
   3227   1.1     joerg static void
   3228   1.1     joerg x86emuOp_leave(struct X86EMU *emu)
   3229   1.1     joerg {
   3230   1.1     joerg 	emu->x86.R_SP = emu->x86.R_BP;
   3231   1.1     joerg 	emu->x86.R_BP = pop_word(emu);
   3232   1.1     joerg }
   3233   1.1     joerg /****************************************************************************
   3234   1.1     joerg REMARKS:
   3235   1.1     joerg Handles opcode 0xca
   3236   1.1     joerg ****************************************************************************/
   3237   1.1     joerg static void
   3238   1.1     joerg x86emuOp_ret_far_IMM(struct X86EMU *emu)
   3239   1.1     joerg {
   3240   1.1     joerg 	uint16_t imm;
   3241   1.1     joerg 
   3242   1.1     joerg 	imm = fetch_word_imm(emu);
   3243   1.1     joerg 	emu->x86.R_IP = pop_word(emu);
   3244   1.1     joerg 	emu->x86.R_CS = pop_word(emu);
   3245   1.1     joerg 	emu->x86.R_SP += imm;
   3246   1.1     joerg }
   3247   1.1     joerg /****************************************************************************
   3248   1.1     joerg REMARKS:
   3249   1.1     joerg Handles opcode 0xcb
   3250   1.1     joerg ****************************************************************************/
   3251   1.1     joerg static void
   3252   1.1     joerg x86emuOp_ret_far(struct X86EMU *emu)
   3253   1.1     joerg {
   3254   1.1     joerg 	emu->x86.R_IP = pop_word(emu);
   3255   1.1     joerg 	emu->x86.R_CS = pop_word(emu);
   3256   1.1     joerg }
   3257   1.1     joerg /****************************************************************************
   3258   1.1     joerg REMARKS:
   3259   1.1     joerg Handles opcode 0xcc
   3260   1.1     joerg ****************************************************************************/
   3261   1.1     joerg static void
   3262   1.1     joerg x86emuOp_int3(struct X86EMU *emu)
   3263   1.1     joerg {
   3264   1.3     joerg 	x86emu_intr_dispatch(emu, 3);
   3265   1.1     joerg }
   3266   1.1     joerg /****************************************************************************
   3267   1.1     joerg REMARKS:
   3268   1.1     joerg Handles opcode 0xcd
   3269   1.1     joerg ****************************************************************************/
   3270   1.1     joerg static void
   3271   1.1     joerg x86emuOp_int_IMM(struct X86EMU *emu)
   3272   1.1     joerg {
   3273   1.1     joerg 	uint8_t intnum;
   3274   1.1     joerg 
   3275   1.1     joerg 	intnum = fetch_byte_imm(emu);
   3276   1.3     joerg 	x86emu_intr_dispatch(emu, intnum);
   3277   1.1     joerg }
   3278   1.1     joerg /****************************************************************************
   3279   1.1     joerg REMARKS:
   3280   1.1     joerg Handles opcode 0xce
   3281   1.1     joerg ****************************************************************************/
   3282   1.1     joerg static void
   3283   1.1     joerg x86emuOp_into(struct X86EMU *emu)
   3284   1.1     joerg {
   3285   1.3     joerg 	if (ACCESS_FLAG(F_OF))
   3286   1.3     joerg 		x86emu_intr_dispatch(emu, 4);
   3287   1.1     joerg }
   3288   1.1     joerg /****************************************************************************
   3289   1.1     joerg REMARKS:
   3290   1.1     joerg Handles opcode 0xcf
   3291   1.1     joerg ****************************************************************************/
   3292   1.1     joerg static void
   3293   1.1     joerg x86emuOp_iret(struct X86EMU *emu)
   3294   1.1     joerg {
   3295   1.1     joerg 	emu->x86.R_IP = pop_word(emu);
   3296   1.1     joerg 	emu->x86.R_CS = pop_word(emu);
   3297   1.1     joerg 	emu->x86.R_FLG = pop_word(emu);
   3298   1.1     joerg }
   3299   1.1     joerg /****************************************************************************
   3300   1.1     joerg REMARKS:
   3301   1.1     joerg Handles opcode 0xd0
   3302   1.1     joerg ****************************************************************************/
   3303   1.1     joerg static void
   3304   1.1     joerg x86emuOp_opcD0_byte_RM_1(struct X86EMU *emu)
   3305   1.1     joerg {
   3306   1.1     joerg 	uint8_t destval;
   3307   1.1     joerg 
   3308   1.1     joerg 	fetch_decode_modrm(emu);
   3309   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   3310   1.1     joerg 	destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, 1);
   3311   1.1     joerg 	write_back_byte(emu, destval);
   3312   1.1     joerg }
   3313   1.1     joerg /****************************************************************************
   3314   1.1     joerg REMARKS:
   3315   1.1     joerg Handles opcode 0xd1
   3316   1.1     joerg ****************************************************************************/
   3317   1.1     joerg static void
   3318   1.1     joerg x86emuOp_opcD1_word_RM_1(struct X86EMU *emu)
   3319   1.1     joerg {
   3320   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3321   1.1     joerg 		uint32_t destval;
   3322   1.1     joerg 
   3323   1.1     joerg 		fetch_decode_modrm(emu);
   3324   1.1     joerg 		destval = decode_and_fetch_long(emu);
   3325   1.1     joerg 		destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, 1);
   3326   1.1     joerg 		write_back_long(emu, destval);
   3327   1.1     joerg 	} else {
   3328   1.1     joerg 		uint16_t destval;
   3329   1.1     joerg 
   3330   1.1     joerg 		fetch_decode_modrm(emu);
   3331   1.1     joerg 		destval = decode_and_fetch_word(emu);
   3332   1.1     joerg 		destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, 1);
   3333   1.1     joerg 		write_back_word(emu, destval);
   3334   1.1     joerg 	}
   3335   1.1     joerg }
   3336   1.1     joerg /****************************************************************************
   3337   1.1     joerg REMARKS:
   3338   1.1     joerg Handles opcode 0xd2
   3339   1.1     joerg ****************************************************************************/
   3340   1.1     joerg static void
   3341   1.1     joerg x86emuOp_opcD2_byte_RM_CL(struct X86EMU *emu)
   3342   1.1     joerg {
   3343   1.1     joerg 	uint8_t destval;
   3344   1.1     joerg 
   3345   1.1     joerg 	fetch_decode_modrm(emu);
   3346   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   3347   1.1     joerg 	destval = (*opcD0_byte_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
   3348   1.1     joerg 	write_back_byte(emu, destval);
   3349   1.1     joerg }
   3350   1.1     joerg /****************************************************************************
   3351   1.1     joerg REMARKS:
   3352   1.1     joerg Handles opcode 0xd3
   3353   1.1     joerg ****************************************************************************/
   3354   1.1     joerg static void
   3355   1.1     joerg x86emuOp_opcD3_word_RM_CL(struct X86EMU *emu)
   3356   1.1     joerg {
   3357   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3358   1.1     joerg 		uint32_t destval;
   3359   1.1     joerg 
   3360   1.1     joerg 		fetch_decode_modrm(emu);
   3361   1.1     joerg 		destval = decode_and_fetch_long(emu);
   3362   1.1     joerg 		destval = (*opcD1_long_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
   3363   1.1     joerg 		write_back_long(emu, destval);
   3364   1.1     joerg 	} else {
   3365   1.1     joerg 		uint16_t destval;
   3366   1.1     joerg 
   3367   1.1     joerg 		fetch_decode_modrm(emu);
   3368   1.1     joerg 		destval = decode_and_fetch_word(emu);
   3369   1.1     joerg 		destval = (*opcD1_word_operation[emu->cur_rh]) (emu, destval, emu->x86.R_CL);
   3370   1.1     joerg 		write_back_word(emu, destval);
   3371   1.1     joerg 	}
   3372   1.1     joerg }
   3373   1.1     joerg /****************************************************************************
   3374   1.1     joerg REMARKS:
   3375   1.1     joerg Handles opcode 0xd4
   3376   1.1     joerg ****************************************************************************/
   3377   1.1     joerg static void
   3378   1.1     joerg x86emuOp_aam(struct X86EMU *emu)
   3379   1.1     joerg {
   3380   1.1     joerg 	uint8_t a;
   3381   1.1     joerg 
   3382   1.1     joerg 	a = fetch_byte_imm(emu);	/* this is a stupid encoding. */
   3383   1.1     joerg 	if (a != 10) {
   3384   1.1     joerg 		/* fix: add base decoding aam_word(uint8_t val, int base a) */
   3385   1.1     joerg 		X86EMU_halt_sys(emu);
   3386   1.1     joerg 	}
   3387   1.1     joerg 	/* note the type change here --- returning AL and AH in AX. */
   3388   1.1     joerg 	emu->x86.R_AX = aam_word(emu, emu->x86.R_AL);
   3389   1.1     joerg }
   3390   1.1     joerg /****************************************************************************
   3391   1.1     joerg REMARKS:
   3392   1.1     joerg Handles opcode 0xd5
   3393   1.1     joerg ****************************************************************************/
   3394   1.1     joerg static void
   3395   1.1     joerg x86emuOp_aad(struct X86EMU *emu)
   3396   1.1     joerg {
   3397   1.1     joerg 	uint8_t a;
   3398   1.1     joerg 
   3399   1.1     joerg 	a = fetch_byte_imm(emu);
   3400   1.1     joerg 	if (a != 10) {
   3401   1.1     joerg 		/* fix: add base decoding aad_word(uint16_t val, int base a) */
   3402   1.1     joerg 		X86EMU_halt_sys(emu);
   3403   1.1     joerg 	}
   3404   1.1     joerg 	emu->x86.R_AX = aad_word(emu, emu->x86.R_AX);
   3405   1.1     joerg }
   3406   1.1     joerg /* opcode 0xd6 ILLEGAL OPCODE */
   3407   1.1     joerg 
   3408   1.1     joerg /****************************************************************************
   3409   1.1     joerg REMARKS:
   3410   1.1     joerg Handles opcode 0xd7
   3411   1.1     joerg ****************************************************************************/
   3412   1.1     joerg static void
   3413   1.1     joerg x86emuOp_xlat(struct X86EMU *emu)
   3414   1.1     joerg {
   3415   1.1     joerg 	uint16_t addr;
   3416   1.1     joerg 
   3417   1.1     joerg 	addr = (uint16_t) (emu->x86.R_BX + (uint8_t) emu->x86.R_AL);
   3418   1.1     joerg 	emu->x86.R_AL = fetch_data_byte(emu, addr);
   3419   1.1     joerg }
   3420   1.1     joerg 
   3421   1.1     joerg /* opcode=0xd8 */
   3422   1.1     joerg static void
   3423   1.1     joerg x86emuOp_esc_coprocess_d8(struct X86EMU *emu)
   3424   1.1     joerg {
   3425   1.1     joerg }
   3426   1.1     joerg /* opcode=0xd9 */
   3427   1.1     joerg static void
   3428   1.1     joerg x86emuOp_esc_coprocess_d9(struct X86EMU *emu)
   3429   1.1     joerg {
   3430   1.1     joerg 	fetch_decode_modrm(emu);
   3431   1.1     joerg 	if (emu->cur_mod != 3)
   3432   1.1     joerg 		decode_rl_address(emu);
   3433   1.1     joerg }
   3434   1.1     joerg /* opcode=0xda */
   3435   1.1     joerg static void
   3436   1.1     joerg x86emuOp_esc_coprocess_da(struct X86EMU *emu)
   3437   1.1     joerg {
   3438   1.1     joerg 	fetch_decode_modrm(emu);
   3439   1.1     joerg 	if (emu->cur_mod != 3)
   3440   1.1     joerg 		decode_rl_address(emu);
   3441   1.1     joerg }
   3442   1.1     joerg /* opcode=0xdb */
   3443   1.1     joerg static void
   3444   1.1     joerg x86emuOp_esc_coprocess_db(struct X86EMU *emu)
   3445   1.1     joerg {
   3446   1.1     joerg 	fetch_decode_modrm(emu);
   3447   1.1     joerg 	if (emu->cur_mod != 3)
   3448   1.1     joerg 		decode_rl_address(emu);
   3449   1.1     joerg }
   3450   1.1     joerg /* opcode=0xdc */
   3451   1.1     joerg static void
   3452   1.1     joerg x86emuOp_esc_coprocess_dc(struct X86EMU *emu)
   3453   1.1     joerg {
   3454   1.1     joerg 	fetch_decode_modrm(emu);
   3455   1.1     joerg 	if (emu->cur_mod != 3)
   3456   1.1     joerg 		decode_rl_address(emu);
   3457   1.1     joerg }
   3458   1.1     joerg /* opcode=0xdd */
   3459   1.1     joerg static void
   3460   1.1     joerg x86emuOp_esc_coprocess_dd(struct X86EMU *emu)
   3461   1.1     joerg {
   3462   1.1     joerg 	fetch_decode_modrm(emu);
   3463   1.1     joerg 	if (emu->cur_mod != 3)
   3464   1.1     joerg 		decode_rl_address(emu);
   3465   1.1     joerg }
   3466   1.1     joerg /* opcode=0xde */
   3467   1.1     joerg static void
   3468   1.1     joerg x86emuOp_esc_coprocess_de(struct X86EMU *emu)
   3469   1.1     joerg {
   3470   1.1     joerg 	fetch_decode_modrm(emu);
   3471   1.1     joerg 	if (emu->cur_mod != 3)
   3472   1.1     joerg 		decode_rl_address(emu);
   3473   1.1     joerg }
   3474   1.1     joerg /* opcode=0xdf */
   3475   1.1     joerg static void
   3476   1.1     joerg x86emuOp_esc_coprocess_df(struct X86EMU *emu)
   3477   1.1     joerg {
   3478   1.1     joerg 	fetch_decode_modrm(emu);
   3479   1.1     joerg 	if (emu->cur_mod != 3)
   3480   1.1     joerg 		decode_rl_address(emu);
   3481   1.1     joerg }
   3482   1.1     joerg 
   3483   1.1     joerg /****************************************************************************
   3484   1.1     joerg REMARKS:
   3485   1.1     joerg Handles opcode 0xe0
   3486   1.1     joerg ****************************************************************************/
   3487   1.1     joerg static void
   3488   1.1     joerg x86emuOp_loopne(struct X86EMU *emu)
   3489   1.1     joerg {
   3490   1.1     joerg 	int16_t ip;
   3491   1.1     joerg 
   3492   1.1     joerg 	ip = (int8_t) fetch_byte_imm(emu);
   3493   1.1     joerg 	ip += (int16_t) emu->x86.R_IP;
   3494   1.1     joerg 	emu->x86.R_CX -= 1;
   3495   1.1     joerg 	if (emu->x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))	/* CX != 0 and !ZF */
   3496   1.1     joerg 		emu->x86.R_IP = ip;
   3497   1.1     joerg }
   3498   1.1     joerg /****************************************************************************
   3499   1.1     joerg REMARKS:
   3500   1.1     joerg Handles opcode 0xe1
   3501   1.1     joerg ****************************************************************************/
   3502   1.1     joerg static void
   3503   1.1     joerg x86emuOp_loope(struct X86EMU *emu)
   3504   1.1     joerg {
   3505   1.1     joerg 	int16_t ip;
   3506   1.1     joerg 
   3507   1.1     joerg 	ip = (int8_t) fetch_byte_imm(emu);
   3508   1.1     joerg 	ip += (int16_t) emu->x86.R_IP;
   3509   1.1     joerg 	emu->x86.R_CX -= 1;
   3510   1.1     joerg 	if (emu->x86.R_CX != 0 && ACCESS_FLAG(F_ZF))	/* CX != 0 and ZF */
   3511   1.1     joerg 		emu->x86.R_IP = ip;
   3512   1.1     joerg }
   3513   1.1     joerg /****************************************************************************
   3514   1.1     joerg REMARKS:
   3515   1.1     joerg Handles opcode 0xe2
   3516   1.1     joerg ****************************************************************************/
   3517   1.1     joerg static void
   3518   1.1     joerg x86emuOp_loop(struct X86EMU *emu)
   3519   1.1     joerg {
   3520   1.1     joerg 	int16_t ip;
   3521   1.1     joerg 
   3522   1.1     joerg 	ip = (int8_t) fetch_byte_imm(emu);
   3523   1.1     joerg 	ip += (int16_t) emu->x86.R_IP;
   3524   1.1     joerg 	emu->x86.R_CX -= 1;
   3525   1.1     joerg 	if (emu->x86.R_CX != 0)
   3526   1.1     joerg 		emu->x86.R_IP = ip;
   3527   1.1     joerg }
   3528   1.1     joerg /****************************************************************************
   3529   1.1     joerg REMARKS:
   3530   1.1     joerg Handles opcode 0xe3
   3531   1.1     joerg ****************************************************************************/
   3532   1.1     joerg static void
   3533   1.1     joerg x86emuOp_jcxz(struct X86EMU *emu)
   3534   1.1     joerg {
   3535   1.1     joerg 	uint16_t target;
   3536   1.1     joerg 	int8_t offset;
   3537   1.1     joerg 
   3538   1.1     joerg 	/* jump to byte offset if overflow flag is set */
   3539   1.1     joerg 	offset = (int8_t) fetch_byte_imm(emu);
   3540   1.1     joerg 	target = (uint16_t) (emu->x86.R_IP + offset);
   3541   1.1     joerg 	if (emu->x86.R_CX == 0)
   3542   1.1     joerg 		emu->x86.R_IP = target;
   3543   1.1     joerg }
   3544   1.1     joerg /****************************************************************************
   3545   1.1     joerg REMARKS:
   3546   1.1     joerg Handles opcode 0xe4
   3547   1.1     joerg ****************************************************************************/
   3548   1.1     joerg static void
   3549   1.1     joerg x86emuOp_in_byte_AL_IMM(struct X86EMU *emu)
   3550   1.1     joerg {
   3551   1.1     joerg 	uint8_t port;
   3552   1.1     joerg 
   3553   1.1     joerg 	port = (uint8_t) fetch_byte_imm(emu);
   3554   1.1     joerg 	emu->x86.R_AL = (*emu->emu_inb) (emu, port);
   3555   1.1     joerg }
   3556   1.1     joerg /****************************************************************************
   3557   1.1     joerg REMARKS:
   3558   1.1     joerg Handles opcode 0xe5
   3559   1.1     joerg ****************************************************************************/
   3560   1.1     joerg static void
   3561   1.1     joerg x86emuOp_in_word_AX_IMM(struct X86EMU *emu)
   3562   1.1     joerg {
   3563   1.1     joerg 	uint8_t port;
   3564   1.1     joerg 
   3565   1.1     joerg 	port = (uint8_t) fetch_byte_imm(emu);
   3566   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3567   1.1     joerg 		emu->x86.R_EAX = (*emu->emu_inl) (emu, port);
   3568   1.1     joerg 	} else {
   3569   1.1     joerg 		emu->x86.R_AX = (*emu->emu_inw) (emu, port);
   3570   1.1     joerg 	}
   3571   1.1     joerg }
   3572   1.1     joerg /****************************************************************************
   3573   1.1     joerg REMARKS:
   3574   1.1     joerg Handles opcode 0xe6
   3575   1.1     joerg ****************************************************************************/
   3576   1.1     joerg static void
   3577   1.1     joerg x86emuOp_out_byte_IMM_AL(struct X86EMU *emu)
   3578   1.1     joerg {
   3579   1.1     joerg 	uint8_t port;
   3580   1.1     joerg 
   3581   1.1     joerg 	port = (uint8_t) fetch_byte_imm(emu);
   3582   1.1     joerg 	(*emu->emu_outb) (emu, port, emu->x86.R_AL);
   3583   1.1     joerg }
   3584   1.1     joerg /****************************************************************************
   3585   1.1     joerg REMARKS:
   3586   1.1     joerg Handles opcode 0xe7
   3587   1.1     joerg ****************************************************************************/
   3588   1.1     joerg static void
   3589   1.1     joerg x86emuOp_out_word_IMM_AX(struct X86EMU *emu)
   3590   1.1     joerg {
   3591   1.1     joerg 	uint8_t port;
   3592   1.1     joerg 
   3593   1.1     joerg 	port = (uint8_t) fetch_byte_imm(emu);
   3594   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3595   1.1     joerg 		(*emu->emu_outl) (emu, port, emu->x86.R_EAX);
   3596   1.1     joerg 	} else {
   3597   1.1     joerg 		(*emu->emu_outw) (emu, port, emu->x86.R_AX);
   3598   1.1     joerg 	}
   3599   1.1     joerg }
   3600   1.1     joerg /****************************************************************************
   3601   1.1     joerg REMARKS:
   3602   1.1     joerg Handles opcode 0xe8
   3603   1.1     joerg ****************************************************************************/
   3604   1.1     joerg static void
   3605   1.1     joerg x86emuOp_call_near_IMM(struct X86EMU *emu)
   3606   1.1     joerg {
   3607  1.10     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3608  1.10     joerg 		int32_t ip;
   3609  1.10     joerg 		ip = (int32_t) fetch_long_imm(emu);
   3610  1.10     joerg 		ip += (int32_t) emu->x86.R_EIP;
   3611  1.10     joerg 		push_long(emu, emu->x86.R_EIP);
   3612  1.10     joerg 		emu->x86.R_EIP = ip;
   3613  1.10     joerg 	} else {
   3614  1.10     joerg 		int16_t ip;
   3615  1.10     joerg 		ip = (int16_t) fetch_word_imm(emu);
   3616  1.10     joerg 		ip += (int16_t) emu->x86.R_IP;	/* CHECK SIGN */
   3617  1.10     joerg 		push_word(emu, emu->x86.R_IP);
   3618  1.10     joerg 		emu->x86.R_IP = ip;
   3619  1.10     joerg 	}
   3620   1.1     joerg }
   3621   1.1     joerg /****************************************************************************
   3622   1.1     joerg REMARKS:
   3623   1.1     joerg Handles opcode 0xe9
   3624   1.1     joerg ****************************************************************************/
   3625   1.1     joerg static void
   3626   1.1     joerg x86emuOp_jump_near_IMM(struct X86EMU *emu)
   3627   1.1     joerg {
   3628   1.1     joerg 	int ip;
   3629   1.1     joerg 
   3630   1.1     joerg 	ip = (int16_t) fetch_word_imm(emu);
   3631   1.1     joerg 	ip += (int16_t) emu->x86.R_IP;
   3632   1.1     joerg 	emu->x86.R_IP = (uint16_t) ip;
   3633   1.1     joerg }
   3634   1.1     joerg /****************************************************************************
   3635   1.1     joerg REMARKS:
   3636   1.1     joerg Handles opcode 0xea
   3637   1.1     joerg ****************************************************************************/
   3638   1.1     joerg static void
   3639   1.1     joerg x86emuOp_jump_far_IMM(struct X86EMU *emu)
   3640   1.1     joerg {
   3641   1.1     joerg 	uint16_t cs, ip;
   3642   1.1     joerg 
   3643   1.1     joerg 	ip = fetch_word_imm(emu);
   3644   1.1     joerg 	cs = fetch_word_imm(emu);
   3645   1.1     joerg 	emu->x86.R_IP = ip;
   3646   1.1     joerg 	emu->x86.R_CS = cs;
   3647   1.1     joerg }
   3648   1.1     joerg /****************************************************************************
   3649   1.1     joerg REMARKS:
   3650   1.1     joerg Handles opcode 0xeb
   3651   1.1     joerg ****************************************************************************/
   3652   1.1     joerg static void
   3653   1.1     joerg x86emuOp_jump_byte_IMM(struct X86EMU *emu)
   3654   1.1     joerg {
   3655   1.1     joerg 	uint16_t target;
   3656   1.1     joerg 	int8_t offset;
   3657   1.1     joerg 
   3658   1.1     joerg 	offset = (int8_t) fetch_byte_imm(emu);
   3659   1.1     joerg 	target = (uint16_t) (emu->x86.R_IP + offset);
   3660   1.1     joerg 	emu->x86.R_IP = target;
   3661   1.1     joerg }
   3662   1.1     joerg /****************************************************************************
   3663   1.1     joerg REMARKS:
   3664   1.1     joerg Handles opcode 0xec
   3665   1.1     joerg ****************************************************************************/
   3666   1.1     joerg static void
   3667   1.1     joerg x86emuOp_in_byte_AL_DX(struct X86EMU *emu)
   3668   1.1     joerg {
   3669   1.1     joerg 	emu->x86.R_AL = (*emu->emu_inb) (emu, emu->x86.R_DX);
   3670   1.1     joerg }
   3671   1.1     joerg /****************************************************************************
   3672   1.1     joerg REMARKS:
   3673   1.1     joerg Handles opcode 0xed
   3674   1.1     joerg ****************************************************************************/
   3675   1.1     joerg static void
   3676   1.1     joerg x86emuOp_in_word_AX_DX(struct X86EMU *emu)
   3677   1.1     joerg {
   3678   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3679   1.1     joerg 		emu->x86.R_EAX = (*emu->emu_inl) (emu, emu->x86.R_DX);
   3680   1.1     joerg 	} else {
   3681   1.1     joerg 		emu->x86.R_AX = (*emu->emu_inw) (emu, emu->x86.R_DX);
   3682   1.1     joerg 	}
   3683   1.1     joerg }
   3684   1.1     joerg /****************************************************************************
   3685   1.1     joerg REMARKS:
   3686   1.1     joerg Handles opcode 0xee
   3687   1.1     joerg ****************************************************************************/
   3688   1.1     joerg static void
   3689   1.1     joerg x86emuOp_out_byte_DX_AL(struct X86EMU *emu)
   3690   1.1     joerg {
   3691   1.1     joerg 	(*emu->emu_outb) (emu, emu->x86.R_DX, emu->x86.R_AL);
   3692   1.1     joerg }
   3693   1.1     joerg /****************************************************************************
   3694   1.1     joerg REMARKS:
   3695   1.1     joerg Handles opcode 0xef
   3696   1.1     joerg ****************************************************************************/
   3697   1.1     joerg static void
   3698   1.1     joerg x86emuOp_out_word_DX_AX(struct X86EMU *emu)
   3699   1.1     joerg {
   3700   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   3701   1.1     joerg 		(*emu->emu_outl) (emu, emu->x86.R_DX, emu->x86.R_EAX);
   3702   1.1     joerg 	} else {
   3703   1.1     joerg 		(*emu->emu_outw) (emu, emu->x86.R_DX, emu->x86.R_AX);
   3704   1.1     joerg 	}
   3705   1.1     joerg }
   3706   1.1     joerg /****************************************************************************
   3707   1.1     joerg REMARKS:
   3708   1.1     joerg Handles opcode 0xf0
   3709   1.1     joerg ****************************************************************************/
   3710   1.1     joerg static void
   3711   1.1     joerg x86emuOp_lock(struct X86EMU *emu)
   3712   1.1     joerg {
   3713   1.1     joerg }
   3714   1.1     joerg /*opcode 0xf1 ILLEGAL OPERATION */
   3715   1.1     joerg 
   3716   1.1     joerg /****************************************************************************
   3717   1.1     joerg REMARKS:
   3718   1.1     joerg Handles opcode 0xf5
   3719   1.1     joerg ****************************************************************************/
   3720   1.1     joerg static void
   3721   1.1     joerg x86emuOp_cmc(struct X86EMU *emu)
   3722   1.1     joerg {
   3723   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   3724   1.1     joerg 		CLEAR_FLAG(F_CF);
   3725   1.1     joerg 	else
   3726   1.1     joerg 		SET_FLAG(F_CF);
   3727   1.1     joerg }
   3728   1.1     joerg /****************************************************************************
   3729   1.1     joerg REMARKS:
   3730   1.1     joerg Handles opcode 0xf6
   3731   1.1     joerg ****************************************************************************/
   3732   1.1     joerg static void
   3733   1.1     joerg x86emuOp_opcF6_byte_RM(struct X86EMU *emu)
   3734   1.1     joerg {
   3735   1.1     joerg 	uint8_t destval, srcval;
   3736   1.1     joerg 
   3737   1.1     joerg 	/* long, drawn out code follows.  Double switch for a total of 32
   3738   1.1     joerg 	 * cases.  */
   3739   1.1     joerg 	fetch_decode_modrm(emu);
   3740   1.1     joerg 	if (emu->cur_rh == 1)
   3741   1.1     joerg 		X86EMU_halt_sys(emu);
   3742   1.1     joerg 
   3743   1.1     joerg 	if (emu->cur_rh == 0) {
   3744   1.1     joerg 		destval = decode_and_fetch_byte_imm8(emu, &srcval);
   3745   1.1     joerg 		test_byte(emu, destval, srcval);
   3746   1.1     joerg 		return;
   3747   1.1     joerg 	}
   3748   1.1     joerg 	destval = decode_and_fetch_byte(emu);
   3749   1.1     joerg 	switch (emu->cur_rh) {
   3750   1.1     joerg 	case 2:
   3751   1.1     joerg 		destval = ~destval;
   3752   1.1     joerg 		write_back_byte(emu, destval);
   3753   1.1     joerg 		break;
   3754   1.1     joerg 	case 3:
   3755   1.1     joerg 		destval = neg_byte(emu, destval);
   3756   1.1     joerg 		write_back_byte(emu, destval);
   3757   1.1     joerg 		break;
   3758   1.1     joerg 	case 4:
   3759   1.1     joerg 		mul_byte(emu, destval);
   3760   1.1     joerg 		break;
   3761   1.1     joerg 	case 5:
   3762   1.1     joerg 		imul_byte(emu, destval);
   3763   1.1     joerg 		break;
   3764   1.1     joerg 	case 6:
   3765   1.1     joerg 		div_byte(emu, destval);
   3766   1.1     joerg 		break;
   3767   1.1     joerg 	case 7:
   3768   1.1     joerg 		idiv_byte(emu, destval);
   3769   1.1     joerg 		break;
   3770   1.1     joerg 	}
   3771   1.1     joerg }
   3772   1.1     joerg /****************************************************************************
   3773   1.1     joerg REMARKS:
   3774   1.1     joerg Handles opcode 0xf7
   3775   1.1     joerg ****************************************************************************/
   3776   1.1     joerg static void
   3777   1.1     joerg x86emuOp32_opcF7_word_RM(struct X86EMU *emu)
   3778   1.1     joerg {
   3779   1.1     joerg 	uint32_t destval, srcval;
   3780   1.1     joerg 
   3781   1.1     joerg 	/* long, drawn out code follows.  Double switch for a total of 32
   3782   1.1     joerg 	 * cases.  */
   3783   1.1     joerg 	fetch_decode_modrm(emu);
   3784   1.1     joerg 	if (emu->cur_rh == 1)
   3785   1.1     joerg 		X86EMU_halt_sys(emu);
   3786   1.1     joerg 
   3787   1.1     joerg 	if (emu->cur_rh == 0) {
   3788   1.1     joerg 		if (emu->cur_mod != 3) {
   3789   1.1     joerg 			uint32_t destoffset;
   3790   1.1     joerg 
   3791   1.1     joerg 			destoffset = decode_rl_address(emu);
   3792   1.1     joerg 			srcval = fetch_long_imm(emu);
   3793   1.1     joerg 			destval = fetch_data_long(emu, destoffset);
   3794   1.1     joerg 		} else {
   3795   1.1     joerg 			srcval = fetch_long_imm(emu);
   3796   1.1     joerg 			destval = *decode_rl_long_register(emu);
   3797   1.1     joerg 		}
   3798   1.1     joerg 		test_long(emu, destval, srcval);
   3799   1.1     joerg 		return;
   3800   1.1     joerg 	}
   3801   1.1     joerg 	destval = decode_and_fetch_long(emu);
   3802   1.1     joerg 	switch (emu->cur_rh) {
   3803   1.1     joerg 	case 2:
   3804   1.1     joerg 		destval = ~destval;
   3805   1.1     joerg 		write_back_long(emu, destval);
   3806   1.1     joerg 		break;
   3807   1.1     joerg 	case 3:
   3808   1.1     joerg 		destval = neg_long(emu, destval);
   3809   1.1     joerg 		write_back_long(emu, destval);
   3810   1.1     joerg 		break;
   3811   1.1     joerg 	case 4:
   3812   1.1     joerg 		mul_long(emu, destval);
   3813   1.1     joerg 		break;
   3814   1.1     joerg 	case 5:
   3815   1.1     joerg 		imul_long(emu, destval);
   3816   1.1     joerg 		break;
   3817   1.1     joerg 	case 6:
   3818   1.1     joerg 		div_long(emu, destval);
   3819   1.1     joerg 		break;
   3820   1.1     joerg 	case 7:
   3821   1.1     joerg 		idiv_long(emu, destval);
   3822   1.1     joerg 		break;
   3823   1.1     joerg 	}
   3824   1.1     joerg }
   3825   1.1     joerg static void
   3826   1.1     joerg x86emuOp16_opcF7_word_RM(struct X86EMU *emu)
   3827   1.1     joerg {
   3828   1.1     joerg 	uint16_t destval, srcval;
   3829   1.1     joerg 
   3830   1.1     joerg 	/* long, drawn out code follows.  Double switch for a total of 32
   3831   1.1     joerg 	 * cases.  */
   3832   1.1     joerg 	fetch_decode_modrm(emu);
   3833   1.1     joerg 	if (emu->cur_rh == 1)
   3834   1.1     joerg 		X86EMU_halt_sys(emu);
   3835   1.1     joerg 
   3836   1.1     joerg 	if (emu->cur_rh == 0) {
   3837   1.1     joerg 		if (emu->cur_mod != 3) {
   3838   1.1     joerg 			uint32_t destoffset;
   3839   1.1     joerg 
   3840   1.1     joerg 			destoffset = decode_rl_address(emu);
   3841   1.1     joerg 			srcval = fetch_word_imm(emu);
   3842   1.1     joerg 			destval = fetch_data_word(emu, destoffset);
   3843   1.1     joerg 		} else {
   3844   1.1     joerg 			srcval = fetch_word_imm(emu);
   3845   1.1     joerg 			destval = *decode_rl_word_register(emu);
   3846   1.1     joerg 		}
   3847   1.1     joerg 		test_word(emu, destval, srcval);
   3848   1.1     joerg 		return;
   3849   1.1     joerg 	}
   3850   1.1     joerg 	destval = decode_and_fetch_word(emu);
   3851   1.1     joerg 	switch (emu->cur_rh) {
   3852   1.1     joerg 	case 2:
   3853   1.1     joerg 		destval = ~destval;
   3854   1.1     joerg 		write_back_word(emu, destval);
   3855   1.1     joerg 		break;
   3856   1.1     joerg 	case 3:
   3857   1.1     joerg 		destval = neg_word(emu, destval);
   3858   1.1     joerg 		write_back_word(emu, destval);
   3859   1.1     joerg 		break;
   3860   1.1     joerg 	case 4:
   3861   1.1     joerg 		mul_word(emu, destval);
   3862   1.1     joerg 		break;
   3863   1.1     joerg 	case 5:
   3864   1.1     joerg 		imul_word(emu, destval);
   3865   1.1     joerg 		break;
   3866   1.1     joerg 	case 6:
   3867   1.1     joerg 		div_word(emu, destval);
   3868   1.1     joerg 		break;
   3869   1.1     joerg 	case 7:
   3870   1.1     joerg 		idiv_word(emu, destval);
   3871   1.1     joerg 		break;
   3872   1.1     joerg 	}
   3873   1.1     joerg }
   3874   1.1     joerg static void
   3875   1.1     joerg x86emuOp_opcF7_word_RM(struct X86EMU *emu)
   3876   1.1     joerg {
   3877   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   3878   1.1     joerg 		x86emuOp32_opcF7_word_RM(emu);
   3879   1.1     joerg 	else
   3880   1.1     joerg 		x86emuOp16_opcF7_word_RM(emu);
   3881   1.1     joerg }
   3882   1.1     joerg /****************************************************************************
   3883   1.1     joerg REMARKS:
   3884   1.1     joerg Handles opcode 0xfe
   3885   1.1     joerg ****************************************************************************/
   3886   1.1     joerg static void
   3887   1.1     joerg x86emuOp_opcFE_byte_RM(struct X86EMU *emu)
   3888   1.1     joerg {
   3889   1.1     joerg 	uint8_t destval;
   3890   1.1     joerg 	uint32_t destoffset;
   3891   1.1     joerg 	uint8_t *destreg;
   3892   1.1     joerg 
   3893   1.1     joerg 	/* Yet another special case instruction. */
   3894   1.1     joerg 	fetch_decode_modrm(emu);
   3895   1.1     joerg 	if (emu->cur_mod != 3) {
   3896   1.1     joerg 		destoffset = decode_rl_address(emu);
   3897   1.1     joerg 		switch (emu->cur_rh) {
   3898   1.1     joerg 		case 0:	/* inc word ptr ... */
   3899   1.1     joerg 			destval = fetch_data_byte(emu, destoffset);
   3900   1.1     joerg 			destval = inc_byte(emu, destval);
   3901   1.1     joerg 			store_data_byte(emu, destoffset, destval);
   3902   1.1     joerg 			break;
   3903   1.1     joerg 		case 1:	/* dec word ptr ... */
   3904   1.1     joerg 			destval = fetch_data_byte(emu, destoffset);
   3905   1.1     joerg 			destval = dec_byte(emu, destval);
   3906   1.1     joerg 			store_data_byte(emu, destoffset, destval);
   3907   1.1     joerg 			break;
   3908   1.1     joerg 		}
   3909   1.1     joerg 	} else {
   3910   1.1     joerg 		destreg = decode_rl_byte_register(emu);
   3911   1.1     joerg 		switch (emu->cur_rh) {
   3912   1.1     joerg 		case 0:
   3913   1.1     joerg 			*destreg = inc_byte(emu, *destreg);
   3914   1.1     joerg 			break;
   3915   1.1     joerg 		case 1:
   3916   1.1     joerg 			*destreg = dec_byte(emu, *destreg);
   3917   1.1     joerg 			break;
   3918   1.1     joerg 		}
   3919   1.1     joerg 	}
   3920   1.1     joerg }
   3921   1.1     joerg /****************************************************************************
   3922   1.1     joerg REMARKS:
   3923   1.1     joerg Handles opcode 0xff
   3924   1.1     joerg ****************************************************************************/
   3925   1.1     joerg static void
   3926   1.1     joerg x86emuOp32_opcFF_word_RM(struct X86EMU *emu)
   3927   1.1     joerg {
   3928   1.1     joerg 	uint32_t destoffset = 0;
   3929   1.1     joerg 	uint32_t destval, *destreg;
   3930   1.1     joerg 
   3931   1.1     joerg 	if (emu->cur_mod != 3) {
   3932   1.1     joerg 		destoffset = decode_rl_address(emu);
   3933   1.1     joerg 		destval = fetch_data_long(emu, destoffset);
   3934   1.1     joerg 		switch (emu->cur_rh) {
   3935   1.1     joerg 		case 0:	/* inc word ptr ... */
   3936   1.1     joerg 			destval = inc_long(emu, destval);
   3937   1.1     joerg 			store_data_long(emu, destoffset, destval);
   3938   1.1     joerg 			break;
   3939   1.1     joerg 		case 1:	/* dec word ptr ... */
   3940   1.1     joerg 			destval = dec_long(emu, destval);
   3941   1.1     joerg 			store_data_long(emu, destoffset, destval);
   3942   1.1     joerg 			break;
   3943   1.1     joerg 		case 6:	/* push word ptr ... */
   3944   1.1     joerg 			push_long(emu, destval);
   3945   1.1     joerg 			break;
   3946   1.1     joerg 		}
   3947   1.1     joerg 	} else {
   3948   1.1     joerg 		destreg = decode_rl_long_register(emu);
   3949   1.1     joerg 		switch (emu->cur_rh) {
   3950   1.1     joerg 		case 0:
   3951   1.1     joerg 			*destreg = inc_long(emu, *destreg);
   3952   1.1     joerg 			break;
   3953   1.1     joerg 		case 1:
   3954   1.1     joerg 			*destreg = dec_long(emu, *destreg);
   3955   1.1     joerg 			break;
   3956   1.1     joerg 		case 6:
   3957   1.1     joerg 			push_long(emu, *destreg);
   3958   1.1     joerg 			break;
   3959   1.1     joerg 		}
   3960   1.1     joerg 	}
   3961   1.1     joerg }
   3962   1.1     joerg 
   3963   1.1     joerg static void
   3964   1.1     joerg x86emuOp16_opcFF_word_RM(struct X86EMU *emu)
   3965   1.1     joerg {
   3966   1.1     joerg 	uint32_t destoffset = 0;
   3967   1.1     joerg 	uint16_t *destreg;
   3968   1.1     joerg 	uint16_t destval;
   3969   1.1     joerg 
   3970   1.1     joerg 	if (emu->cur_mod != 3) {
   3971   1.1     joerg 		destoffset = decode_rl_address(emu);
   3972   1.1     joerg 		destval = fetch_data_word(emu, destoffset);
   3973   1.1     joerg 		switch (emu->cur_rh) {
   3974   1.1     joerg 		case 0:
   3975   1.1     joerg 			destval = inc_word(emu, destval);
   3976   1.1     joerg 			store_data_word(emu, destoffset, destval);
   3977   1.1     joerg 			break;
   3978   1.1     joerg 		case 1:	/* dec word ptr ... */
   3979   1.1     joerg 			destval = dec_word(emu, destval);
   3980   1.1     joerg 			store_data_word(emu, destoffset, destval);
   3981   1.1     joerg 			break;
   3982   1.1     joerg 		case 6:	/* push word ptr ... */
   3983   1.1     joerg 			push_word(emu, destval);
   3984   1.1     joerg 			break;
   3985   1.1     joerg 		}
   3986   1.1     joerg 	} else {
   3987   1.1     joerg 		destreg = decode_rl_word_register(emu);
   3988   1.1     joerg 		switch (emu->cur_rh) {
   3989   1.1     joerg 		case 0:
   3990   1.1     joerg 			*destreg = inc_word(emu, *destreg);
   3991   1.1     joerg 			break;
   3992   1.1     joerg 		case 1:
   3993   1.1     joerg 			*destreg = dec_word(emu, *destreg);
   3994   1.1     joerg 			break;
   3995   1.1     joerg 		case 6:
   3996   1.1     joerg 			push_word(emu, *destreg);
   3997   1.1     joerg 			break;
   3998   1.1     joerg 		}
   3999   1.1     joerg 	}
   4000   1.1     joerg }
   4001   1.1     joerg 
   4002   1.1     joerg static void
   4003   1.1     joerg x86emuOp_opcFF_word_RM(struct X86EMU *emu)
   4004   1.1     joerg {
   4005   1.1     joerg 	uint32_t destoffset = 0;
   4006   1.1     joerg 	uint16_t destval, destval2;
   4007   1.1     joerg 
   4008   1.1     joerg 	/* Yet another special case instruction. */
   4009   1.1     joerg 	fetch_decode_modrm(emu);
   4010   1.1     joerg 	if ((emu->cur_mod == 3 && (emu->cur_rh == 3 || emu->cur_rh == 5)) || emu->cur_rh == 7)
   4011   1.1     joerg 		X86EMU_halt_sys(emu);
   4012   1.1     joerg 	if (emu->cur_rh == 0 || emu->cur_rh == 1 || emu->cur_rh == 6) {
   4013   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   4014   1.1     joerg 			x86emuOp32_opcFF_word_RM(emu);
   4015   1.1     joerg 		else
   4016   1.1     joerg 			x86emuOp16_opcFF_word_RM(emu);
   4017   1.1     joerg 		return;
   4018   1.1     joerg 	}
   4019   1.1     joerg 
   4020   1.1     joerg 	if (emu->cur_mod != 3) {
   4021   1.1     joerg 		destoffset = decode_rl_address(emu);
   4022   1.1     joerg 		destval = fetch_data_word(emu, destoffset);
   4023   1.1     joerg 		switch (emu->cur_rh) {
   4024   1.1     joerg 		case 3:	/* call far ptr ... */
   4025   1.1     joerg 			destval2 = fetch_data_word(emu, destoffset + 2);
   4026   1.1     joerg 			push_word(emu, emu->x86.R_CS);
   4027   1.1     joerg 			emu->x86.R_CS = destval2;
   4028   1.1     joerg 			push_word(emu, emu->x86.R_IP);
   4029   1.1     joerg 			emu->x86.R_IP = destval;
   4030   1.1     joerg 			break;
   4031   1.1     joerg 		case 5:	/* jmp far ptr ... */
   4032   1.1     joerg 			destval2 = fetch_data_word(emu, destoffset + 2);
   4033   1.1     joerg 			emu->x86.R_IP = destval;
   4034   1.1     joerg 			emu->x86.R_CS = destval2;
   4035   1.1     joerg 			break;
   4036   1.1     joerg 		}
   4037   1.1     joerg 	} else {
   4038   1.1     joerg 		destval = *decode_rl_word_register(emu);
   4039   1.1     joerg 	}
   4040   1.1     joerg 
   4041   1.1     joerg 	switch (emu->cur_rh) {
   4042   1.1     joerg 	case 2: /* call word ptr */
   4043   1.1     joerg 		push_word(emu, emu->x86.R_IP);
   4044   1.1     joerg 		emu->x86.R_IP = destval;
   4045   1.1     joerg 		break;
   4046   1.1     joerg 	case 4: /* jmp */
   4047   1.1     joerg 		emu->x86.R_IP = destval;
   4048   1.1     joerg 		break;
   4049   1.1     joerg 	}
   4050   1.1     joerg }
   4051   1.1     joerg /***************************************************************************
   4052   1.1     joerg  * Single byte operation code table:
   4053   1.1     joerg  **************************************************************************/
   4054   1.1     joerg static void
   4055   1.1     joerg X86EMU_exec_one_byte(struct X86EMU * emu)
   4056   1.1     joerg {
   4057   1.1     joerg 	uint8_t op1;
   4058   1.1     joerg 
   4059   1.1     joerg 	op1 = fetch_byte_imm(emu);
   4060   1.1     joerg 
   4061   1.1     joerg 	switch (op1) {
   4062   1.1     joerg 	case 0x00:
   4063   1.1     joerg 		common_binop_byte_rm_r(emu, add_byte);
   4064   1.1     joerg 		break;
   4065   1.1     joerg 	case 0x01:
   4066   1.1     joerg 		common_binop_word_long_rm_r(emu, add_word, add_long);
   4067   1.1     joerg 		break;
   4068   1.1     joerg 	case 0x02:
   4069   1.1     joerg 		common_binop_byte_r_rm(emu, add_byte);
   4070   1.1     joerg 		break;
   4071   1.1     joerg 	case 0x03:
   4072   1.1     joerg 		common_binop_word_long_r_rm(emu, add_word, add_long);
   4073   1.1     joerg 		break;
   4074   1.1     joerg 	case 0x04:
   4075   1.1     joerg 		common_binop_byte_imm(emu, add_byte);
   4076   1.1     joerg 		break;
   4077   1.1     joerg 	case 0x05:
   4078   1.1     joerg 		common_binop_word_long_imm(emu, add_word, add_long);
   4079   1.1     joerg 		break;
   4080   1.1     joerg 	case 0x06:
   4081   1.1     joerg 		push_word(emu, emu->x86.R_ES);
   4082   1.1     joerg 		break;
   4083   1.1     joerg 	case 0x07:
   4084   1.1     joerg 		emu->x86.R_ES = pop_word(emu);
   4085   1.1     joerg 		break;
   4086   1.1     joerg 
   4087   1.1     joerg 	case 0x08:
   4088   1.1     joerg 		common_binop_byte_rm_r(emu, or_byte);
   4089   1.1     joerg 		break;
   4090   1.1     joerg 	case 0x09:
   4091   1.1     joerg 		common_binop_word_long_rm_r(emu, or_word, or_long);
   4092   1.1     joerg 		break;
   4093   1.1     joerg 	case 0x0a:
   4094   1.1     joerg 		common_binop_byte_r_rm(emu, or_byte);
   4095   1.1     joerg 		break;
   4096   1.1     joerg 	case 0x0b:
   4097   1.1     joerg 		common_binop_word_long_r_rm(emu, or_word, or_long);
   4098   1.1     joerg 		break;
   4099   1.1     joerg 	case 0x0c:
   4100   1.1     joerg 		common_binop_byte_imm(emu, or_byte);
   4101   1.1     joerg 		break;
   4102   1.1     joerg 	case 0x0d:
   4103   1.1     joerg 		common_binop_word_long_imm(emu, or_word, or_long);
   4104   1.1     joerg 		break;
   4105   1.1     joerg 	case 0x0e:
   4106   1.1     joerg 		push_word(emu, emu->x86.R_CS);
   4107   1.1     joerg 		break;
   4108   1.1     joerg 	case 0x0f:
   4109   1.1     joerg 		X86EMU_exec_two_byte(emu);
   4110   1.1     joerg 		break;
   4111   1.1     joerg 
   4112   1.1     joerg 	case 0x10:
   4113   1.1     joerg 		common_binop_byte_rm_r(emu, adc_byte);
   4114   1.1     joerg 		break;
   4115   1.1     joerg 	case 0x11:
   4116   1.1     joerg 		common_binop_word_long_rm_r(emu, adc_word, adc_long);
   4117   1.1     joerg 		break;
   4118   1.1     joerg 	case 0x12:
   4119   1.1     joerg 		common_binop_byte_r_rm(emu, adc_byte);
   4120   1.1     joerg 		break;
   4121   1.1     joerg 	case 0x13:
   4122   1.1     joerg 		common_binop_word_long_r_rm(emu, adc_word, adc_long);
   4123   1.1     joerg 		break;
   4124   1.1     joerg 	case 0x14:
   4125   1.1     joerg 		common_binop_byte_imm(emu, adc_byte);
   4126   1.1     joerg 		break;
   4127   1.1     joerg 	case 0x15:
   4128   1.1     joerg 		common_binop_word_long_imm(emu, adc_word, adc_long);
   4129   1.1     joerg 		break;
   4130   1.1     joerg 	case 0x16:
   4131   1.1     joerg 		push_word(emu, emu->x86.R_SS);
   4132   1.1     joerg 		break;
   4133   1.1     joerg 	case 0x17:
   4134   1.1     joerg 		emu->x86.R_SS = pop_word(emu);
   4135   1.1     joerg 		break;
   4136   1.1     joerg 
   4137   1.1     joerg 	case 0x18:
   4138   1.1     joerg 		common_binop_byte_rm_r(emu, sbb_byte);
   4139   1.1     joerg 		break;
   4140   1.1     joerg 	case 0x19:
   4141   1.1     joerg 		common_binop_word_long_rm_r(emu, sbb_word, sbb_long);
   4142   1.1     joerg 		break;
   4143   1.1     joerg 	case 0x1a:
   4144   1.1     joerg 		common_binop_byte_r_rm(emu, sbb_byte);
   4145   1.1     joerg 		break;
   4146   1.1     joerg 	case 0x1b:
   4147   1.1     joerg 		common_binop_word_long_r_rm(emu, sbb_word, sbb_long);
   4148   1.1     joerg 		break;
   4149   1.1     joerg 	case 0x1c:
   4150   1.1     joerg 		common_binop_byte_imm(emu, sbb_byte);
   4151   1.1     joerg 		break;
   4152   1.1     joerg 	case 0x1d:
   4153   1.1     joerg 		common_binop_word_long_imm(emu, sbb_word, sbb_long);
   4154   1.1     joerg 		break;
   4155   1.1     joerg 	case 0x1e:
   4156   1.1     joerg 		push_word(emu, emu->x86.R_DS);
   4157   1.1     joerg 		break;
   4158   1.1     joerg 	case 0x1f:
   4159   1.1     joerg 		emu->x86.R_DS = pop_word(emu);
   4160   1.1     joerg 		break;
   4161   1.1     joerg 
   4162   1.1     joerg 	case 0x20:
   4163   1.1     joerg 		common_binop_byte_rm_r(emu, and_byte);
   4164   1.1     joerg 		break;
   4165   1.1     joerg 	case 0x21:
   4166   1.1     joerg 		common_binop_word_long_rm_r(emu, and_word, and_long);
   4167   1.1     joerg 		break;
   4168   1.1     joerg 	case 0x22:
   4169   1.1     joerg 		common_binop_byte_r_rm(emu, and_byte);
   4170   1.1     joerg 		break;
   4171   1.1     joerg 	case 0x23:
   4172   1.1     joerg 		common_binop_word_long_r_rm(emu, and_word, and_long);
   4173   1.1     joerg 		break;
   4174   1.1     joerg 	case 0x24:
   4175   1.1     joerg 		common_binop_byte_imm(emu, and_byte);
   4176   1.1     joerg 		break;
   4177   1.1     joerg 	case 0x25:
   4178   1.1     joerg 		common_binop_word_long_imm(emu, and_word, and_long);
   4179   1.1     joerg 		break;
   4180   1.1     joerg 	case 0x26:
   4181   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_ES;
   4182   1.1     joerg 		break;
   4183   1.1     joerg 	case 0x27:
   4184   1.1     joerg 		emu->x86.R_AL = daa_byte(emu, emu->x86.R_AL);
   4185   1.1     joerg 		break;
   4186   1.1     joerg 
   4187   1.1     joerg 	case 0x28:
   4188   1.1     joerg 		common_binop_byte_rm_r(emu, sub_byte);
   4189   1.1     joerg 		break;
   4190   1.1     joerg 	case 0x29:
   4191   1.1     joerg 		common_binop_word_long_rm_r(emu, sub_word, sub_long);
   4192   1.1     joerg 		break;
   4193   1.1     joerg 	case 0x2a:
   4194   1.1     joerg 		common_binop_byte_r_rm(emu, sub_byte);
   4195   1.1     joerg 		break;
   4196   1.1     joerg 	case 0x2b:
   4197   1.1     joerg 		common_binop_word_long_r_rm(emu, sub_word, sub_long);
   4198   1.1     joerg 		break;
   4199   1.1     joerg 	case 0x2c:
   4200   1.1     joerg 		common_binop_byte_imm(emu, sub_byte);
   4201   1.1     joerg 		break;
   4202   1.1     joerg 	case 0x2d:
   4203   1.1     joerg 		common_binop_word_long_imm(emu, sub_word, sub_long);
   4204   1.1     joerg 		break;
   4205   1.1     joerg 	case 0x2e:
   4206   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_CS;
   4207   1.1     joerg 		break;
   4208   1.1     joerg 	case 0x2f:
   4209   1.1     joerg 		emu->x86.R_AL = das_byte(emu, emu->x86.R_AL);
   4210   1.1     joerg 		break;
   4211   1.1     joerg 
   4212   1.1     joerg 	case 0x30:
   4213   1.1     joerg 		common_binop_byte_rm_r(emu, xor_byte);
   4214   1.1     joerg 		break;
   4215   1.1     joerg 	case 0x31:
   4216   1.1     joerg 		common_binop_word_long_rm_r(emu, xor_word, xor_long);
   4217   1.1     joerg 		break;
   4218   1.1     joerg 	case 0x32:
   4219   1.1     joerg 		common_binop_byte_r_rm(emu, xor_byte);
   4220   1.1     joerg 		break;
   4221   1.1     joerg 	case 0x33:
   4222   1.1     joerg 		common_binop_word_long_r_rm(emu, xor_word, xor_long);
   4223   1.1     joerg 		break;
   4224   1.1     joerg 	case 0x34:
   4225   1.1     joerg 		common_binop_byte_imm(emu, xor_byte);
   4226   1.1     joerg 		break;
   4227   1.1     joerg 	case 0x35:
   4228   1.1     joerg 		common_binop_word_long_imm(emu, xor_word, xor_long);
   4229   1.1     joerg 		break;
   4230   1.1     joerg 	case 0x36:
   4231   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_SS;
   4232   1.1     joerg 		break;
   4233   1.1     joerg 	case 0x37:
   4234   1.1     joerg 		emu->x86.R_AX = aaa_word(emu, emu->x86.R_AX);
   4235   1.1     joerg 		break;
   4236   1.1     joerg 
   4237   1.1     joerg 	case 0x38:
   4238   1.1     joerg 		common_binop_ns_byte_rm_r(emu, cmp_byte_no_return);
   4239   1.1     joerg 		break;
   4240   1.1     joerg 	case 0x39:
   4241   1.1     joerg 		common_binop_ns_word_long_rm_r(emu, cmp_word_no_return,
   4242   1.1     joerg 		    cmp_long_no_return);
   4243   1.1     joerg 		break;
   4244   1.1     joerg 	case 0x3a:
   4245   1.1     joerg 		x86emuOp_cmp_byte_R_RM(emu);
   4246   1.1     joerg 		break;
   4247   1.1     joerg 	case 0x3b:
   4248   1.1     joerg 		x86emuOp_cmp_word_R_RM(emu);
   4249   1.1     joerg 		break;
   4250   1.1     joerg 	case 0x3c:
   4251   1.1     joerg 		x86emuOp_cmp_byte_AL_IMM(emu);
   4252   1.1     joerg 		break;
   4253   1.1     joerg 	case 0x3d:
   4254   1.1     joerg 		x86emuOp_cmp_word_AX_IMM(emu);
   4255   1.1     joerg 		break;
   4256   1.1     joerg 	case 0x3e:
   4257   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_DS;
   4258   1.1     joerg 		break;
   4259   1.1     joerg 	case 0x3f:
   4260   1.1     joerg 		emu->x86.R_AX = aas_word(emu, emu->x86.R_AX);
   4261   1.1     joerg 		break;
   4262   1.1     joerg 
   4263   1.1     joerg 	case 0x40:
   4264   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_a);
   4265   1.1     joerg 		break;
   4266   1.1     joerg 	case 0x41:
   4267   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_c);
   4268   1.1     joerg 		break;
   4269   1.1     joerg 	case 0x42:
   4270   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_d);
   4271   1.1     joerg 		break;
   4272   1.1     joerg 	case 0x43:
   4273   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_b);
   4274   1.1     joerg 		break;
   4275   1.1     joerg 	case 0x44:
   4276   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_sp);
   4277   1.1     joerg 		break;
   4278   1.1     joerg 	case 0x45:
   4279   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_bp);
   4280   1.1     joerg 		break;
   4281   1.1     joerg 	case 0x46:
   4282   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_si);
   4283   1.1     joerg 		break;
   4284   1.1     joerg 	case 0x47:
   4285   1.1     joerg 		common_inc_word_long(emu, &emu->x86.register_di);
   4286   1.1     joerg 		break;
   4287   1.1     joerg 
   4288   1.1     joerg 	case 0x48:
   4289   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_a);
   4290   1.1     joerg 		break;
   4291   1.1     joerg 	case 0x49:
   4292   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_c);
   4293   1.1     joerg 		break;
   4294   1.1     joerg 	case 0x4a:
   4295   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_d);
   4296   1.1     joerg 		break;
   4297   1.1     joerg 	case 0x4b:
   4298   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_b);
   4299   1.1     joerg 		break;
   4300   1.1     joerg 	case 0x4c:
   4301   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_sp);
   4302   1.1     joerg 		break;
   4303   1.1     joerg 	case 0x4d:
   4304   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_bp);
   4305   1.1     joerg 		break;
   4306   1.1     joerg 	case 0x4e:
   4307   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_si);
   4308   1.1     joerg 		break;
   4309   1.1     joerg 	case 0x4f:
   4310   1.1     joerg 		common_dec_word_long(emu, &emu->x86.register_di);
   4311   1.1     joerg 		break;
   4312   1.1     joerg 
   4313   1.1     joerg 	case 0x50:
   4314   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_a);
   4315   1.1     joerg 		break;
   4316   1.1     joerg 	case 0x51:
   4317   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_c);
   4318   1.1     joerg 		break;
   4319   1.1     joerg 	case 0x52:
   4320   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_d);
   4321   1.1     joerg 		break;
   4322   1.1     joerg 	case 0x53:
   4323   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_b);
   4324   1.1     joerg 		break;
   4325   1.1     joerg 	case 0x54:
   4326   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_sp);
   4327   1.1     joerg 		break;
   4328   1.1     joerg 	case 0x55:
   4329   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_bp);
   4330   1.1     joerg 		break;
   4331   1.1     joerg 	case 0x56:
   4332   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_si);
   4333   1.1     joerg 		break;
   4334   1.1     joerg 	case 0x57:
   4335   1.1     joerg 		common_push_word_long(emu, &emu->x86.register_di);
   4336   1.1     joerg 		break;
   4337   1.1     joerg 
   4338   1.1     joerg 	case 0x58:
   4339   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_a);
   4340   1.1     joerg 		break;
   4341   1.1     joerg 	case 0x59:
   4342   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_c);
   4343   1.1     joerg 		break;
   4344   1.1     joerg 	case 0x5a:
   4345   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_d);
   4346   1.1     joerg 		break;
   4347   1.1     joerg 	case 0x5b:
   4348   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_b);
   4349   1.1     joerg 		break;
   4350   1.1     joerg 	case 0x5c:
   4351   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_sp);
   4352   1.1     joerg 		break;
   4353   1.1     joerg 	case 0x5d:
   4354   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_bp);
   4355   1.1     joerg 		break;
   4356   1.1     joerg 	case 0x5e:
   4357   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_si);
   4358   1.1     joerg 		break;
   4359   1.1     joerg 	case 0x5f:
   4360   1.1     joerg 		common_pop_word_long(emu, &emu->x86.register_di);
   4361   1.1     joerg 		break;
   4362   1.1     joerg 
   4363   1.1     joerg 	case 0x60:
   4364   1.1     joerg 		x86emuOp_push_all(emu);
   4365   1.1     joerg 		break;
   4366   1.1     joerg 	case 0x61:
   4367   1.1     joerg 		x86emuOp_pop_all(emu);
   4368   1.1     joerg 		break;
   4369   1.1     joerg 	/* 0x62 bound */
   4370   1.1     joerg 	/* 0x63 arpl */
   4371   1.1     joerg 	case 0x64:
   4372   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_FS;
   4373   1.1     joerg 		break;
   4374   1.1     joerg 	case 0x65:
   4375   1.1     joerg 		emu->x86.mode |= SYSMODE_SEGOVR_GS;
   4376   1.1     joerg 		break;
   4377   1.1     joerg 	case 0x66:
   4378   1.1     joerg 		emu->x86.mode |= SYSMODE_PREFIX_DATA;
   4379   1.1     joerg 		break;
   4380   1.1     joerg 	case 0x67:
   4381   1.1     joerg 		emu->x86.mode |= SYSMODE_PREFIX_ADDR;
   4382   1.1     joerg 		break;
   4383   1.1     joerg 
   4384   1.1     joerg 	case 0x68:
   4385   1.1     joerg 		x86emuOp_push_word_IMM(emu);
   4386   1.1     joerg 		break;
   4387   1.1     joerg 	case 0x69:
   4388   1.1     joerg 		common_imul_imm(emu, false);
   4389   1.1     joerg 		break;
   4390   1.1     joerg 	case 0x6a:
   4391   1.1     joerg 		x86emuOp_push_byte_IMM(emu);
   4392   1.1     joerg 		break;
   4393   1.1     joerg 	case 0x6b:
   4394   1.1     joerg 		common_imul_imm(emu, true);
   4395   1.1     joerg 		break;
   4396   1.1     joerg 	case 0x6c:
   4397   1.1     joerg 		ins(emu, 1);
   4398   1.1     joerg 		break;
   4399   1.1     joerg 	case 0x6d:
   4400   1.1     joerg 		x86emuOp_ins_word(emu);
   4401   1.1     joerg 		break;
   4402   1.1     joerg 	case 0x6e:
   4403   1.1     joerg 		outs(emu, 1);
   4404   1.1     joerg 		break;
   4405   1.1     joerg 	case 0x6f:
   4406   1.1     joerg 		x86emuOp_outs_word(emu);
   4407   1.1     joerg 		break;
   4408   1.1     joerg 
   4409   1.1     joerg 	case 0x70:
   4410   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_OF));
   4411   1.1     joerg 		break;
   4412   1.1     joerg 	case 0x71:
   4413   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_OF));
   4414   1.1     joerg 		break;
   4415   1.1     joerg 	case 0x72:
   4416   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_CF));
   4417   1.1     joerg 		break;
   4418   1.1     joerg 	case 0x73:
   4419   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_CF));
   4420   1.1     joerg 		break;
   4421   1.1     joerg 	case 0x74:
   4422   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_ZF));
   4423   1.1     joerg 		break;
   4424   1.1     joerg 	case 0x75:
   4425   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_ZF));
   4426   1.1     joerg 		break;
   4427   1.1     joerg 	case 0x76:
   4428   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
   4429   1.1     joerg 		break;
   4430   1.1     joerg 	case 0x77:
   4431   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_CF) && !ACCESS_FLAG(F_ZF));
   4432   1.1     joerg 		break;
   4433   1.1     joerg 
   4434   1.1     joerg 	case 0x78:
   4435   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_SF));
   4436   1.1     joerg 		break;
   4437   1.1     joerg 	case 0x79:
   4438   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_SF));
   4439   1.1     joerg 		break;
   4440   1.1     joerg 	case 0x7a:
   4441   1.1     joerg 		common_jmp_near(emu, ACCESS_FLAG(F_PF));
   4442   1.1     joerg 		break;
   4443   1.1     joerg 	case 0x7b:
   4444   1.1     joerg 		common_jmp_near(emu, !ACCESS_FLAG(F_PF));
   4445   1.1     joerg 		break;
   4446   1.1     joerg 	case 0x7c:
   4447   1.1     joerg 		x86emuOp_jump_near_L(emu);
   4448   1.1     joerg 		break;
   4449   1.1     joerg 	case 0x7d:
   4450   1.1     joerg 		x86emuOp_jump_near_NL(emu);
   4451   1.1     joerg 		break;
   4452   1.1     joerg 	case 0x7e:
   4453   1.1     joerg 		x86emuOp_jump_near_LE(emu);
   4454   1.1     joerg 		break;
   4455   1.1     joerg 	case 0x7f:
   4456   1.1     joerg 		x86emuOp_jump_near_NLE(emu);
   4457   1.1     joerg 		break;
   4458   1.1     joerg 
   4459   1.1     joerg 	case 0x80:
   4460   1.1     joerg 		x86emuOp_opc80_byte_RM_IMM(emu);
   4461   1.1     joerg 		break;
   4462   1.1     joerg 	case 0x81:
   4463   1.1     joerg 		x86emuOp_opc81_word_RM_IMM(emu);
   4464   1.1     joerg 		break;
   4465   1.1     joerg 	case 0x82:
   4466   1.1     joerg 		x86emuOp_opc82_byte_RM_IMM(emu);
   4467   1.1     joerg 		break;
   4468   1.1     joerg 	case 0x83:
   4469   1.1     joerg 		x86emuOp_opc83_word_RM_IMM(emu);
   4470   1.1     joerg 		break;
   4471   1.1     joerg 	case 0x84:
   4472   1.1     joerg 		common_binop_ns_byte_rm_r(emu, test_byte);
   4473   1.1     joerg 		break;
   4474   1.1     joerg 	case 0x85:
   4475   1.1     joerg 		common_binop_ns_word_long_rm_r(emu, test_word, test_long);
   4476   1.1     joerg 		break;
   4477   1.1     joerg 	case 0x86:
   4478   1.1     joerg 		x86emuOp_xchg_byte_RM_R(emu);
   4479   1.1     joerg 		break;
   4480   1.1     joerg 	case 0x87:
   4481   1.1     joerg 		x86emuOp_xchg_word_RM_R(emu);
   4482   1.1     joerg 		break;
   4483   1.1     joerg 
   4484   1.1     joerg 	case 0x88:
   4485   1.1     joerg 		x86emuOp_mov_byte_RM_R(emu);
   4486   1.1     joerg 		break;
   4487   1.1     joerg 	case 0x89:
   4488   1.1     joerg 		x86emuOp_mov_word_RM_R(emu);
   4489   1.1     joerg 		break;
   4490   1.1     joerg 	case 0x8a:
   4491   1.1     joerg 		x86emuOp_mov_byte_R_RM(emu);
   4492   1.1     joerg 		break;
   4493   1.1     joerg 	case 0x8b:
   4494   1.1     joerg 		x86emuOp_mov_word_R_RM(emu);
   4495   1.1     joerg 		break;
   4496   1.1     joerg 	case 0x8c:
   4497   1.1     joerg 		x86emuOp_mov_word_RM_SR(emu);
   4498   1.1     joerg 		break;
   4499   1.1     joerg 	case 0x8d:
   4500   1.1     joerg 		x86emuOp_lea_word_R_M(emu);
   4501   1.1     joerg 		break;
   4502   1.1     joerg 	case 0x8e:
   4503   1.1     joerg 		x86emuOp_mov_word_SR_RM(emu);
   4504   1.1     joerg 		break;
   4505   1.1     joerg 	case 0x8f:
   4506   1.1     joerg 		x86emuOp_pop_RM(emu);
   4507   1.1     joerg 		break;
   4508   1.1     joerg 
   4509   1.1     joerg 	case 0x90:
   4510   1.1     joerg 		/* nop */
   4511   1.1     joerg 		break;
   4512   1.1     joerg 	case 0x91:
   4513   1.1     joerg 		x86emuOp_xchg_word_AX_CX(emu);
   4514   1.1     joerg 		break;
   4515   1.1     joerg 	case 0x92:
   4516   1.1     joerg 		x86emuOp_xchg_word_AX_DX(emu);
   4517   1.1     joerg 		break;
   4518   1.1     joerg 	case 0x93:
   4519   1.1     joerg 		x86emuOp_xchg_word_AX_BX(emu);
   4520   1.1     joerg 		break;
   4521   1.1     joerg 	case 0x94:
   4522   1.1     joerg 		x86emuOp_xchg_word_AX_SP(emu);
   4523   1.1     joerg 		break;
   4524   1.1     joerg 	case 0x95:
   4525   1.1     joerg 		x86emuOp_xchg_word_AX_BP(emu);
   4526   1.1     joerg 		break;
   4527   1.1     joerg 	case 0x96:
   4528   1.1     joerg 		x86emuOp_xchg_word_AX_SI(emu);
   4529   1.1     joerg 		break;
   4530   1.1     joerg 	case 0x97:
   4531   1.1     joerg 		x86emuOp_xchg_word_AX_DI(emu);
   4532   1.1     joerg 		break;
   4533   1.1     joerg 
   4534   1.1     joerg 	case 0x98:
   4535   1.1     joerg 		x86emuOp_cbw(emu);
   4536   1.1     joerg 		break;
   4537   1.1     joerg 	case 0x99:
   4538   1.1     joerg 		x86emuOp_cwd(emu);
   4539   1.1     joerg 		break;
   4540   1.1     joerg 	case 0x9a:
   4541   1.1     joerg 		x86emuOp_call_far_IMM(emu);
   4542   1.1     joerg 		break;
   4543   1.1     joerg 	case 0x9b:
   4544   1.1     joerg 		/* wait */
   4545   1.1     joerg 		break;
   4546   1.1     joerg 	case 0x9c:
   4547   1.1     joerg 		x86emuOp_pushf_word(emu);
   4548   1.1     joerg 		break;
   4549   1.1     joerg 	case 0x9d:
   4550   1.1     joerg 		x86emuOp_popf_word(emu);
   4551   1.1     joerg 		break;
   4552   1.1     joerg 	case 0x9e:
   4553   1.1     joerg 		x86emuOp_sahf(emu);
   4554   1.1     joerg 		break;
   4555   1.1     joerg 	case 0x9f:
   4556   1.1     joerg 		x86emuOp_lahf(emu);
   4557   1.1     joerg 		break;
   4558   1.1     joerg 
   4559   1.1     joerg 	case 0xa0:
   4560   1.1     joerg 		x86emuOp_mov_AL_M_IMM(emu);
   4561   1.1     joerg 		break;
   4562   1.1     joerg 	case 0xa1:
   4563   1.1     joerg 		x86emuOp_mov_AX_M_IMM(emu);
   4564   1.1     joerg 		break;
   4565   1.1     joerg 	case 0xa2:
   4566   1.1     joerg 		x86emuOp_mov_M_AL_IMM(emu);
   4567   1.1     joerg 		break;
   4568   1.1     joerg 	case 0xa3:
   4569   1.1     joerg 		x86emuOp_mov_M_AX_IMM(emu);
   4570   1.1     joerg 		break;
   4571   1.1     joerg 	case 0xa4:
   4572   1.1     joerg 		x86emuOp_movs_byte(emu);
   4573   1.1     joerg 		break;
   4574   1.1     joerg 	case 0xa5:
   4575   1.1     joerg 		x86emuOp_movs_word(emu);
   4576   1.1     joerg 		break;
   4577   1.1     joerg 	case 0xa6:
   4578   1.1     joerg 		x86emuOp_cmps_byte(emu);
   4579   1.1     joerg 		break;
   4580   1.1     joerg 	case 0xa7:
   4581   1.1     joerg 		x86emuOp_cmps_word(emu);
   4582   1.1     joerg 		break;
   4583   1.1     joerg 
   4584   1.1     joerg 	case 0xa8:
   4585   1.1     joerg 		test_byte(emu, emu->x86.R_AL, fetch_byte_imm(emu));
   4586   1.1     joerg 		break;
   4587   1.1     joerg 	case 0xa9:
   4588   1.1     joerg 		x86emuOp_test_AX_IMM(emu);
   4589   1.1     joerg 		break;
   4590   1.1     joerg 	case 0xaa:
   4591   1.1     joerg 		x86emuOp_stos_byte(emu);
   4592   1.1     joerg 		break;
   4593   1.1     joerg 	case 0xab:
   4594   1.1     joerg 		x86emuOp_stos_word(emu);
   4595   1.1     joerg 		break;
   4596   1.1     joerg 	case 0xac:
   4597   1.1     joerg 		x86emuOp_lods_byte(emu);
   4598   1.1     joerg 		break;
   4599   1.1     joerg 	case 0xad:
   4600   1.1     joerg 		x86emuOp_lods_word(emu);
   4601   1.1     joerg 		break;
   4602   1.1     joerg 	case 0xae:
   4603   1.1     joerg 		x86emuOp_scas_byte(emu);
   4604   1.1     joerg 		break;
   4605   1.1     joerg 	case 0xaf:
   4606   1.1     joerg 		x86emuOp_scas_word(emu);
   4607   1.1     joerg 		break;
   4608   1.1     joerg 
   4609   1.1     joerg 	case 0xb0:
   4610   1.1     joerg 		emu->x86.R_AL = fetch_byte_imm(emu);
   4611   1.1     joerg 		break;
   4612   1.1     joerg 	case 0xb1:
   4613   1.1     joerg 		emu->x86.R_CL = fetch_byte_imm(emu);
   4614   1.1     joerg 		break;
   4615   1.1     joerg 	case 0xb2:
   4616   1.1     joerg 		emu->x86.R_DL = fetch_byte_imm(emu);
   4617   1.1     joerg 		break;
   4618   1.1     joerg 	case 0xb3:
   4619   1.1     joerg 		emu->x86.R_BL = fetch_byte_imm(emu);
   4620   1.1     joerg 		break;
   4621   1.1     joerg 	case 0xb4:
   4622   1.1     joerg 		emu->x86.R_AH = fetch_byte_imm(emu);
   4623   1.1     joerg 		break;
   4624   1.1     joerg 	case 0xb5:
   4625   1.1     joerg 		emu->x86.R_CH = fetch_byte_imm(emu);
   4626   1.1     joerg 		break;
   4627   1.1     joerg 	case 0xb6:
   4628   1.1     joerg 		emu->x86.R_DH = fetch_byte_imm(emu);
   4629   1.1     joerg 		break;
   4630   1.1     joerg 	case 0xb7:
   4631   1.1     joerg 		emu->x86.R_BH = fetch_byte_imm(emu);
   4632   1.1     joerg 		break;
   4633   1.1     joerg 
   4634   1.1     joerg 	case 0xb8:
   4635   1.1     joerg 		x86emuOp_mov_word_AX_IMM(emu);
   4636   1.1     joerg 		break;
   4637   1.1     joerg 	case 0xb9:
   4638   1.1     joerg 		x86emuOp_mov_word_CX_IMM(emu);
   4639   1.1     joerg 		break;
   4640   1.1     joerg 	case 0xba:
   4641   1.1     joerg 		x86emuOp_mov_word_DX_IMM(emu);
   4642   1.1     joerg 		break;
   4643   1.1     joerg 	case 0xbb:
   4644   1.1     joerg 		x86emuOp_mov_word_BX_IMM(emu);
   4645   1.1     joerg 		break;
   4646   1.1     joerg 	case 0xbc:
   4647   1.1     joerg 		x86emuOp_mov_word_SP_IMM(emu);
   4648   1.1     joerg 		break;
   4649   1.1     joerg 	case 0xbd:
   4650   1.1     joerg 		x86emuOp_mov_word_BP_IMM(emu);
   4651   1.1     joerg 		break;
   4652   1.1     joerg 	case 0xbe:
   4653   1.1     joerg 		x86emuOp_mov_word_SI_IMM(emu);
   4654   1.1     joerg 		break;
   4655   1.1     joerg 	case 0xbf:
   4656   1.1     joerg 		x86emuOp_mov_word_DI_IMM(emu);
   4657   1.1     joerg 		break;
   4658   1.1     joerg 
   4659   1.1     joerg 	case 0xc0:
   4660   1.1     joerg 		x86emuOp_opcC0_byte_RM_MEM(emu);
   4661   1.1     joerg 		break;
   4662   1.1     joerg 	case 0xc1:
   4663   1.1     joerg 		x86emuOp_opcC1_word_RM_MEM(emu);
   4664   1.1     joerg 		break;
   4665   1.1     joerg 	case 0xc2:
   4666   1.1     joerg 		x86emuOp_ret_near_IMM(emu);
   4667   1.1     joerg 		break;
   4668   1.1     joerg 	case 0xc3:
   4669   1.1     joerg 		emu->x86.R_IP = pop_word(emu);
   4670   1.1     joerg 		break;
   4671   1.1     joerg 	case 0xc4:
   4672   1.1     joerg 		common_load_far_pointer(emu, &emu->x86.R_ES);
   4673   1.1     joerg 		break;
   4674   1.1     joerg 	case 0xc5:
   4675   1.1     joerg 		common_load_far_pointer(emu, &emu->x86.R_DS);
   4676   1.1     joerg 		break;
   4677   1.1     joerg 	case 0xc6:
   4678   1.1     joerg 		x86emuOp_mov_byte_RM_IMM(emu);
   4679   1.1     joerg 		break;
   4680   1.1     joerg 	case 0xc7:
   4681   1.1     joerg 		x86emuOp_mov_word_RM_IMM(emu);
   4682   1.1     joerg 		break;
   4683   1.1     joerg 	case 0xc8:
   4684   1.1     joerg 		x86emuOp_enter(emu);
   4685   1.1     joerg 		break;
   4686   1.1     joerg 	case 0xc9:
   4687   1.1     joerg 		x86emuOp_leave(emu);
   4688   1.1     joerg 		break;
   4689   1.1     joerg 	case 0xca:
   4690   1.1     joerg 		x86emuOp_ret_far_IMM(emu);
   4691   1.1     joerg 		break;
   4692   1.1     joerg 	case 0xcb:
   4693   1.1     joerg 		x86emuOp_ret_far(emu);
   4694   1.1     joerg 		break;
   4695   1.1     joerg 	case 0xcc:
   4696   1.1     joerg 		x86emuOp_int3(emu);
   4697   1.1     joerg 		break;
   4698   1.1     joerg 	case 0xcd:
   4699   1.1     joerg 		x86emuOp_int_IMM(emu);
   4700   1.1     joerg 		break;
   4701   1.1     joerg 	case 0xce:
   4702   1.1     joerg 		x86emuOp_into(emu);
   4703   1.1     joerg 		break;
   4704   1.1     joerg 	case 0xcf:
   4705   1.1     joerg 		x86emuOp_iret(emu);
   4706   1.1     joerg 		break;
   4707   1.1     joerg 
   4708   1.1     joerg 	case 0xd0:
   4709   1.1     joerg 		x86emuOp_opcD0_byte_RM_1(emu);
   4710   1.1     joerg 		break;
   4711   1.1     joerg 	case 0xd1:
   4712   1.1     joerg 		x86emuOp_opcD1_word_RM_1(emu);
   4713   1.1     joerg 		break;
   4714   1.1     joerg 	case 0xd2:
   4715   1.1     joerg 		x86emuOp_opcD2_byte_RM_CL(emu);
   4716   1.1     joerg 		break;
   4717   1.1     joerg 	case 0xd3:
   4718   1.1     joerg 		x86emuOp_opcD3_word_RM_CL(emu);
   4719   1.1     joerg 		break;
   4720   1.1     joerg 	case 0xd4:
   4721   1.1     joerg 		x86emuOp_aam(emu);
   4722   1.1     joerg 		break;
   4723   1.1     joerg 	case 0xd5:
   4724   1.1     joerg 		x86emuOp_aad(emu);
   4725   1.1     joerg 		break;
   4726   1.1     joerg 	/* 0xd6 Undocumented SETALC instruction */
   4727   1.1     joerg 	case 0xd7:
   4728   1.1     joerg 		x86emuOp_xlat(emu);
   4729   1.1     joerg 		break;
   4730   1.1     joerg 	case 0xd8:
   4731   1.1     joerg 		x86emuOp_esc_coprocess_d8(emu);
   4732   1.1     joerg 		break;
   4733   1.1     joerg 	case 0xd9:
   4734   1.1     joerg 		x86emuOp_esc_coprocess_d9(emu);
   4735   1.1     joerg 		break;
   4736   1.1     joerg 	case 0xda:
   4737   1.1     joerg 		x86emuOp_esc_coprocess_da(emu);
   4738   1.1     joerg 		break;
   4739   1.1     joerg 	case 0xdb:
   4740   1.1     joerg 		x86emuOp_esc_coprocess_db(emu);
   4741   1.1     joerg 		break;
   4742   1.1     joerg 	case 0xdc:
   4743   1.1     joerg 		x86emuOp_esc_coprocess_dc(emu);
   4744   1.1     joerg 		break;
   4745   1.1     joerg 	case 0xdd:
   4746   1.1     joerg 		x86emuOp_esc_coprocess_dd(emu);
   4747   1.1     joerg 		break;
   4748   1.1     joerg 	case 0xde:
   4749   1.1     joerg 		x86emuOp_esc_coprocess_de(emu);
   4750   1.1     joerg 		break;
   4751   1.1     joerg 	case 0xdf:
   4752   1.1     joerg 		x86emuOp_esc_coprocess_df(emu);
   4753   1.1     joerg 		break;
   4754   1.1     joerg 
   4755   1.1     joerg 	case 0xe0:
   4756   1.1     joerg 		x86emuOp_loopne(emu);
   4757   1.1     joerg 		break;
   4758   1.1     joerg 	case 0xe1:
   4759   1.1     joerg 		x86emuOp_loope(emu);
   4760   1.1     joerg 		break;
   4761   1.1     joerg 	case 0xe2:
   4762   1.1     joerg 		x86emuOp_loop(emu);
   4763   1.1     joerg 		break;
   4764   1.1     joerg 	case 0xe3:
   4765   1.1     joerg 		x86emuOp_jcxz(emu);
   4766   1.1     joerg 		break;
   4767   1.1     joerg 	case 0xe4:
   4768   1.1     joerg 		x86emuOp_in_byte_AL_IMM(emu);
   4769   1.1     joerg 		break;
   4770   1.1     joerg 	case 0xe5:
   4771   1.1     joerg 		x86emuOp_in_word_AX_IMM(emu);
   4772   1.1     joerg 		break;
   4773   1.1     joerg 	case 0xe6:
   4774   1.1     joerg 		x86emuOp_out_byte_IMM_AL(emu);
   4775   1.1     joerg 		break;
   4776   1.1     joerg 	case 0xe7:
   4777   1.1     joerg 		x86emuOp_out_word_IMM_AX(emu);
   4778   1.1     joerg 		break;
   4779   1.1     joerg 
   4780   1.1     joerg 	case 0xe8:
   4781   1.1     joerg 		x86emuOp_call_near_IMM(emu);
   4782   1.1     joerg 		break;
   4783   1.1     joerg 	case 0xe9:
   4784   1.1     joerg 		x86emuOp_jump_near_IMM(emu);
   4785   1.1     joerg 		break;
   4786   1.1     joerg 	case 0xea:
   4787   1.1     joerg 		x86emuOp_jump_far_IMM(emu);
   4788   1.1     joerg 		break;
   4789   1.1     joerg 	case 0xeb:
   4790   1.1     joerg 		x86emuOp_jump_byte_IMM(emu);
   4791   1.1     joerg 		break;
   4792   1.1     joerg 	case 0xec:
   4793   1.1     joerg 		x86emuOp_in_byte_AL_DX(emu);
   4794   1.1     joerg 		break;
   4795   1.1     joerg 	case 0xed:
   4796   1.1     joerg 		x86emuOp_in_word_AX_DX(emu);
   4797   1.1     joerg 		break;
   4798   1.1     joerg 	case 0xee:
   4799   1.1     joerg 		x86emuOp_out_byte_DX_AL(emu);
   4800   1.1     joerg 		break;
   4801   1.1     joerg 	case 0xef:
   4802   1.1     joerg 		x86emuOp_out_word_DX_AX(emu);
   4803   1.1     joerg 		break;
   4804   1.1     joerg 
   4805   1.1     joerg 	case 0xf0:
   4806   1.1     joerg 		x86emuOp_lock(emu);
   4807   1.1     joerg 		break;
   4808   1.1     joerg 	case 0xf2:
   4809   1.1     joerg 		emu->x86.mode |= SYSMODE_PREFIX_REPNE;
   4810   1.1     joerg 		break;
   4811   1.1     joerg 	case 0xf3:
   4812   1.1     joerg 		emu->x86.mode |= SYSMODE_PREFIX_REPE;
   4813   1.1     joerg 		break;
   4814   1.1     joerg 	case 0xf4:
   4815   1.1     joerg 		X86EMU_halt_sys(emu);
   4816   1.1     joerg 		break;
   4817   1.1     joerg 	case 0xf5:
   4818   1.1     joerg 		x86emuOp_cmc(emu);
   4819   1.1     joerg 		break;
   4820   1.1     joerg 	case 0xf6:
   4821   1.1     joerg 		x86emuOp_opcF6_byte_RM(emu);
   4822   1.1     joerg 		break;
   4823   1.1     joerg 	case 0xf7:
   4824   1.1     joerg 		x86emuOp_opcF7_word_RM(emu);
   4825   1.1     joerg 		break;
   4826   1.1     joerg 
   4827   1.1     joerg 	case 0xf8:
   4828   1.1     joerg 		CLEAR_FLAG(F_CF);
   4829   1.1     joerg 		break;
   4830   1.1     joerg 	case 0xf9:
   4831   1.1     joerg 		SET_FLAG(F_CF);
   4832   1.1     joerg 		break;
   4833   1.1     joerg 	case 0xfa:
   4834   1.1     joerg 		CLEAR_FLAG(F_IF);
   4835   1.1     joerg 		break;
   4836   1.1     joerg 	case 0xfb:
   4837   1.1     joerg 		SET_FLAG(F_IF);
   4838   1.1     joerg 		break;
   4839   1.1     joerg 	case 0xfc:
   4840   1.1     joerg 		CLEAR_FLAG(F_DF);
   4841   1.1     joerg 		break;
   4842   1.1     joerg 	case 0xfd:
   4843   1.1     joerg 		SET_FLAG(F_DF);
   4844   1.1     joerg 		break;
   4845   1.1     joerg 	case 0xfe:
   4846   1.1     joerg 		x86emuOp_opcFE_byte_RM(emu);
   4847   1.1     joerg 		break;
   4848   1.1     joerg 	case 0xff:
   4849   1.1     joerg 		x86emuOp_opcFF_word_RM(emu);
   4850   1.1     joerg 		break;
   4851   1.1     joerg 	default:
   4852   1.1     joerg 		X86EMU_halt_sys(emu);
   4853   1.1     joerg 		break;
   4854   1.1     joerg 	}
   4855   1.1     joerg 	if (op1 != 0x26 && op1 != 0x2e && op1 != 0x36 && op1 != 0x3e &&
   4856   1.1     joerg 	    (op1 | 3) != 0x67)
   4857   1.1     joerg 		emu->x86.mode &= ~SYSMODE_CLRMASK;
   4858   1.1     joerg }
   4859   1.1     joerg 
   4860   1.1     joerg static void
   4861   1.1     joerg common_jmp_long(struct X86EMU *emu, bool cond)
   4862   1.1     joerg {
   4863   1.1     joerg 	int16_t target;
   4864   1.1     joerg 
   4865   1.1     joerg 	target = (int16_t) fetch_word_imm(emu);
   4866   1.1     joerg 	target += (int16_t) emu->x86.R_IP;
   4867   1.1     joerg 	if (cond)
   4868   1.1     joerg 		emu->x86.R_IP = (uint16_t) target;
   4869   1.1     joerg }
   4870   1.1     joerg 
   4871   1.1     joerg static void
   4872   1.1     joerg common_set_byte(struct X86EMU *emu, bool cond)
   4873   1.1     joerg {
   4874   1.1     joerg 	uint32_t destoffset;
   4875   1.1     joerg 	uint8_t *destreg, destval;
   4876   1.1     joerg 
   4877   1.1     joerg 	fetch_decode_modrm(emu);
   4878   1.1     joerg 	destval = cond ? 0x01 : 0x00;
   4879   1.1     joerg 	if (emu->cur_mod != 3) {
   4880   1.1     joerg 		destoffset = decode_rl_address(emu);
   4881   1.1     joerg 		store_data_byte(emu, destoffset, destval);
   4882   1.1     joerg 	} else {
   4883   1.1     joerg 		destreg = decode_rl_byte_register(emu);
   4884   1.1     joerg 		*destreg = destval;
   4885   1.1     joerg 	}
   4886   1.1     joerg }
   4887   1.1     joerg 
   4888   1.1     joerg static void
   4889   1.1     joerg common_bitstring32(struct X86EMU *emu, int op)
   4890   1.1     joerg {
   4891   1.1     joerg 	int bit;
   4892   1.1     joerg 	uint32_t srcval, *shiftreg, mask;
   4893   1.1     joerg 
   4894   1.1     joerg 	fetch_decode_modrm(emu);
   4895   1.1     joerg 	shiftreg = decode_rh_long_register(emu);
   4896   1.1     joerg 	srcval = decode_and_fetch_long_disp(emu, (int16_t) *shiftreg >> 5);
   4897   1.1     joerg 	bit = *shiftreg & 0x1F;
   4898   1.1     joerg 	mask =  0x1 << bit;
   4899   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   4900   1.1     joerg 
   4901   1.1     joerg 	switch (op) {
   4902   1.1     joerg 	case 0:
   4903   1.1     joerg 		break;
   4904   1.1     joerg 	case 1:
   4905   1.1     joerg 		write_back_long(emu, srcval | mask);
   4906   1.1     joerg 		break;
   4907   1.1     joerg 	case 2:
   4908   1.1     joerg 		write_back_long(emu, srcval & ~mask);
   4909   1.1     joerg 		break;
   4910   1.1     joerg 	case 3:
   4911   1.1     joerg 		write_back_long(emu, srcval ^ mask);
   4912   1.1     joerg 		break;
   4913   1.1     joerg 	}
   4914   1.1     joerg }
   4915   1.1     joerg 
   4916   1.1     joerg static void
   4917   1.1     joerg common_bitstring16(struct X86EMU *emu, int op)
   4918   1.1     joerg {
   4919   1.1     joerg 	int bit;
   4920   1.1     joerg 	uint16_t srcval, *shiftreg, mask;
   4921   1.1     joerg 
   4922   1.1     joerg 	fetch_decode_modrm(emu);
   4923   1.1     joerg 	shiftreg = decode_rh_word_register(emu);
   4924   1.1     joerg 	srcval = decode_and_fetch_word_disp(emu, (int16_t) *shiftreg >> 4);
   4925   1.1     joerg 	bit = *shiftreg & 0xF;
   4926   1.1     joerg 	mask =  0x1 << bit;
   4927   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   4928   1.1     joerg 
   4929   1.1     joerg 	switch (op) {
   4930   1.1     joerg 	case 0:
   4931   1.1     joerg 		break;
   4932   1.1     joerg 	case 1:
   4933   1.1     joerg 		write_back_word(emu, srcval | mask);
   4934   1.1     joerg 		break;
   4935   1.1     joerg 	case 2:
   4936   1.1     joerg 		write_back_word(emu, srcval & ~mask);
   4937   1.1     joerg 		break;
   4938   1.1     joerg 	case 3:
   4939   1.1     joerg 		write_back_word(emu, srcval ^ mask);
   4940   1.1     joerg 		break;
   4941   1.1     joerg 	}
   4942   1.1     joerg }
   4943   1.1     joerg 
   4944   1.1     joerg static void
   4945   1.1     joerg common_bitstring(struct X86EMU *emu, int op)
   4946   1.1     joerg {
   4947   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   4948   1.1     joerg 		common_bitstring32(emu, op);
   4949   1.1     joerg 	else
   4950   1.1     joerg 		common_bitstring16(emu, op);
   4951   1.1     joerg }
   4952   1.1     joerg 
   4953   1.1     joerg static void
   4954   1.1     joerg common_bitsearch32(struct X86EMU *emu, int diff)
   4955   1.1     joerg {
   4956   1.1     joerg 	uint32_t srcval, *dstreg;
   4957   1.1     joerg 
   4958   1.1     joerg 	fetch_decode_modrm(emu);
   4959   1.1     joerg 	dstreg = decode_rh_long_register(emu);
   4960   1.1     joerg 	srcval = decode_and_fetch_long(emu);
   4961   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   4962   1.1     joerg 	for (*dstreg = 0; *dstreg < 32; *dstreg += diff) {
   4963   1.1     joerg 		if ((srcval >> *dstreg) & 1)
   4964   1.1     joerg 			break;
   4965   1.1     joerg 	}
   4966   1.1     joerg }
   4967   1.1     joerg 
   4968   1.1     joerg static void
   4969   1.1     joerg common_bitsearch16(struct X86EMU *emu, int diff)
   4970   1.1     joerg {
   4971   1.1     joerg 	uint16_t srcval, *dstreg;
   4972   1.1     joerg 
   4973   1.1     joerg 	fetch_decode_modrm(emu);
   4974   1.1     joerg 	dstreg = decode_rh_word_register(emu);
   4975   1.1     joerg 	srcval = decode_and_fetch_word(emu);
   4976   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
   4977   1.1     joerg 	for (*dstreg = 0; *dstreg < 16; *dstreg += diff) {
   4978   1.1     joerg 		if ((srcval >> *dstreg) & 1)
   4979   1.1     joerg 			break;
   4980   1.1     joerg 	}
   4981   1.1     joerg }
   4982   1.1     joerg 
   4983   1.1     joerg static void
   4984   1.1     joerg common_bitsearch(struct X86EMU *emu, int diff)
   4985   1.1     joerg {
   4986   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   4987   1.1     joerg 		common_bitsearch32(emu, diff);
   4988   1.1     joerg 	else
   4989   1.1     joerg 		common_bitsearch16(emu, diff);
   4990   1.1     joerg }
   4991   1.1     joerg 
   4992   1.1     joerg static void
   4993   1.1     joerg common_shift32(struct X86EMU *emu, bool shift_left, bool use_cl)
   4994   1.1     joerg {
   4995   1.1     joerg 	uint8_t shift;
   4996   1.1     joerg 	uint32_t destval, *shiftreg;
   4997   1.1     joerg 
   4998   1.1     joerg 	fetch_decode_modrm(emu);
   4999   1.1     joerg 	shiftreg = decode_rh_long_register(emu);
   5000   1.1     joerg 	if (use_cl) {
   5001   1.1     joerg 		destval = decode_and_fetch_long(emu);
   5002   1.1     joerg 		shift = emu->x86.R_CL;
   5003   1.1     joerg 	} else {
   5004   1.1     joerg 		destval = decode_and_fetch_long_imm8(emu, &shift);
   5005   1.1     joerg 	}
   5006   1.1     joerg 	if (shift_left)
   5007   1.1     joerg 		destval = shld_long(emu, destval, *shiftreg, shift);
   5008   1.1     joerg 	else
   5009   1.1     joerg 		destval = shrd_long(emu, destval, *shiftreg, shift);
   5010   1.1     joerg 	write_back_long(emu, destval);
   5011   1.1     joerg }
   5012   1.1     joerg 
   5013   1.1     joerg static void
   5014   1.1     joerg common_shift16(struct X86EMU *emu, bool shift_left, bool use_cl)
   5015   1.1     joerg {
   5016   1.1     joerg 	uint8_t shift;
   5017   1.1     joerg 	uint16_t destval, *shiftreg;
   5018   1.1     joerg 
   5019   1.1     joerg 	fetch_decode_modrm(emu);
   5020   1.1     joerg 	shiftreg = decode_rh_word_register(emu);
   5021   1.1     joerg 	if (use_cl) {
   5022   1.1     joerg 		destval = decode_and_fetch_word(emu);
   5023   1.1     joerg 		shift = emu->x86.R_CL;
   5024   1.1     joerg 	} else {
   5025   1.1     joerg 		destval = decode_and_fetch_word_imm8(emu, &shift);
   5026   1.1     joerg 	}
   5027   1.1     joerg 	if (shift_left)
   5028   1.1     joerg 		destval = shld_word(emu, destval, *shiftreg, shift);
   5029   1.1     joerg 	else
   5030   1.1     joerg 		destval = shrd_word(emu, destval, *shiftreg, shift);
   5031   1.1     joerg 	write_back_word(emu, destval);
   5032   1.1     joerg }
   5033   1.1     joerg 
   5034   1.1     joerg static void
   5035   1.1     joerg common_shift(struct X86EMU *emu, bool shift_left, bool use_cl)
   5036   1.1     joerg {
   5037   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   5038   1.1     joerg 		common_shift32(emu, shift_left, use_cl);
   5039   1.1     joerg 	else
   5040   1.1     joerg 		common_shift16(emu, shift_left, use_cl);
   5041   1.1     joerg }
   5042   1.1     joerg 
   5043   1.1     joerg /*----------------------------- Implementation ----------------------------*/
   5044   1.1     joerg #define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
   5045   1.1     joerg 
   5046   1.1     joerg /****************************************************************************
   5047   1.1     joerg REMARKS:
   5048   1.1     joerg Handles opcode 0x0f,0x31
   5049   1.1     joerg ****************************************************************************/
   5050   1.1     joerg static void
   5051   1.1     joerg x86emuOp2_rdtsc(struct X86EMU *emu)
   5052   1.1     joerg {
   5053   1.1     joerg 	emu->x86.R_EAX = emu->cur_cycles & 0xffffffff;
   5054   1.1     joerg 	emu->x86.R_EDX = emu->cur_cycles >> 32;
   5055   1.1     joerg }
   5056   1.1     joerg /****************************************************************************
   5057   1.1     joerg REMARKS:
   5058   1.1     joerg Handles opcode 0x0f,0xa0
   5059   1.1     joerg ****************************************************************************/
   5060   1.1     joerg static void
   5061   1.1     joerg x86emuOp2_push_FS(struct X86EMU *emu)
   5062   1.1     joerg {
   5063   1.1     joerg 	push_word(emu, emu->x86.R_FS);
   5064   1.1     joerg }
   5065   1.1     joerg /****************************************************************************
   5066   1.1     joerg REMARKS:
   5067   1.1     joerg Handles opcode 0x0f,0xa1
   5068   1.1     joerg ****************************************************************************/
   5069   1.1     joerg static void
   5070   1.1     joerg x86emuOp2_pop_FS(struct X86EMU *emu)
   5071   1.1     joerg {
   5072   1.1     joerg 	emu->x86.R_FS = pop_word(emu);
   5073   1.1     joerg }
   5074   1.1     joerg /****************************************************************************
   5075   1.1     joerg REMARKS:
   5076   1.4  jmcneill Handles opcode 0x0f,0xa1
   5077   1.4  jmcneill ****************************************************************************/
   5078   1.4  jmcneill #if defined(__i386__) || defined(__amd64__)
   5079   1.4  jmcneill static void
   5080   1.4  jmcneill hw_cpuid(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
   5081   1.4  jmcneill {
   5082   1.4  jmcneill 	__asm__ __volatile__("cpuid"
   5083   1.4  jmcneill 			     : "=a" (*a), "=b" (*b),
   5084   1.4  jmcneill 			       "=c" (*c), "=d" (*d)
   5085   1.4  jmcneill 			     : "a" (*a), "c" (*c)
   5086   1.4  jmcneill 			     : "cc");
   5087   1.4  jmcneill }
   5088   1.4  jmcneill #endif
   5089   1.4  jmcneill static void
   5090   1.4  jmcneill x86emuOp2_cpuid(struct X86EMU *emu)
   5091   1.4  jmcneill {
   5092   1.4  jmcneill #if defined(__i386__) || defined(__amd64__)
   5093   1.4  jmcneill 	hw_cpuid(&emu->x86.R_EAX, &emu->x86.R_EBX, &emu->x86.R_ECX,
   5094   1.4  jmcneill 	    &emu->x86.R_EDX);
   5095   1.4  jmcneill #endif
   5096   1.4  jmcneill 	switch (emu->x86.R_EAX) {
   5097   1.4  jmcneill 	case 0:
   5098   1.4  jmcneill 		emu->x86.R_EAX = 1;
   5099   1.4  jmcneill #if !defined(__i386__) && !defined(__amd64__)
   5100   1.4  jmcneill 		/* "GenuineIntel" */
   5101   1.4  jmcneill 		emu->x86.R_EBX = 0x756e6547;
   5102   1.4  jmcneill 		emu->x86.R_EDX = 0x49656e69;
   5103   1.4  jmcneill 		emu->x86.R_ECX = 0x6c65746e;
   5104   1.4  jmcneill #endif
   5105   1.4  jmcneill 		break;
   5106   1.4  jmcneill 	case 1:
   5107   1.4  jmcneill #if !defined(__i386__) && !defined(__amd64__)
   5108   1.4  jmcneill 		emu->x86.R_EAX = 0x00000480;
   5109   1.4  jmcneill 		emu->x86.R_EBX = emu->x86.R_ECX = 0;
   5110   1.4  jmcneill 		emu->x86.R_EDX = 0x00000002;
   5111   1.4  jmcneill #else
   5112   1.4  jmcneill 		emu->x86.R_EDX &= 0x00000012;
   5113   1.4  jmcneill #endif
   5114   1.4  jmcneill 		break;
   5115   1.4  jmcneill 	default:
   5116   1.4  jmcneill 		emu->x86.R_EAX = emu->x86.R_EBX = emu->x86.R_ECX =
   5117   1.4  jmcneill 		    emu->x86.R_EDX = 0;
   5118   1.4  jmcneill 		break;
   5119   1.4  jmcneill 	}
   5120   1.4  jmcneill }
   5121   1.4  jmcneill /****************************************************************************
   5122   1.4  jmcneill REMARKS:
   5123   1.1     joerg Handles opcode 0x0f,0xa3
   5124   1.1     joerg ****************************************************************************/
   5125   1.1     joerg static void
   5126   1.1     joerg x86emuOp2_bt_R(struct X86EMU *emu)
   5127   1.1     joerg {
   5128   1.1     joerg 	common_bitstring(emu, 0);
   5129   1.1     joerg }
   5130   1.1     joerg /****************************************************************************
   5131   1.1     joerg REMARKS:
   5132   1.1     joerg Handles opcode 0x0f,0xa4
   5133   1.1     joerg ****************************************************************************/
   5134   1.1     joerg static void
   5135   1.1     joerg x86emuOp2_shld_IMM(struct X86EMU *emu)
   5136   1.1     joerg {
   5137   1.1     joerg 	common_shift(emu, true, false);
   5138   1.1     joerg }
   5139   1.1     joerg /****************************************************************************
   5140   1.1     joerg REMARKS:
   5141   1.1     joerg Handles opcode 0x0f,0xa5
   5142   1.1     joerg ****************************************************************************/
   5143   1.1     joerg static void
   5144   1.1     joerg x86emuOp2_shld_CL(struct X86EMU *emu)
   5145   1.1     joerg {
   5146   1.1     joerg 	common_shift(emu, true, true);
   5147   1.1     joerg }
   5148   1.1     joerg /****************************************************************************
   5149   1.1     joerg REMARKS:
   5150   1.1     joerg Handles opcode 0x0f,0xa8
   5151   1.1     joerg ****************************************************************************/
   5152   1.1     joerg static void
   5153   1.1     joerg x86emuOp2_push_GS(struct X86EMU *emu)
   5154   1.1     joerg {
   5155   1.1     joerg 	push_word(emu, emu->x86.R_GS);
   5156   1.1     joerg }
   5157   1.1     joerg /****************************************************************************
   5158   1.1     joerg REMARKS:
   5159   1.1     joerg Handles opcode 0x0f,0xa9
   5160   1.1     joerg ****************************************************************************/
   5161   1.1     joerg static void
   5162   1.1     joerg x86emuOp2_pop_GS(struct X86EMU *emu)
   5163   1.1     joerg {
   5164   1.1     joerg 	emu->x86.R_GS = pop_word(emu);
   5165   1.1     joerg }
   5166   1.1     joerg /****************************************************************************
   5167   1.1     joerg REMARKS:
   5168   1.1     joerg Handles opcode 0x0f,0xab
   5169   1.1     joerg ****************************************************************************/
   5170   1.1     joerg static void
   5171   1.1     joerg x86emuOp2_bts_R(struct X86EMU *emu)
   5172   1.1     joerg {
   5173   1.1     joerg 	common_bitstring(emu, 1);
   5174   1.1     joerg }
   5175   1.1     joerg /****************************************************************************
   5176   1.1     joerg REMARKS:
   5177   1.1     joerg Handles opcode 0x0f,0xac
   5178   1.1     joerg ****************************************************************************/
   5179   1.1     joerg static void
   5180   1.1     joerg x86emuOp2_shrd_IMM(struct X86EMU *emu)
   5181   1.1     joerg {
   5182   1.1     joerg 	common_shift(emu, false, false);
   5183   1.1     joerg }
   5184   1.1     joerg /****************************************************************************
   5185   1.1     joerg REMARKS:
   5186   1.1     joerg Handles opcode 0x0f,0xad
   5187   1.1     joerg ****************************************************************************/
   5188   1.1     joerg static void
   5189   1.1     joerg x86emuOp2_shrd_CL(struct X86EMU *emu)
   5190   1.1     joerg {
   5191   1.1     joerg 	common_shift(emu, false, true);
   5192   1.1     joerg }
   5193   1.1     joerg /****************************************************************************
   5194   1.1     joerg REMARKS:
   5195   1.1     joerg Handles opcode 0x0f,0xaf
   5196   1.1     joerg ****************************************************************************/
   5197   1.1     joerg static void
   5198   1.1     joerg x86emuOp2_32_imul_R_RM(struct X86EMU *emu)
   5199   1.1     joerg {
   5200   1.1     joerg 	uint32_t *destreg, srcval;
   5201   1.1     joerg 	uint64_t res;
   5202   1.1     joerg 
   5203   1.1     joerg 	fetch_decode_modrm(emu);
   5204   1.1     joerg 	destreg = decode_rh_long_register(emu);
   5205   1.1     joerg 	srcval = decode_and_fetch_long(emu);
   5206   1.1     joerg 	res = (int32_t) *destreg * (int32_t)srcval;
   5207   1.1     joerg 	if (res > 0xffffffff) {
   5208   1.1     joerg 		SET_FLAG(F_CF);
   5209   1.1     joerg 		SET_FLAG(F_OF);
   5210   1.1     joerg 	} else {
   5211   1.1     joerg 		CLEAR_FLAG(F_CF);
   5212   1.1     joerg 		CLEAR_FLAG(F_OF);
   5213   1.1     joerg 	}
   5214   1.1     joerg 	*destreg = (uint32_t) res;
   5215   1.1     joerg }
   5216   1.1     joerg 
   5217   1.1     joerg static void
   5218   1.1     joerg x86emuOp2_16_imul_R_RM(struct X86EMU *emu)
   5219   1.1     joerg {
   5220   1.1     joerg 	uint16_t *destreg, srcval;
   5221   1.1     joerg 	uint32_t res;
   5222   1.1     joerg 
   5223   1.1     joerg 	fetch_decode_modrm(emu);
   5224   1.1     joerg 	destreg = decode_rh_word_register(emu);
   5225   1.1     joerg 	srcval = decode_and_fetch_word(emu);
   5226   1.1     joerg 	res = (int16_t) * destreg * (int16_t)srcval;
   5227   1.1     joerg 	if (res > 0xFFFF) {
   5228   1.1     joerg 		SET_FLAG(F_CF);
   5229   1.1     joerg 		SET_FLAG(F_OF);
   5230   1.1     joerg 	} else {
   5231   1.1     joerg 		CLEAR_FLAG(F_CF);
   5232   1.1     joerg 		CLEAR_FLAG(F_OF);
   5233   1.1     joerg 	}
   5234   1.1     joerg 	*destreg = (uint16_t) res;
   5235   1.1     joerg }
   5236   1.1     joerg 
   5237   1.1     joerg static void
   5238   1.1     joerg x86emuOp2_imul_R_RM(struct X86EMU *emu)
   5239   1.1     joerg {
   5240   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   5241   1.1     joerg 		x86emuOp2_32_imul_R_RM(emu);
   5242   1.1     joerg 	else
   5243   1.1     joerg 		x86emuOp2_16_imul_R_RM(emu);
   5244   1.1     joerg }
   5245   1.1     joerg /****************************************************************************
   5246   1.1     joerg REMARKS:
   5247   1.1     joerg Handles opcode 0x0f,0xb2
   5248   1.1     joerg ****************************************************************************/
   5249   1.1     joerg static void
   5250   1.1     joerg x86emuOp2_lss_R_IMM(struct X86EMU *emu)
   5251   1.1     joerg {
   5252   1.1     joerg 	common_load_far_pointer(emu, &emu->x86.R_SS);
   5253   1.1     joerg }
   5254   1.1     joerg /****************************************************************************
   5255   1.1     joerg REMARKS:
   5256   1.1     joerg Handles opcode 0x0f,0xb3
   5257   1.1     joerg ****************************************************************************/
   5258   1.1     joerg static void
   5259   1.1     joerg x86emuOp2_btr_R(struct X86EMU *emu)
   5260   1.1     joerg {
   5261   1.1     joerg 	common_bitstring(emu, 2);
   5262   1.1     joerg }
   5263   1.1     joerg /****************************************************************************
   5264   1.1     joerg REMARKS:
   5265   1.1     joerg Handles opcode 0x0f,0xb4
   5266   1.1     joerg ****************************************************************************/
   5267   1.1     joerg static void
   5268   1.1     joerg x86emuOp2_lfs_R_IMM(struct X86EMU *emu)
   5269   1.1     joerg {
   5270   1.1     joerg 	common_load_far_pointer(emu, &emu->x86.R_FS);
   5271   1.1     joerg }
   5272   1.1     joerg /****************************************************************************
   5273   1.1     joerg REMARKS:
   5274   1.1     joerg Handles opcode 0x0f,0xb5
   5275   1.1     joerg ****************************************************************************/
   5276   1.1     joerg static void
   5277   1.1     joerg x86emuOp2_lgs_R_IMM(struct X86EMU *emu)
   5278   1.1     joerg {
   5279   1.1     joerg 	common_load_far_pointer(emu, &emu->x86.R_GS);
   5280   1.1     joerg }
   5281   1.1     joerg /****************************************************************************
   5282   1.1     joerg REMARKS:
   5283   1.1     joerg Handles opcode 0x0f,0xb6
   5284   1.1     joerg ****************************************************************************/
   5285   1.1     joerg static void
   5286   1.1     joerg x86emuOp2_32_movzx_byte_R_RM(struct X86EMU *emu)
   5287   1.1     joerg {
   5288   1.1     joerg 	uint32_t *destreg;
   5289   1.1     joerg 
   5290   1.1     joerg 	fetch_decode_modrm(emu);
   5291   1.1     joerg 	destreg = decode_rh_long_register(emu);
   5292   1.1     joerg 	*destreg = decode_and_fetch_byte(emu);
   5293   1.1     joerg }
   5294   1.1     joerg 
   5295   1.1     joerg static void
   5296   1.1     joerg x86emuOp2_16_movzx_byte_R_RM(struct X86EMU *emu)
   5297   1.1     joerg {
   5298   1.1     joerg 	uint16_t *destreg;
   5299   1.1     joerg 
   5300   1.1     joerg 	fetch_decode_modrm(emu);
   5301   1.1     joerg 	destreg = decode_rh_word_register(emu);
   5302   1.1     joerg 	*destreg = decode_and_fetch_byte(emu);
   5303   1.1     joerg }
   5304   1.1     joerg 
   5305   1.1     joerg static void
   5306   1.1     joerg x86emuOp2_movzx_byte_R_RM(struct X86EMU *emu)
   5307   1.1     joerg {
   5308   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   5309   1.1     joerg 		x86emuOp2_32_movzx_byte_R_RM(emu);
   5310   1.1     joerg 	else
   5311   1.1     joerg 		x86emuOp2_16_movzx_byte_R_RM(emu);
   5312   1.1     joerg }
   5313   1.1     joerg /****************************************************************************
   5314   1.1     joerg REMARKS:
   5315   1.1     joerg Handles opcode 0x0f,0xb7
   5316   1.1     joerg ****************************************************************************/
   5317   1.1     joerg static void
   5318   1.1     joerg x86emuOp2_movzx_word_R_RM(struct X86EMU *emu)
   5319   1.1     joerg {
   5320   1.1     joerg 	uint32_t *destreg;
   5321   1.1     joerg 
   5322   1.1     joerg 	fetch_decode_modrm(emu);
   5323   1.1     joerg 	destreg = decode_rh_long_register(emu);
   5324   1.1     joerg 	*destreg = decode_and_fetch_word(emu);
   5325   1.1     joerg }
   5326   1.1     joerg /****************************************************************************
   5327   1.1     joerg REMARKS:
   5328   1.1     joerg Handles opcode 0x0f,0xba
   5329   1.1     joerg ****************************************************************************/
   5330   1.1     joerg static void
   5331   1.1     joerg x86emuOp2_32_btX_I(struct X86EMU *emu)
   5332   1.1     joerg {
   5333   1.1     joerg 	int bit;
   5334   1.1     joerg 	uint32_t srcval, mask;
   5335   1.1     joerg 	uint8_t shift;
   5336   1.1     joerg 
   5337   1.1     joerg 	fetch_decode_modrm(emu);
   5338   1.1     joerg 	if (emu->cur_rh < 4)
   5339   1.1     joerg 		X86EMU_halt_sys(emu);
   5340   1.1     joerg 
   5341   1.1     joerg 	srcval = decode_and_fetch_long_imm8(emu, &shift);
   5342   1.1     joerg 	bit = shift & 0x1F;
   5343   1.1     joerg 	mask = (0x1 << bit);
   5344   1.1     joerg 
   5345   1.1     joerg 	switch (emu->cur_rh) {
   5346   1.1     joerg 	case 5:
   5347   1.1     joerg 		write_back_long(emu, srcval | mask);
   5348   1.1     joerg 		break;
   5349   1.1     joerg 	case 6:
   5350   1.1     joerg 		write_back_long(emu, srcval & ~mask);
   5351   1.1     joerg 		break;
   5352   1.1     joerg 	case 7:
   5353   1.1     joerg 		write_back_long(emu, srcval ^ mask);
   5354   1.1     joerg 		break;
   5355   1.1     joerg 	}
   5356   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   5357   1.1     joerg }
   5358   1.1     joerg 
   5359   1.1     joerg static void
   5360   1.1     joerg x86emuOp2_16_btX_I(struct X86EMU *emu)
   5361   1.1     joerg {
   5362   1.1     joerg 	int bit;
   5363   1.1     joerg 
   5364   1.1     joerg 	uint16_t srcval, mask;
   5365   1.1     joerg 	uint8_t shift;
   5366   1.1     joerg 
   5367   1.1     joerg 	fetch_decode_modrm(emu);
   5368   1.1     joerg 	if (emu->cur_rh < 4)
   5369   1.1     joerg 		X86EMU_halt_sys(emu);
   5370   1.1     joerg 
   5371   1.1     joerg 	srcval = decode_and_fetch_word_imm8(emu, &shift);
   5372   1.1     joerg 	bit = shift & 0xF;
   5373   1.1     joerg 	mask = (0x1 << bit);
   5374   1.1     joerg 	switch (emu->cur_rh) {
   5375   1.1     joerg 	case 5:
   5376   1.1     joerg 		write_back_word(emu, srcval | mask);
   5377   1.1     joerg 		break;
   5378   1.1     joerg 	case 6:
   5379   1.1     joerg 		write_back_word(emu, srcval & ~mask);
   5380   1.1     joerg 		break;
   5381   1.1     joerg 	case 7:
   5382   1.1     joerg 		write_back_word(emu, srcval ^ mask);
   5383   1.1     joerg 		break;
   5384   1.1     joerg 	}
   5385   1.1     joerg 	CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
   5386   1.1     joerg }
   5387   1.1     joerg 
   5388   1.1     joerg static void
   5389   1.1     joerg x86emuOp2_btX_I(struct X86EMU *emu)
   5390   1.1     joerg {
   5391   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   5392   1.1     joerg 		x86emuOp2_32_btX_I(emu);
   5393   1.1     joerg 	else
   5394   1.1     joerg 		x86emuOp2_16_btX_I(emu);
   5395   1.1     joerg }
   5396   1.1     joerg /****************************************************************************
   5397   1.1     joerg REMARKS:
   5398   1.1     joerg Handles opcode 0x0f,0xbb
   5399   1.1     joerg ****************************************************************************/
   5400   1.1     joerg static void
   5401   1.1     joerg x86emuOp2_btc_R(struct X86EMU *emu)
   5402   1.1     joerg {
   5403   1.1     joerg 	common_bitstring(emu, 3);
   5404   1.1     joerg }
   5405   1.1     joerg /****************************************************************************
   5406   1.1     joerg REMARKS:
   5407   1.1     joerg Handles opcode 0x0f,0xbc
   5408   1.1     joerg ****************************************************************************/
   5409   1.1     joerg static void
   5410   1.1     joerg x86emuOp2_bsf(struct X86EMU *emu)
   5411   1.1     joerg {
   5412   1.1     joerg 	common_bitsearch(emu, +1);
   5413   1.1     joerg }
   5414   1.1     joerg /****************************************************************************
   5415   1.1     joerg REMARKS:
   5416   1.1     joerg Handles opcode 0x0f,0xbd
   5417   1.1     joerg ****************************************************************************/
   5418   1.1     joerg static void
   5419   1.1     joerg x86emuOp2_bsr(struct X86EMU *emu)
   5420   1.1     joerg {
   5421   1.1     joerg 	common_bitsearch(emu, -1);
   5422   1.1     joerg }
   5423   1.1     joerg /****************************************************************************
   5424   1.1     joerg REMARKS:
   5425   1.1     joerg Handles opcode 0x0f,0xbe
   5426   1.1     joerg ****************************************************************************/
   5427   1.1     joerg static void
   5428   1.1     joerg x86emuOp2_32_movsx_byte_R_RM(struct X86EMU *emu)
   5429   1.1     joerg {
   5430   1.1     joerg 	uint32_t *destreg;
   5431   1.1     joerg 
   5432   1.8     joerg 	fetch_decode_modrm(emu);
   5433   1.1     joerg 	destreg = decode_rh_long_register(emu);
   5434   1.1     joerg 	*destreg = (int32_t)(int8_t)decode_and_fetch_byte(emu);
   5435   1.1     joerg }
   5436   1.1     joerg 
   5437   1.1     joerg static void
   5438   1.1     joerg x86emuOp2_16_movsx_byte_R_RM(struct X86EMU *emu)
   5439   1.1     joerg {
   5440   1.1     joerg 	uint16_t *destreg;
   5441   1.1     joerg 
   5442   1.1     joerg 	fetch_decode_modrm(emu);
   5443   1.1     joerg 	destreg = decode_rh_word_register(emu);
   5444   1.1     joerg 	*destreg = (int16_t)(int8_t)decode_and_fetch_byte(emu);
   5445   1.1     joerg }
   5446   1.1     joerg 
   5447   1.1     joerg static void
   5448   1.1     joerg x86emuOp2_movsx_byte_R_RM(struct X86EMU *emu)
   5449   1.1     joerg {
   5450   1.1     joerg 	if (emu->x86.mode & SYSMODE_PREFIX_DATA)
   5451   1.1     joerg 		x86emuOp2_32_movsx_byte_R_RM(emu);
   5452   1.1     joerg 	else
   5453   1.1     joerg 		x86emuOp2_16_movsx_byte_R_RM(emu);
   5454   1.1     joerg }
   5455   1.1     joerg /****************************************************************************
   5456   1.1     joerg REMARKS:
   5457   1.1     joerg Handles opcode 0x0f,0xbf
   5458   1.1     joerg ****************************************************************************/
   5459   1.1     joerg static void
   5460   1.1     joerg x86emuOp2_movsx_word_R_RM(struct X86EMU *emu)
   5461   1.1     joerg {
   5462   1.1     joerg 	uint32_t *destreg;
   5463   1.1     joerg 
   5464   1.1     joerg 	fetch_decode_modrm(emu);
   5465   1.1     joerg 	destreg = decode_rh_long_register(emu);
   5466   1.1     joerg 	*destreg = (int32_t)(int16_t)decode_and_fetch_word(emu);
   5467   1.1     joerg }
   5468   1.1     joerg 
   5469   1.1     joerg static void
   5470   1.1     joerg X86EMU_exec_two_byte(struct X86EMU * emu)
   5471   1.1     joerg {
   5472   1.1     joerg 	uint8_t op2;
   5473   1.1     joerg 
   5474   1.1     joerg 	op2 = fetch_byte_imm(emu);
   5475   1.1     joerg 
   5476   1.1     joerg 	switch (op2) {
   5477   1.1     joerg 	/* 0x00 Group F (ring 0 PM)      */
   5478   1.1     joerg 	/* 0x01 Group G (ring 0 PM)      */
   5479   1.1     joerg 	/* 0x02 lar (ring 0 PM)          */
   5480   1.1     joerg 	/* 0x03 lsl (ring 0 PM)          */
   5481   1.1     joerg 	/* 0x05 loadall (undocumented)   */
   5482   1.1     joerg 	/* 0x06 clts (ring 0 PM)         */
   5483   1.1     joerg 	/* 0x07 loadall (undocumented)   */
   5484   1.1     joerg 	/* 0x08 invd (ring 0 PM)         */
   5485   1.1     joerg 	/* 0x09 wbinvd (ring 0 PM)       */
   5486   1.1     joerg 
   5487   1.1     joerg 	/* 0x20 mov reg32(op2); break;creg (ring 0 PM) */
   5488   1.1     joerg 	/* 0x21 mov reg32(op2); break;dreg (ring 0 PM) */
   5489   1.1     joerg 	/* 0x22 mov creg(op2); break;reg32 (ring 0 PM) */
   5490   1.1     joerg 	/* 0x23 mov dreg(op2); break;reg32 (ring 0 PM) */
   5491   1.1     joerg 	/* 0x24 mov reg32(op2); break;treg (ring 0 PM) */
   5492   1.1     joerg 	/* 0x26 mov treg(op2); break;reg32 (ring 0 PM) */
   5493   1.1     joerg 
   5494   1.1     joerg 	case 0x31:
   5495   1.1     joerg 		x86emuOp2_rdtsc(emu);
   5496   1.1     joerg 		break;
   5497   1.1     joerg 
   5498   1.1     joerg 	case 0x80:
   5499   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_OF));
   5500   1.1     joerg 		break;
   5501   1.1     joerg 	case 0x81:
   5502   1.1     joerg 		common_jmp_long(emu, !ACCESS_FLAG(F_OF));
   5503   1.1     joerg 		break;
   5504   1.1     joerg 	case 0x82:
   5505   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_CF));
   5506   1.1     joerg 		break;
   5507   1.1     joerg 	case 0x83:
   5508   1.1     joerg 		common_jmp_long(emu, !ACCESS_FLAG(F_CF));
   5509   1.1     joerg 		break;
   5510   1.1     joerg 	case 0x84:
   5511   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_ZF));
   5512   1.1     joerg 		break;
   5513   1.1     joerg 	case 0x85:
   5514   1.1     joerg 		common_jmp_long(emu, !ACCESS_FLAG(F_ZF));
   5515   1.1     joerg 		break;
   5516   1.1     joerg 	case 0x86:
   5517   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
   5518   1.1     joerg 		break;
   5519   1.1     joerg 	case 0x87:
   5520   1.1     joerg 		common_jmp_long(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
   5521   1.1     joerg 		break;
   5522   1.1     joerg 	case 0x88:
   5523   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_SF));
   5524   1.1     joerg 		break;
   5525   1.1     joerg 	case 0x89:
   5526   1.1     joerg 		common_jmp_long(emu, !ACCESS_FLAG(F_SF));
   5527   1.1     joerg 		break;
   5528   1.1     joerg 	case 0x8a:
   5529   1.1     joerg 		common_jmp_long(emu, ACCESS_FLAG(F_PF));
   5530   1.1     joerg 		break;
   5531   1.1     joerg 	case 0x8b:
   5532   1.1     joerg 		common_jmp_long(emu, !ACCESS_FLAG(F_PF));
   5533   1.1     joerg 		break;
   5534   1.1     joerg 	case 0x8c:
   5535   1.1     joerg 		common_jmp_long(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
   5536   1.1     joerg 		break;
   5537   1.1     joerg 	case 0x8d:
   5538   1.1     joerg 		common_jmp_long(emu, !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))));
   5539   1.1     joerg 		break;
   5540   1.1     joerg 	case 0x8e:
   5541   1.1     joerg 		common_jmp_long(emu,
   5542   1.1     joerg 		    (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
   5543   1.1     joerg 		break;
   5544   1.1     joerg 	case 0x8f:
   5545   1.1     joerg 		common_jmp_long(emu,
   5546   1.1     joerg 		    !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)));
   5547   1.1     joerg 		break;
   5548   1.1     joerg 
   5549   1.1     joerg 	case 0x90:
   5550   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_OF));
   5551   1.1     joerg 		break;
   5552   1.1     joerg 	case 0x91:
   5553   1.1     joerg 		common_set_byte(emu, !ACCESS_FLAG(F_OF));
   5554   1.1     joerg 		break;
   5555   1.1     joerg 	case 0x92:
   5556   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_CF));
   5557   1.1     joerg 		break;
   5558   1.1     joerg 	case 0x93:
   5559   1.1     joerg 		common_set_byte(emu, !ACCESS_FLAG(F_CF));
   5560   1.1     joerg 		break;
   5561   1.1     joerg 	case 0x94:
   5562   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_ZF));
   5563   1.1     joerg 		break;
   5564   1.1     joerg 	case 0x95:
   5565   1.1     joerg 		common_set_byte(emu, !ACCESS_FLAG(F_ZF));
   5566   1.1     joerg 		break;
   5567   1.1     joerg 	case 0x96:
   5568   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
   5569   1.1     joerg 		break;
   5570   1.1     joerg 	case 0x97:
   5571   1.1     joerg 		common_set_byte(emu, !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)));
   5572   1.1     joerg 		break;
   5573   1.1     joerg 	case 0x98:
   5574   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_SF));
   5575   1.1     joerg 		break;
   5576   1.1     joerg 	case 0x99:
   5577   1.1     joerg 		common_set_byte(emu, !ACCESS_FLAG(F_SF));
   5578   1.1     joerg 		break;
   5579   1.1     joerg 	case 0x9a:
   5580   1.1     joerg 		common_set_byte(emu, ACCESS_FLAG(F_PF));
   5581   1.1     joerg 		break;
   5582   1.1     joerg 	case 0x9b:
   5583   1.1     joerg 		common_set_byte(emu, !ACCESS_FLAG(F_PF));
   5584   1.1     joerg 		break;
   5585   1.1     joerg 	case 0x9c:
   5586   1.1     joerg 		common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
   5587   1.1     joerg 		break;
   5588   1.1     joerg 	case 0x9d:
   5589   1.1     joerg 		common_set_byte(emu, xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
   5590   1.1     joerg 		break;
   5591   1.1     joerg 	case 0x9e:
   5592   1.1     joerg 		common_set_byte(emu,
   5593   1.1     joerg 		    (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
   5594   1.1     joerg 		    ACCESS_FLAG(F_ZF)));
   5595   1.1     joerg 		break;
   5596   1.1     joerg 	case 0x9f:
   5597   1.1     joerg 		common_set_byte(emu,
   5598   1.1     joerg 		    !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
   5599   1.1     joerg 		    ACCESS_FLAG(F_ZF)));
   5600   1.1     joerg 		break;
   5601   1.1     joerg 
   5602   1.1     joerg 	case 0xa0:
   5603   1.1     joerg 		x86emuOp2_push_FS(emu);
   5604   1.1     joerg 		break;
   5605   1.1     joerg 	case 0xa1:
   5606   1.1     joerg 		x86emuOp2_pop_FS(emu);
   5607   1.1     joerg 		break;
   5608   1.4  jmcneill 	case 0xa2:
   5609   1.4  jmcneill 		x86emuOp2_cpuid(emu);
   5610   1.4  jmcneill 		break;
   5611   1.1     joerg 	case 0xa3:
   5612   1.1     joerg 		x86emuOp2_bt_R(emu);
   5613   1.1     joerg 		break;
   5614   1.1     joerg 	case 0xa4:
   5615   1.1     joerg 		x86emuOp2_shld_IMM(emu);
   5616   1.1     joerg 		break;
   5617   1.1     joerg 	case 0xa5:
   5618   1.1     joerg 		x86emuOp2_shld_CL(emu);
   5619   1.1     joerg 		break;
   5620   1.1     joerg 	case 0xa8:
   5621   1.1     joerg 		x86emuOp2_push_GS(emu);
   5622   1.1     joerg 		break;
   5623   1.1     joerg 	case 0xa9:
   5624   1.1     joerg 		x86emuOp2_pop_GS(emu);
   5625   1.1     joerg 		break;
   5626   1.1     joerg 	case 0xab:
   5627   1.1     joerg 		x86emuOp2_bts_R(emu);
   5628   1.1     joerg 		break;
   5629   1.1     joerg 	case 0xac:
   5630   1.1     joerg 		x86emuOp2_shrd_IMM(emu);
   5631   1.1     joerg 		break;
   5632   1.1     joerg 	case 0xad:
   5633   1.1     joerg 		x86emuOp2_shrd_CL(emu);
   5634   1.1     joerg 		break;
   5635   1.1     joerg 	case 0xaf:
   5636   1.1     joerg 		x86emuOp2_imul_R_RM(emu);
   5637   1.1     joerg 		break;
   5638   1.1     joerg 
   5639   1.1     joerg 	/* 0xb0 TODO: cmpxchg */
   5640   1.1     joerg 	/* 0xb1 TODO: cmpxchg */
   5641   1.1     joerg 	case 0xb2:
   5642   1.1     joerg 		x86emuOp2_lss_R_IMM(emu);
   5643   1.1     joerg 		break;
   5644   1.1     joerg 	case 0xb3:
   5645   1.1     joerg 		x86emuOp2_btr_R(emu);
   5646   1.1     joerg 		break;
   5647   1.1     joerg 	case 0xb4:
   5648   1.1     joerg 		x86emuOp2_lfs_R_IMM(emu);
   5649   1.1     joerg 		break;
   5650   1.1     joerg 	case 0xb5:
   5651   1.1     joerg 		x86emuOp2_lgs_R_IMM(emu);
   5652   1.1     joerg 		break;
   5653   1.1     joerg 	case 0xb6:
   5654   1.1     joerg 		x86emuOp2_movzx_byte_R_RM(emu);
   5655   1.1     joerg 		break;
   5656   1.1     joerg 	case 0xb7:
   5657   1.1     joerg 		x86emuOp2_movzx_word_R_RM(emu);
   5658   1.1     joerg 		break;
   5659   1.1     joerg 	case 0xba:
   5660   1.1     joerg 		x86emuOp2_btX_I(emu);
   5661   1.1     joerg 		break;
   5662   1.1     joerg 	case 0xbb:
   5663   1.1     joerg 		x86emuOp2_btc_R(emu);
   5664   1.1     joerg 		break;
   5665   1.1     joerg 	case 0xbc:
   5666   1.1     joerg 		x86emuOp2_bsf(emu);
   5667   1.1     joerg 		break;
   5668   1.1     joerg 	case 0xbd:
   5669   1.1     joerg 		x86emuOp2_bsr(emu);
   5670   1.1     joerg 		break;
   5671   1.1     joerg 	case 0xbe:
   5672   1.1     joerg 		x86emuOp2_movsx_byte_R_RM(emu);
   5673   1.1     joerg 		break;
   5674   1.1     joerg 	case 0xbf:
   5675   1.1     joerg 		x86emuOp2_movsx_word_R_RM(emu);
   5676   1.1     joerg 		break;
   5677   1.1     joerg 
   5678   1.1     joerg 	/* 0xc0 TODO: xadd */
   5679   1.1     joerg 	/* 0xc1 TODO: xadd */
   5680   1.1     joerg 	/* 0xc8 TODO: bswap */
   5681   1.1     joerg 	/* 0xc9 TODO: bswap */
   5682   1.1     joerg 	/* 0xca TODO: bswap */
   5683   1.1     joerg 	/* 0xcb TODO: bswap */
   5684   1.1     joerg 	/* 0xcc TODO: bswap */
   5685   1.1     joerg 	/* 0xcd TODO: bswap */
   5686   1.1     joerg 	/* 0xce TODO: bswap */
   5687   1.1     joerg 	/* 0xcf TODO: bswap */
   5688   1.1     joerg 
   5689   1.1     joerg 	default:
   5690   1.1     joerg 		X86EMU_halt_sys(emu);
   5691   1.1     joerg 		break;
   5692   1.1     joerg 	}
   5693   1.1     joerg }
   5694   1.1     joerg 
   5695   1.1     joerg /*
   5696   1.1     joerg * Carry Chain Calculation
   5697   1.1     joerg *
   5698   1.1     joerg * This represents a somewhat expensive calculation which is
   5699   1.1     joerg * apparently required to emulate the setting of the OF and AF flag.
   5700   1.1     joerg * The latter is not so important, but the former is.  The overflow
   5701   1.1     joerg * flag is the XOR of the top two bits of the carry chain for an
   5702   1.1     joerg * addition (similar for subtraction).  Since we do not want to
   5703   1.1     joerg * simulate the addition in a bitwise manner, we try to calculate the
   5704   1.1     joerg * carry chain given the two operands and the result.
   5705   1.1     joerg *
   5706   1.1     joerg * So, given the following table, which represents the addition of two
   5707   1.1     joerg * bits, we can derive a formula for the carry chain.
   5708   1.1     joerg *
   5709   1.1     joerg * a   b   cin   r     cout
   5710   1.1     joerg * 0   0   0     0     0
   5711   1.1     joerg * 0   0   1     1     0
   5712   1.1     joerg * 0   1   0     1     0
   5713   1.1     joerg * 0   1   1     0     1
   5714   1.1     joerg * 1   0   0     1     0
   5715   1.1     joerg * 1   0   1     0     1
   5716   1.1     joerg * 1   1   0     0     1
   5717   1.1     joerg * 1   1   1     1     1
   5718   1.1     joerg *
   5719   1.1     joerg * Construction of table for cout:
   5720   1.1     joerg *
   5721   1.1     joerg * ab
   5722   1.1     joerg * r  \  00   01   11  10
   5723   1.1     joerg * |------------------
   5724   1.1     joerg * 0  |   0    1    1   1
   5725   1.1     joerg * 1  |   0    0    1   0
   5726   1.1     joerg *
   5727   1.1     joerg * By inspection, one gets:  cc = ab +  r'(a + b)
   5728   1.1     joerg *
   5729   1.1     joerg * That represents alot of operations, but NO CHOICE....
   5730   1.1     joerg *
   5731   1.1     joerg * Borrow Chain Calculation.
   5732   1.1     joerg *
   5733   1.1     joerg * The following table represents the subtraction of two bits, from
   5734   1.1     joerg * which we can derive a formula for the borrow chain.
   5735   1.1     joerg *
   5736   1.1     joerg * a   b   bin   r     bout
   5737   1.1     joerg * 0   0   0     0     0
   5738   1.1     joerg * 0   0   1     1     1
   5739   1.1     joerg * 0   1   0     1     1
   5740   1.1     joerg * 0   1   1     0     1
   5741   1.1     joerg * 1   0   0     1     0
   5742   1.1     joerg * 1   0   1     0     0
   5743   1.1     joerg * 1   1   0     0     0
   5744   1.1     joerg * 1   1   1     1     1
   5745   1.1     joerg *
   5746   1.1     joerg * Construction of table for cout:
   5747   1.1     joerg *
   5748   1.1     joerg * ab
   5749   1.1     joerg * r  \  00   01   11  10
   5750   1.1     joerg * |------------------
   5751   1.1     joerg * 0  |   0    1    0   0
   5752   1.1     joerg * 1  |   1    1    1   0
   5753   1.1     joerg *
   5754   1.1     joerg * By inspection, one gets:  bc = a'b +  r(a' + b)
   5755   1.1     joerg *
   5756   1.1     joerg ****************************************************************************/
   5757   1.1     joerg 
   5758   1.1     joerg /*------------------------- Global Variables ------------------------------*/
   5759   1.1     joerg 
   5760   1.1     joerg static uint32_t x86emu_parity_tab[8] =
   5761   1.1     joerg {
   5762   1.1     joerg 	0x96696996,
   5763   1.1     joerg 	0x69969669,
   5764   1.1     joerg 	0x69969669,
   5765   1.1     joerg 	0x96696996,
   5766   1.1     joerg 	0x69969669,
   5767   1.1     joerg 	0x96696996,
   5768   1.1     joerg 	0x96696996,
   5769   1.1     joerg 	0x69969669,
   5770   1.1     joerg };
   5771   1.1     joerg #define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
   5772   1.1     joerg #define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)
   5773   1.1     joerg 
   5774   1.1     joerg /****************************************************************************
   5775   1.1     joerg REMARKS:
   5776   1.1     joerg Implements the AAA instruction and side effects.
   5777   1.1     joerg ****************************************************************************/
   5778   1.1     joerg static uint16_t
   5779   1.1     joerg aaa_word(struct X86EMU *emu, uint16_t d)
   5780   1.1     joerg {
   5781   1.1     joerg 	uint16_t res;
   5782   1.1     joerg 	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
   5783   1.1     joerg 		d += 0x6;
   5784   1.1     joerg 		d += 0x100;
   5785   1.1     joerg 		SET_FLAG(F_AF);
   5786   1.1     joerg 		SET_FLAG(F_CF);
   5787   1.1     joerg 	} else {
   5788   1.1     joerg 		CLEAR_FLAG(F_CF);
   5789   1.1     joerg 		CLEAR_FLAG(F_AF);
   5790   1.1     joerg 	}
   5791   1.1     joerg 	res = (uint16_t) (d & 0xFF0F);
   5792   1.1     joerg 	CLEAR_FLAG(F_SF);
   5793   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   5794   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5795   1.1     joerg 	return res;
   5796   1.1     joerg }
   5797   1.1     joerg /****************************************************************************
   5798   1.1     joerg REMARKS:
   5799   1.1     joerg Implements the AAA instruction and side effects.
   5800   1.1     joerg ****************************************************************************/
   5801   1.1     joerg static uint16_t
   5802   1.1     joerg aas_word(struct X86EMU *emu, uint16_t d)
   5803   1.1     joerg {
   5804   1.1     joerg 	uint16_t res;
   5805   1.1     joerg 	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
   5806   1.1     joerg 		d -= 0x6;
   5807   1.1     joerg 		d -= 0x100;
   5808   1.1     joerg 		SET_FLAG(F_AF);
   5809   1.1     joerg 		SET_FLAG(F_CF);
   5810   1.1     joerg 	} else {
   5811   1.1     joerg 		CLEAR_FLAG(F_CF);
   5812   1.1     joerg 		CLEAR_FLAG(F_AF);
   5813   1.1     joerg 	}
   5814   1.1     joerg 	res = (uint16_t) (d & 0xFF0F);
   5815   1.1     joerg 	CLEAR_FLAG(F_SF);
   5816   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   5817   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5818   1.1     joerg 	return res;
   5819   1.1     joerg }
   5820   1.1     joerg /****************************************************************************
   5821   1.1     joerg REMARKS:
   5822   1.1     joerg Implements the AAD instruction and side effects.
   5823   1.1     joerg ****************************************************************************/
   5824   1.1     joerg static uint16_t
   5825   1.1     joerg aad_word(struct X86EMU *emu, uint16_t d)
   5826   1.1     joerg {
   5827   1.1     joerg 	uint16_t l;
   5828   1.1     joerg 	uint8_t hb, lb;
   5829   1.1     joerg 
   5830   1.1     joerg 	hb = (uint8_t) ((d >> 8) & 0xff);
   5831   1.1     joerg 	lb = (uint8_t) ((d & 0xff));
   5832   1.1     joerg 	l = (uint16_t) ((lb + 10 * hb) & 0xFF);
   5833   1.1     joerg 
   5834   1.1     joerg 	CLEAR_FLAG(F_CF);
   5835   1.1     joerg 	CLEAR_FLAG(F_AF);
   5836   1.1     joerg 	CLEAR_FLAG(F_OF);
   5837   1.1     joerg 	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
   5838   1.1     joerg 	CONDITIONAL_SET_FLAG(l == 0, F_ZF);
   5839   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
   5840   1.1     joerg 	return l;
   5841   1.1     joerg }
   5842   1.1     joerg /****************************************************************************
   5843   1.1     joerg REMARKS:
   5844   1.1     joerg Implements the AAM instruction and side effects.
   5845   1.1     joerg ****************************************************************************/
   5846   1.1     joerg static uint16_t
   5847   1.1     joerg aam_word(struct X86EMU *emu, uint8_t d)
   5848   1.1     joerg {
   5849   1.1     joerg 	uint16_t h, l;
   5850   1.1     joerg 
   5851   1.1     joerg 	h = (uint16_t) (d / 10);
   5852   1.1     joerg 	l = (uint16_t) (d % 10);
   5853   1.1     joerg 	l |= (uint16_t) (h << 8);
   5854   1.1     joerg 
   5855   1.1     joerg 	CLEAR_FLAG(F_CF);
   5856   1.1     joerg 	CLEAR_FLAG(F_AF);
   5857   1.1     joerg 	CLEAR_FLAG(F_OF);
   5858   1.1     joerg 	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
   5859   1.1     joerg 	CONDITIONAL_SET_FLAG(l == 0, F_ZF);
   5860   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
   5861   1.1     joerg 	return l;
   5862   1.1     joerg }
   5863   1.1     joerg /****************************************************************************
   5864   1.1     joerg REMARKS:
   5865   1.1     joerg Implements the ADC instruction and side effects.
   5866   1.1     joerg ****************************************************************************/
   5867   1.1     joerg static uint8_t
   5868   1.1     joerg adc_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   5869   1.1     joerg {
   5870   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   5871   1.1     joerg 	uint32_t cc;
   5872   1.1     joerg 
   5873   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   5874   1.1     joerg 		res = 1 + d + s;
   5875   1.1     joerg 	else
   5876   1.1     joerg 		res = d + s;
   5877   1.1     joerg 
   5878   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
   5879   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   5880   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   5881   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5882   1.1     joerg 
   5883   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   5884   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   5885   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
   5886   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   5887   1.1     joerg 	return (uint8_t) res;
   5888   1.1     joerg }
   5889   1.1     joerg /****************************************************************************
   5890   1.1     joerg REMARKS:
   5891   1.1     joerg Implements the ADC instruction and side effects.
   5892   1.1     joerg ****************************************************************************/
   5893   1.1     joerg static uint16_t
   5894   1.1     joerg adc_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   5895   1.1     joerg {
   5896   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   5897   1.1     joerg 	uint32_t cc;
   5898   1.1     joerg 
   5899   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   5900   1.1     joerg 		res = 1 + d + s;
   5901   1.1     joerg 	else
   5902   1.1     joerg 		res = d + s;
   5903   1.1     joerg 
   5904   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
   5905   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   5906   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   5907   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5908   1.1     joerg 
   5909   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   5910   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   5911   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
   5912   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   5913   1.1     joerg 	return (uint16_t) res;
   5914   1.1     joerg }
   5915   1.1     joerg /****************************************************************************
   5916   1.1     joerg REMARKS:
   5917   1.1     joerg Implements the ADC instruction and side effects.
   5918   1.1     joerg ****************************************************************************/
   5919   1.1     joerg static uint32_t
   5920   1.1     joerg adc_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   5921   1.1     joerg {
   5922   1.1     joerg 	uint32_t lo;	/* all operands in native machine order */
   5923   1.1     joerg 	uint32_t hi;
   5924   1.1     joerg 	uint32_t res;
   5925   1.1     joerg 	uint32_t cc;
   5926   1.1     joerg 
   5927   1.1     joerg 	if (ACCESS_FLAG(F_CF)) {
   5928   1.1     joerg 		lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
   5929   1.1     joerg 		res = 1 + d + s;
   5930   1.1     joerg 	} else {
   5931   1.1     joerg 		lo = (d & 0xFFFF) + (s & 0xFFFF);
   5932   1.1     joerg 		res = d + s;
   5933   1.1     joerg 	}
   5934   1.1     joerg 	hi = (lo >> 16) + (d >> 16) + (s >> 16);
   5935   1.1     joerg 
   5936   1.1     joerg 	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
   5937   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   5938   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   5939   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5940   1.1     joerg 
   5941   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   5942   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   5943   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
   5944   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   5945   1.1     joerg 	return res;
   5946   1.1     joerg }
   5947   1.1     joerg /****************************************************************************
   5948   1.1     joerg REMARKS:
   5949   1.1     joerg Implements the ADD instruction and side effects.
   5950   1.1     joerg ****************************************************************************/
   5951   1.1     joerg static uint8_t
   5952   1.1     joerg add_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   5953   1.1     joerg {
   5954   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   5955   1.1     joerg 	uint32_t cc;
   5956   1.1     joerg 
   5957   1.1     joerg 	res = d + s;
   5958   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
   5959   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   5960   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   5961   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5962   1.1     joerg 
   5963   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   5964   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   5965   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
   5966   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   5967   1.1     joerg 	return (uint8_t) res;
   5968   1.1     joerg }
   5969   1.1     joerg /****************************************************************************
   5970   1.1     joerg REMARKS:
   5971   1.1     joerg Implements the ADD instruction and side effects.
   5972   1.1     joerg ****************************************************************************/
   5973   1.1     joerg static uint16_t
   5974   1.1     joerg add_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   5975   1.1     joerg {
   5976   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   5977   1.1     joerg 	uint32_t cc;
   5978   1.1     joerg 
   5979   1.1     joerg 	res = d + s;
   5980   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
   5981   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   5982   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   5983   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   5984   1.1     joerg 
   5985   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   5986   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   5987   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
   5988   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   5989   1.1     joerg 	return (uint16_t) res;
   5990   1.1     joerg }
   5991   1.1     joerg /****************************************************************************
   5992   1.1     joerg REMARKS:
   5993   1.1     joerg Implements the ADD instruction and side effects.
   5994   1.1     joerg ****************************************************************************/
   5995   1.1     joerg static uint32_t
   5996   1.1     joerg add_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   5997   1.1     joerg {
   5998   1.1     joerg 	uint32_t lo;	/* all operands in native machine order */
   5999   1.1     joerg 	uint32_t hi;
   6000   1.1     joerg 	uint32_t res;
   6001   1.1     joerg 	uint32_t cc;
   6002   1.1     joerg 
   6003   1.1     joerg 	lo = (d & 0xFFFF) + (s & 0xFFFF);
   6004   1.1     joerg 	res = d + s;
   6005   1.1     joerg 	hi = (lo >> 16) + (d >> 16) + (s >> 16);
   6006   1.1     joerg 
   6007   1.1     joerg 	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
   6008   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   6009   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6010   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6011   1.1     joerg 
   6012   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   6013   1.1     joerg 	cc = (s & d) | ((~res) & (s | d));
   6014   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
   6015   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   6016   1.1     joerg 
   6017   1.1     joerg 	return res;
   6018   1.1     joerg }
   6019   1.1     joerg /****************************************************************************
   6020   1.1     joerg REMARKS:
   6021   1.1     joerg Implements the AND instruction and side effects.
   6022   1.1     joerg ****************************************************************************/
   6023   1.1     joerg static uint8_t
   6024   1.1     joerg and_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6025   1.1     joerg {
   6026   1.1     joerg 	uint8_t res;	/* all operands in native machine order */
   6027   1.1     joerg 
   6028   1.1     joerg 	res = d & s;
   6029   1.1     joerg 
   6030   1.1     joerg 	/* set the flags  */
   6031   1.1     joerg 	CLEAR_FLAG(F_OF);
   6032   1.1     joerg 	CLEAR_FLAG(F_CF);
   6033   1.1     joerg 	CLEAR_FLAG(F_AF);
   6034   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6035   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6036   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
   6037   1.1     joerg 	return res;
   6038   1.1     joerg }
   6039   1.1     joerg /****************************************************************************
   6040   1.1     joerg REMARKS:
   6041   1.1     joerg Implements the AND instruction and side effects.
   6042   1.1     joerg ****************************************************************************/
   6043   1.1     joerg static uint16_t
   6044   1.1     joerg and_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   6045   1.1     joerg {
   6046   1.1     joerg 	uint16_t res;	/* all operands in native machine order */
   6047   1.1     joerg 
   6048   1.1     joerg 	res = d & s;
   6049   1.1     joerg 
   6050   1.1     joerg 	/* set the flags  */
   6051   1.1     joerg 	CLEAR_FLAG(F_OF);
   6052   1.1     joerg 	CLEAR_FLAG(F_CF);
   6053   1.1     joerg 	CLEAR_FLAG(F_AF);
   6054   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6055   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6056   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6057   1.1     joerg 	return res;
   6058   1.1     joerg }
   6059   1.1     joerg /****************************************************************************
   6060   1.1     joerg REMARKS:
   6061   1.1     joerg Implements the AND instruction and side effects.
   6062   1.1     joerg ****************************************************************************/
   6063   1.1     joerg static uint32_t
   6064   1.1     joerg and_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   6065   1.1     joerg {
   6066   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6067   1.1     joerg 
   6068   1.1     joerg 	res = d & s;
   6069   1.1     joerg 
   6070   1.1     joerg 	/* set the flags  */
   6071   1.1     joerg 	CLEAR_FLAG(F_OF);
   6072   1.1     joerg 	CLEAR_FLAG(F_CF);
   6073   1.1     joerg 	CLEAR_FLAG(F_AF);
   6074   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6075   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6076   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6077   1.1     joerg 	return res;
   6078   1.1     joerg }
   6079   1.1     joerg /****************************************************************************
   6080   1.1     joerg REMARKS:
   6081   1.1     joerg Implements the CMP instruction and side effects.
   6082   1.1     joerg ****************************************************************************/
   6083   1.1     joerg static uint8_t
   6084   1.1     joerg cmp_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6085   1.1     joerg {
   6086   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6087   1.1     joerg 	uint32_t bc;
   6088   1.1     joerg 
   6089   1.1     joerg 	res = d - s;
   6090   1.1     joerg 	CLEAR_FLAG(F_CF);
   6091   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6092   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   6093   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6094   1.1     joerg 
   6095   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6096   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   6097   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
   6098   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   6099   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6100   1.1     joerg 	return d;
   6101   1.1     joerg }
   6102   1.1     joerg 
   6103   1.1     joerg static void
   6104   1.1     joerg cmp_byte_no_return(struct X86EMU *emu, uint8_t d, uint8_t s)
   6105   1.1     joerg {
   6106   1.1     joerg 	cmp_byte(emu, d, s);
   6107   1.1     joerg }
   6108   1.1     joerg /****************************************************************************
   6109   1.1     joerg REMARKS:
   6110   1.1     joerg Implements the CMP instruction and side effects.
   6111   1.1     joerg ****************************************************************************/
   6112   1.1     joerg static uint16_t
   6113   1.1     joerg cmp_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   6114   1.1     joerg {
   6115   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6116   1.1     joerg 	uint32_t bc;
   6117   1.1     joerg 
   6118   1.1     joerg 	res = d - s;
   6119   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6120   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   6121   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6122   1.1     joerg 
   6123   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6124   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   6125   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
   6126   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   6127   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6128   1.1     joerg 	return d;
   6129   1.1     joerg }
   6130   1.1     joerg 
   6131   1.1     joerg static void
   6132   1.1     joerg cmp_word_no_return(struct X86EMU *emu, uint16_t d, uint16_t s)
   6133   1.1     joerg {
   6134   1.1     joerg 	cmp_word(emu, d, s);
   6135   1.1     joerg }
   6136   1.1     joerg /****************************************************************************
   6137   1.1     joerg REMARKS:
   6138   1.1     joerg Implements the CMP instruction and side effects.
   6139   1.1     joerg ****************************************************************************/
   6140   1.1     joerg static uint32_t
   6141   1.1     joerg cmp_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   6142   1.1     joerg {
   6143   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6144   1.1     joerg 	uint32_t bc;
   6145   1.1     joerg 
   6146   1.1     joerg 	res = d - s;
   6147   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6148   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   6149   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6150   1.1     joerg 
   6151   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6152   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   6153   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
   6154   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   6155   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6156   1.1     joerg 	return d;
   6157   1.1     joerg }
   6158   1.1     joerg 
   6159   1.1     joerg static void
   6160   1.1     joerg cmp_long_no_return(struct X86EMU *emu, uint32_t d, uint32_t s)
   6161   1.1     joerg {
   6162   1.1     joerg 	cmp_long(emu, d, s);
   6163   1.1     joerg }
   6164   1.1     joerg /****************************************************************************
   6165   1.1     joerg REMARKS:
   6166   1.1     joerg Implements the DAA instruction and side effects.
   6167   1.1     joerg ****************************************************************************/
   6168   1.1     joerg static uint8_t
   6169   1.1     joerg daa_byte(struct X86EMU *emu, uint8_t d)
   6170   1.1     joerg {
   6171   1.1     joerg 	uint32_t res = d;
   6172   1.1     joerg 	if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
   6173   1.1     joerg 		res += 6;
   6174   1.1     joerg 		SET_FLAG(F_AF);
   6175   1.1     joerg 	}
   6176   1.1     joerg 	if (res > 0x9F || ACCESS_FLAG(F_CF)) {
   6177   1.1     joerg 		res += 0x60;
   6178   1.1     joerg 		SET_FLAG(F_CF);
   6179   1.1     joerg 	}
   6180   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6181   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
   6182   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6183   1.1     joerg 	return (uint8_t) res;
   6184   1.1     joerg }
   6185   1.1     joerg /****************************************************************************
   6186   1.1     joerg REMARKS:
   6187   1.1     joerg Implements the DAS instruction and side effects.
   6188   1.1     joerg ****************************************************************************/
   6189   1.1     joerg static uint8_t
   6190   1.1     joerg das_byte(struct X86EMU *emu, uint8_t d)
   6191   1.1     joerg {
   6192   1.1     joerg 	if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
   6193   1.1     joerg 		d -= 6;
   6194   1.1     joerg 		SET_FLAG(F_AF);
   6195   1.1     joerg 	}
   6196   1.1     joerg 	if (d > 0x9F || ACCESS_FLAG(F_CF)) {
   6197   1.1     joerg 		d -= 0x60;
   6198   1.1     joerg 		SET_FLAG(F_CF);
   6199   1.1     joerg 	}
   6200   1.1     joerg 	CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
   6201   1.1     joerg 	CONDITIONAL_SET_FLAG(d == 0, F_ZF);
   6202   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
   6203   1.1     joerg 	return d;
   6204   1.1     joerg }
   6205   1.1     joerg /****************************************************************************
   6206   1.1     joerg REMARKS:
   6207   1.1     joerg Implements the DEC instruction and side effects.
   6208   1.1     joerg ****************************************************************************/
   6209   1.1     joerg static uint8_t
   6210   1.1     joerg dec_byte(struct X86EMU *emu, uint8_t d)
   6211   1.1     joerg {
   6212   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6213   1.1     joerg 	uint32_t bc;
   6214   1.1     joerg 
   6215   1.1     joerg 	res = d - 1;
   6216   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6217   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   6218   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6219   1.1     joerg 
   6220   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6221   1.1     joerg 	/* based on sub_byte, uses s==1.  */
   6222   1.1     joerg 	bc = (res & (~d | 1)) | (~d & 1);
   6223   1.1     joerg 	/* carry flag unchanged */
   6224   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   6225   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6226   1.1     joerg 	return (uint8_t) res;
   6227   1.1     joerg }
   6228   1.1     joerg /****************************************************************************
   6229   1.1     joerg REMARKS:
   6230   1.1     joerg Implements the DEC instruction and side effects.
   6231   1.1     joerg ****************************************************************************/
   6232   1.1     joerg static uint16_t
   6233   1.1     joerg dec_word(struct X86EMU *emu, uint16_t d)
   6234   1.1     joerg {
   6235   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6236   1.1     joerg 	uint32_t bc;
   6237   1.1     joerg 
   6238   1.1     joerg 	res = d - 1;
   6239   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6240   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   6241   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6242   1.1     joerg 
   6243   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6244   1.1     joerg 	/* based on the sub_byte routine, with s==1 */
   6245   1.1     joerg 	bc = (res & (~d | 1)) | (~d & 1);
   6246   1.1     joerg 	/* carry flag unchanged */
   6247   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   6248   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6249   1.1     joerg 	return (uint16_t) res;
   6250   1.1     joerg }
   6251   1.1     joerg /****************************************************************************
   6252   1.1     joerg REMARKS:
   6253   1.1     joerg Implements the DEC instruction and side effects.
   6254   1.1     joerg ****************************************************************************/
   6255   1.1     joerg static uint32_t
   6256   1.1     joerg dec_long(struct X86EMU *emu, uint32_t d)
   6257   1.1     joerg {
   6258   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6259   1.1     joerg 	uint32_t bc;
   6260   1.1     joerg 
   6261   1.1     joerg 	res = d - 1;
   6262   1.1     joerg 
   6263   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6264   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   6265   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6266   1.1     joerg 
   6267   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   6268   1.1     joerg 	bc = (res & (~d | 1)) | (~d & 1);
   6269   1.1     joerg 	/* carry flag unchanged */
   6270   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   6271   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6272   1.1     joerg 	return res;
   6273   1.1     joerg }
   6274   1.1     joerg /****************************************************************************
   6275   1.1     joerg REMARKS:
   6276   1.1     joerg Implements the INC instruction and side effects.
   6277   1.1     joerg ****************************************************************************/
   6278   1.1     joerg static uint8_t
   6279   1.1     joerg inc_byte(struct X86EMU *emu, uint8_t d)
   6280   1.1     joerg {
   6281   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6282   1.1     joerg 	uint32_t cc;
   6283   1.1     joerg 
   6284   1.1     joerg 	res = d + 1;
   6285   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   6286   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6287   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6288   1.1     joerg 
   6289   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   6290   1.1     joerg 	cc = ((1 & d) | (~res)) & (1 | d);
   6291   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
   6292   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   6293   1.1     joerg 	return (uint8_t) res;
   6294   1.1     joerg }
   6295   1.1     joerg /****************************************************************************
   6296   1.1     joerg REMARKS:
   6297   1.1     joerg Implements the INC instruction and side effects.
   6298   1.1     joerg ****************************************************************************/
   6299   1.1     joerg static uint16_t
   6300   1.1     joerg inc_word(struct X86EMU *emu, uint16_t d)
   6301   1.1     joerg {
   6302   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6303   1.1     joerg 	uint32_t cc;
   6304   1.1     joerg 
   6305   1.1     joerg 	res = d + 1;
   6306   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   6307   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6308   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6309   1.1     joerg 
   6310   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   6311   1.1     joerg 	cc = (1 & d) | ((~res) & (1 | d));
   6312   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
   6313   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   6314   1.1     joerg 	return (uint16_t) res;
   6315   1.1     joerg }
   6316   1.1     joerg /****************************************************************************
   6317   1.1     joerg REMARKS:
   6318   1.1     joerg Implements the INC instruction and side effects.
   6319   1.1     joerg ****************************************************************************/
   6320   1.1     joerg static uint32_t
   6321   1.1     joerg inc_long(struct X86EMU *emu, uint32_t d)
   6322   1.1     joerg {
   6323   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6324   1.1     joerg 	uint32_t cc;
   6325   1.1     joerg 
   6326   1.1     joerg 	res = d + 1;
   6327   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   6328   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6329   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6330   1.1     joerg 
   6331   1.1     joerg 	/* calculate the carry chain  SEE NOTE AT TOP. */
   6332   1.1     joerg 	cc = (1 & d) | ((~res) & (1 | d));
   6333   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
   6334   1.1     joerg 	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
   6335   1.1     joerg 	return res;
   6336   1.1     joerg }
   6337   1.1     joerg /****************************************************************************
   6338   1.1     joerg REMARKS:
   6339   1.1     joerg Implements the OR instruction and side effects.
   6340   1.1     joerg ****************************************************************************/
   6341   1.1     joerg static uint8_t
   6342   1.1     joerg or_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6343   1.1     joerg {
   6344   1.1     joerg 	uint8_t res;	/* all operands in native machine order */
   6345   1.1     joerg 
   6346   1.1     joerg 	res = d | s;
   6347   1.1     joerg 	CLEAR_FLAG(F_OF);
   6348   1.1     joerg 	CLEAR_FLAG(F_CF);
   6349   1.1     joerg 	CLEAR_FLAG(F_AF);
   6350   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6351   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6352   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
   6353   1.1     joerg 	return res;
   6354   1.1     joerg }
   6355   1.1     joerg /****************************************************************************
   6356   1.1     joerg REMARKS:
   6357   1.1     joerg Implements the OR instruction and side effects.
   6358   1.1     joerg ****************************************************************************/
   6359   1.1     joerg static uint16_t
   6360   1.1     joerg or_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   6361   1.1     joerg {
   6362   1.1     joerg 	uint16_t res;	/* all operands in native machine order */
   6363   1.1     joerg 
   6364   1.1     joerg 	res = d | s;
   6365   1.1     joerg 	/* set the carry flag to be bit 8 */
   6366   1.1     joerg 	CLEAR_FLAG(F_OF);
   6367   1.1     joerg 	CLEAR_FLAG(F_CF);
   6368   1.1     joerg 	CLEAR_FLAG(F_AF);
   6369   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6370   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6371   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6372   1.1     joerg 	return res;
   6373   1.1     joerg }
   6374   1.1     joerg /****************************************************************************
   6375   1.1     joerg REMARKS:
   6376   1.1     joerg Implements the OR instruction and side effects.
   6377   1.1     joerg ****************************************************************************/
   6378   1.1     joerg static uint32_t
   6379   1.1     joerg or_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   6380   1.1     joerg {
   6381   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   6382   1.1     joerg 
   6383   1.1     joerg 	res = d | s;
   6384   1.1     joerg 
   6385   1.1     joerg 	/* set the carry flag to be bit 8 */
   6386   1.1     joerg 	CLEAR_FLAG(F_OF);
   6387   1.1     joerg 	CLEAR_FLAG(F_CF);
   6388   1.1     joerg 	CLEAR_FLAG(F_AF);
   6389   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6390   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   6391   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6392   1.1     joerg 	return res;
   6393   1.1     joerg }
   6394   1.1     joerg /****************************************************************************
   6395   1.1     joerg REMARKS:
   6396   1.1     joerg Implements the OR instruction and side effects.
   6397   1.1     joerg ****************************************************************************/
   6398   1.1     joerg static uint8_t
   6399   1.1     joerg neg_byte(struct X86EMU *emu, uint8_t s)
   6400   1.1     joerg {
   6401   1.1     joerg 	uint8_t res;
   6402   1.1     joerg 	uint8_t bc;
   6403   1.1     joerg 
   6404   1.1     joerg 	CONDITIONAL_SET_FLAG(s != 0, F_CF);
   6405   1.1     joerg 	res = (uint8_t) - s;
   6406   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   6407   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6408   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
   6409   1.1     joerg 	/* calculate the borrow chain --- modified such that d=0.
   6410   1.1     joerg 	 * substitutiing d=0 into     bc= res&(~d|s)|(~d&s); (the one used for
   6411   1.1     joerg 	 * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
   6412   1.1     joerg 	 * res&0xfff... == res.  Similarly ~d&s == s.  So the simplified
   6413   1.1     joerg 	 * result is: */
   6414   1.1     joerg 	bc = res | s;
   6415   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   6416   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6417   1.1     joerg 	return res;
   6418   1.1     joerg }
   6419   1.1     joerg /****************************************************************************
   6420   1.1     joerg REMARKS:
   6421   1.1     joerg Implements the OR instruction and side effects.
   6422   1.1     joerg ****************************************************************************/
   6423   1.1     joerg static uint16_t
   6424   1.1     joerg neg_word(struct X86EMU *emu, uint16_t s)
   6425   1.1     joerg {
   6426   1.1     joerg 	uint16_t res;
   6427   1.1     joerg 	uint16_t bc;
   6428   1.1     joerg 
   6429   1.1     joerg 	CONDITIONAL_SET_FLAG(s != 0, F_CF);
   6430   1.1     joerg 	res = (uint16_t) - s;
   6431   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   6432   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6433   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6434   1.1     joerg 
   6435   1.1     joerg 	/* calculate the borrow chain --- modified such that d=0.
   6436   1.1     joerg 	 * substitutiing d=0 into     bc= res&(~d|s)|(~d&s); (the one used for
   6437   1.1     joerg 	 * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
   6438   1.1     joerg 	 * res&0xfff... == res.  Similarly ~d&s == s.  So the simplified
   6439   1.1     joerg 	 * result is: */
   6440   1.1     joerg 	bc = res | s;
   6441   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   6442   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6443   1.1     joerg 	return res;
   6444   1.1     joerg }
   6445   1.1     joerg /****************************************************************************
   6446   1.1     joerg REMARKS:
   6447   1.1     joerg Implements the OR instruction and side effects.
   6448   1.1     joerg ****************************************************************************/
   6449   1.1     joerg static uint32_t
   6450   1.1     joerg neg_long(struct X86EMU *emu, uint32_t s)
   6451   1.1     joerg {
   6452   1.1     joerg 	uint32_t res;
   6453   1.1     joerg 	uint32_t bc;
   6454   1.1     joerg 
   6455   1.1     joerg 	CONDITIONAL_SET_FLAG(s != 0, F_CF);
   6456   1.1     joerg 	res = (uint32_t) - s;
   6457   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   6458   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   6459   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6460   1.1     joerg 
   6461   1.1     joerg 	/* calculate the borrow chain --- modified such that d=0.
   6462   1.1     joerg 	 * substitutiing d=0 into     bc= res&(~d|s)|(~d&s); (the one used for
   6463   1.1     joerg 	 * sub) and simplifying, since ~d=0xff..., ~d|s == 0xffff..., and
   6464   1.1     joerg 	 * res&0xfff... == res.  Similarly ~d&s == s.  So the simplified
   6465   1.1     joerg 	 * result is: */
   6466   1.1     joerg 	bc = res | s;
   6467   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   6468   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   6469   1.1     joerg 	return res;
   6470   1.1     joerg }
   6471   1.1     joerg /****************************************************************************
   6472   1.1     joerg REMARKS:
   6473   1.1     joerg Implements the RCL instruction and side effects.
   6474   1.1     joerg ****************************************************************************/
   6475   1.1     joerg static uint8_t
   6476   1.1     joerg rcl_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6477   1.1     joerg {
   6478   1.1     joerg 	unsigned int res, cnt, mask, cf;
   6479   1.1     joerg 
   6480   1.1     joerg 	/* s is the rotate distance.  It varies from 0 - 8. */
   6481   1.1     joerg 	/* have
   6482   1.1     joerg 	 *
   6483   1.1     joerg 	 * CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
   6484   1.1     joerg 	 *
   6485   1.1     joerg 	 * want to rotate through the carry by "s" bits.  We could loop, but
   6486   1.1     joerg 	 * that's inefficient.  So the width is 9, and we split into three
   6487   1.1     joerg 	 * parts:
   6488   1.1     joerg 	 *
   6489   1.1     joerg 	 * The new carry flag   (was B_n) the stuff in B_n-1 .. B_0 the stuff in
   6490   1.1     joerg 	 * B_7 .. B_n+1
   6491   1.1     joerg 	 *
   6492   1.1     joerg 	 * The new rotate is done mod 9, and given this, for a rotation of n bits
   6493   1.1     joerg 	 * (mod 9) the new carry flag is then located n bits from the MSB.
   6494   1.1     joerg 	 * The low part is then shifted up cnt bits, and the high part is or'd
   6495   1.1     joerg 	 * in.  Using CAPS for new values, and lowercase for the original
   6496   1.1     joerg 	 * values, this can be expressed as:
   6497   1.1     joerg 	 *
   6498   1.1     joerg 	 * IF n > 0 1) CF <-  b_(8-n) 2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
   6499   1.1     joerg 	 * 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
   6500   1.1     joerg 	res = d;
   6501   1.1     joerg 	if ((cnt = s % 9) != 0) {
   6502   1.1     joerg 		/* extract the new CARRY FLAG. */
   6503   1.1     joerg 		/* CF <-  b_(8-n)             */
   6504   1.1     joerg 		cf = (d >> (8 - cnt)) & 0x1;
   6505   1.1     joerg 
   6506   1.1     joerg 		/* get the low stuff which rotated into the range B_7 .. B_cnt */
   6507   1.1     joerg 		/* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
   6508   1.1     joerg 		/* note that the right hand side done by the mask */
   6509   1.1     joerg 		res = (d << cnt) & 0xff;
   6510   1.1     joerg 
   6511   1.1     joerg 		/* now the high stuff which rotated around into the positions
   6512   1.1     joerg 		 * B_cnt-2 .. B_0 */
   6513   1.1     joerg 		/* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
   6514   1.1     joerg 		/* shift it downward, 7-(n-2) = 9-n positions. and mask off
   6515   1.1     joerg 		 * the result before or'ing in. */
   6516   1.1     joerg 		mask = (1 << (cnt - 1)) - 1;
   6517   1.1     joerg 		res |= (d >> (9 - cnt)) & mask;
   6518   1.1     joerg 
   6519   1.1     joerg 		/* if the carry flag was set, or it in.  */
   6520   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {	/* carry flag is set */
   6521   1.1     joerg 			/* B_(n-1) <- cf */
   6522   1.1     joerg 			res |= 1 << (cnt - 1);
   6523   1.1     joerg 		}
   6524   1.1     joerg 		/* set the new carry flag, based on the variable "cf" */
   6525   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6526   1.1     joerg 		/* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
   6527   1.1     joerg 		 * the most significant bit.  Blecck. */
   6528   1.1     joerg 		/* parenthesized this expression since it appears to be
   6529   1.1     joerg 		 * causing OF to be misset */
   6530   1.1     joerg 		CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)),
   6531   1.1     joerg 		    F_OF);
   6532   1.1     joerg 
   6533   1.1     joerg 	}
   6534   1.1     joerg 	return (uint8_t) res;
   6535   1.1     joerg }
   6536   1.1     joerg /****************************************************************************
   6537   1.1     joerg REMARKS:
   6538   1.1     joerg Implements the RCL instruction and side effects.
   6539   1.1     joerg ****************************************************************************/
   6540   1.1     joerg static uint16_t
   6541   1.1     joerg rcl_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   6542   1.1     joerg {
   6543   1.1     joerg 	unsigned int res, cnt, mask, cf;
   6544   1.1     joerg 
   6545   1.1     joerg 	res = d;
   6546   1.1     joerg 	if ((cnt = s % 17) != 0) {
   6547   1.1     joerg 		cf = (d >> (16 - cnt)) & 0x1;
   6548   1.1     joerg 		res = (d << cnt) & 0xffff;
   6549   1.1     joerg 		mask = (1 << (cnt - 1)) - 1;
   6550   1.1     joerg 		res |= (d >> (17 - cnt)) & mask;
   6551   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {
   6552   1.1     joerg 			res |= 1 << (cnt - 1);
   6553   1.1     joerg 		}
   6554   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6555   1.1     joerg 		CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)),
   6556   1.1     joerg 		    F_OF);
   6557   1.1     joerg 	}
   6558   1.1     joerg 	return (uint16_t) res;
   6559   1.1     joerg }
   6560   1.1     joerg /****************************************************************************
   6561   1.1     joerg REMARKS:
   6562   1.1     joerg Implements the RCL instruction and side effects.
   6563   1.1     joerg ****************************************************************************/
   6564   1.1     joerg static uint32_t
   6565   1.1     joerg rcl_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   6566   1.1     joerg {
   6567   1.1     joerg 	uint32_t res, cnt, mask, cf;
   6568   1.1     joerg 
   6569   1.1     joerg 	res = d;
   6570   1.1     joerg 	if ((cnt = s % 33) != 0) {
   6571   1.1     joerg 		cf = (d >> (32 - cnt)) & 0x1;
   6572   1.1     joerg 		res = (d << cnt) & 0xffffffff;
   6573   1.1     joerg 		mask = (1 << (cnt - 1)) - 1;
   6574   1.1     joerg 		res |= (d >> (33 - cnt)) & mask;
   6575   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {	/* carry flag is set */
   6576   1.1     joerg 			res |= 1 << (cnt - 1);
   6577   1.1     joerg 		}
   6578   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6579   1.1     joerg 		CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)),
   6580   1.1     joerg 		    F_OF);
   6581   1.1     joerg 	}
   6582   1.1     joerg 	return res;
   6583   1.1     joerg }
   6584   1.1     joerg /****************************************************************************
   6585   1.1     joerg REMARKS:
   6586   1.1     joerg Implements the RCR instruction and side effects.
   6587   1.1     joerg ****************************************************************************/
   6588   1.1     joerg static uint8_t
   6589   1.1     joerg rcr_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6590   1.1     joerg {
   6591   1.1     joerg 	uint32_t res, cnt;
   6592   1.1     joerg 	uint32_t mask, cf, ocf = 0;
   6593   1.1     joerg 
   6594   1.1     joerg 	/* rotate right through carry */
   6595   1.1     joerg 	/* s is the rotate distance.  It varies from 0 - 8. d is the byte
   6596   1.1     joerg 	 * object rotated.
   6597   1.1     joerg 	 *
   6598   1.1     joerg 	 * have
   6599   1.1     joerg 	 *
   6600   1.1     joerg 	 * CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
   6601   1.1     joerg 	 *
   6602   1.1     joerg 	 * The new rotate is done mod 9, and given this, for a rotation of n bits
   6603   1.1     joerg 	 * (mod 9) the new carry flag is then located n bits from the LSB.
   6604   1.1     joerg 	 * The low part is then shifted up cnt bits, and the high part is or'd
   6605   1.1     joerg 	 * in.  Using CAPS for new values, and lowercase for the original
   6606   1.1     joerg 	 * values, this can be expressed as:
   6607   1.1     joerg 	 *
   6608   1.1     joerg 	 * IF n > 0 1) CF <-  b_(n-1) 2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
   6609   1.1     joerg 	 * 3) B_(8-n) <- cf 4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
   6610   1.1     joerg 	res = d;
   6611   1.1     joerg 	if ((cnt = s % 9) != 0) {
   6612   1.1     joerg 		/* extract the new CARRY FLAG. */
   6613   1.1     joerg 		/* CF <-  b_(n-1)              */
   6614   1.1     joerg 		if (cnt == 1) {
   6615   1.1     joerg 			cf = d & 0x1;
   6616   1.1     joerg 			/* note hackery here.  Access_flag(..) evaluates to
   6617   1.1     joerg 			 * either 0 if flag not set non-zero if flag is set.
   6618   1.1     joerg 			 * doing access_flag(..) != 0 casts that into either
   6619   1.1     joerg 			 * 0..1 in any representation of the flags register
   6620   1.1     joerg 			 * (i.e. packed bit array or unpacked.) */
   6621   1.1     joerg 			ocf = ACCESS_FLAG(F_CF) != 0;
   6622   1.1     joerg 		} else
   6623   1.1     joerg 			cf = (d >> (cnt - 1)) & 0x1;
   6624   1.1     joerg 
   6625   1.1     joerg 		/* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
   6626   1.1     joerg 		/* note that the right hand side done by the mask This is
   6627   1.1     joerg 		 * effectively done by shifting the object to the right.  The
   6628   1.1     joerg 		 * result must be masked, in case the object came in and was
   6629   1.1     joerg 		 * treated as a negative number.  Needed??? */
   6630   1.1     joerg 
   6631   1.1     joerg 		mask = (1 << (8 - cnt)) - 1;
   6632   1.1     joerg 		res = (d >> cnt) & mask;
   6633   1.1     joerg 
   6634   1.1     joerg 		/* now the high stuff which rotated around into the positions
   6635   1.1     joerg 		 * B_cnt-2 .. B_0 */
   6636   1.1     joerg 		/* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
   6637   1.1     joerg 		/* shift it downward, 7-(n-2) = 9-n positions. and mask off
   6638   1.1     joerg 		 * the result before or'ing in. */
   6639   1.1     joerg 		res |= (d << (9 - cnt));
   6640   1.1     joerg 
   6641   1.1     joerg 		/* if the carry flag was set, or it in.  */
   6642   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {	/* carry flag is set */
   6643   1.1     joerg 			/* B_(8-n) <- cf */
   6644   1.1     joerg 			res |= 1 << (8 - cnt);
   6645   1.1     joerg 		}
   6646   1.1     joerg 		/* set the new carry flag, based on the variable "cf" */
   6647   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6648   1.1     joerg 		/* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and
   6649   1.1     joerg 		 * the most significant bit.  Blecck. */
   6650   1.1     joerg 		/* parenthesized... */
   6651   1.1     joerg 		if (cnt == 1) {
   6652   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)),
   6653   1.1     joerg 			    F_OF);
   6654   1.1     joerg 		}
   6655   1.1     joerg 	}
   6656   1.1     joerg 	return (uint8_t) res;
   6657   1.1     joerg }
   6658   1.1     joerg /****************************************************************************
   6659   1.1     joerg REMARKS:
   6660   1.1     joerg Implements the RCR instruction and side effects.
   6661   1.1     joerg ****************************************************************************/
   6662   1.1     joerg static uint16_t
   6663   1.1     joerg rcr_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   6664   1.1     joerg {
   6665   1.1     joerg 	uint32_t res, cnt;
   6666   1.1     joerg 	uint32_t mask, cf, ocf = 0;
   6667   1.1     joerg 
   6668   1.1     joerg 	/* rotate right through carry */
   6669   1.1     joerg 	res = d;
   6670   1.1     joerg 	if ((cnt = s % 17) != 0) {
   6671   1.1     joerg 		if (cnt == 1) {
   6672   1.1     joerg 			cf = d & 0x1;
   6673   1.1     joerg 			ocf = ACCESS_FLAG(F_CF) != 0;
   6674   1.1     joerg 		} else
   6675   1.1     joerg 			cf = (d >> (cnt - 1)) & 0x1;
   6676   1.1     joerg 		mask = (1 << (16 - cnt)) - 1;
   6677   1.1     joerg 		res = (d >> cnt) & mask;
   6678   1.1     joerg 		res |= (d << (17 - cnt));
   6679   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {
   6680   1.1     joerg 			res |= 1 << (16 - cnt);
   6681   1.1     joerg 		}
   6682   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6683   1.1     joerg 		if (cnt == 1) {
   6684   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)),
   6685   1.1     joerg 			    F_OF);
   6686   1.1     joerg 		}
   6687   1.1     joerg 	}
   6688   1.1     joerg 	return (uint16_t) res;
   6689   1.1     joerg }
   6690   1.1     joerg /****************************************************************************
   6691   1.1     joerg REMARKS:
   6692   1.1     joerg Implements the RCR instruction and side effects.
   6693   1.1     joerg ****************************************************************************/
   6694   1.1     joerg static uint32_t
   6695   1.1     joerg rcr_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   6696   1.1     joerg {
   6697   1.1     joerg 	uint32_t res, cnt;
   6698   1.1     joerg 	uint32_t mask, cf, ocf = 0;
   6699   1.1     joerg 
   6700   1.1     joerg 	/* rotate right through carry */
   6701   1.1     joerg 	res = d;
   6702   1.1     joerg 	if ((cnt = s % 33) != 0) {
   6703   1.1     joerg 		if (cnt == 1) {
   6704   1.1     joerg 			cf = d & 0x1;
   6705   1.1     joerg 			ocf = ACCESS_FLAG(F_CF) != 0;
   6706   1.1     joerg 		} else
   6707   1.1     joerg 			cf = (d >> (cnt - 1)) & 0x1;
   6708   1.1     joerg 		mask = (1 << (32 - cnt)) - 1;
   6709   1.1     joerg 		res = (d >> cnt) & mask;
   6710   1.1     joerg 		if (cnt != 1)
   6711   1.1     joerg 			res |= (d << (33 - cnt));
   6712   1.1     joerg 		if (ACCESS_FLAG(F_CF)) {	/* carry flag is set */
   6713   1.1     joerg 			res |= 1 << (32 - cnt);
   6714   1.1     joerg 		}
   6715   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   6716   1.1     joerg 		if (cnt == 1) {
   6717   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)),
   6718   1.1     joerg 			    F_OF);
   6719   1.1     joerg 		}
   6720   1.1     joerg 	}
   6721   1.1     joerg 	return res;
   6722   1.1     joerg }
   6723   1.1     joerg /****************************************************************************
   6724   1.1     joerg REMARKS:
   6725   1.1     joerg Implements the ROL instruction and side effects.
   6726   1.1     joerg ****************************************************************************/
   6727   1.1     joerg static uint8_t
   6728   1.1     joerg rol_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6729   1.1     joerg {
   6730   1.1     joerg 	unsigned int res, cnt, mask;
   6731   1.1     joerg 
   6732   1.1     joerg 	/* rotate left */
   6733   1.1     joerg 	/* s is the rotate distance.  It varies from 0 - 8. d is the byte
   6734   1.1     joerg 	 * object rotated.
   6735   1.1     joerg 	 *
   6736   1.1     joerg 	 * have
   6737   1.1     joerg 	 *
   6738   1.1     joerg 	 * CF  B_7 ... B_0
   6739   1.1     joerg 	 *
   6740   1.1     joerg 	 * The new rotate is done mod 8. Much simpler than the "rcl" or "rcr"
   6741   1.1     joerg 	 * operations.
   6742   1.1     joerg 	 *
   6743   1.1     joerg 	 * IF n > 0 1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) 2) B_(n-1) ..
   6744   1.1     joerg 	 * B_(0) <-  b_(7) .. b_(8-n) */
   6745   1.1     joerg 	res = d;
   6746   1.1     joerg 	if ((cnt = s % 8) != 0) {
   6747   1.1     joerg 		/* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
   6748   1.1     joerg 		res = (d << cnt);
   6749   1.1     joerg 
   6750   1.1     joerg 		/* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
   6751   1.1     joerg 		mask = (1 << cnt) - 1;
   6752   1.1     joerg 		res |= (d >> (8 - cnt)) & mask;
   6753   1.1     joerg 
   6754   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6755   1.1     joerg 		 * of the result!!!                               */
   6756   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6757   1.1     joerg 		/* OVERFLOW is set *IFF* s==1, then it is the xor of CF and
   6758   1.1     joerg 		 * the most significant bit.  Blecck. */
   6759   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 &&
   6760   1.1     joerg 		    XOR2((res & 0x1) + ((res >> 6) & 0x2)),
   6761   1.1     joerg 		    F_OF);
   6762   1.1     joerg 	} if (s != 0) {
   6763   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6764   1.1     joerg 		 * of the result!!!                               */
   6765   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6766   1.1     joerg 	}
   6767   1.1     joerg 	return (uint8_t) res;
   6768   1.1     joerg }
   6769   1.1     joerg /****************************************************************************
   6770   1.1     joerg REMARKS:
   6771   1.1     joerg Implements the ROL instruction and side effects.
   6772   1.1     joerg ****************************************************************************/
   6773   1.1     joerg static uint16_t
   6774   1.1     joerg rol_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   6775   1.1     joerg {
   6776   1.1     joerg 	unsigned int res, cnt, mask;
   6777   1.1     joerg 
   6778   1.1     joerg 	res = d;
   6779   1.1     joerg 	if ((cnt = s % 16) != 0) {
   6780   1.1     joerg 		res = (d << cnt);
   6781   1.1     joerg 		mask = (1 << cnt) - 1;
   6782   1.1     joerg 		res |= (d >> (16 - cnt)) & mask;
   6783   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6784   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 &&
   6785   1.1     joerg 		    XOR2((res & 0x1) + ((res >> 14) & 0x2)),
   6786   1.1     joerg 		    F_OF);
   6787   1.1     joerg 	} if (s != 0) {
   6788   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6789   1.1     joerg 		 * of the result!!!                               */
   6790   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6791   1.1     joerg 	}
   6792   1.1     joerg 	return (uint16_t) res;
   6793   1.1     joerg }
   6794   1.1     joerg /****************************************************************************
   6795   1.1     joerg REMARKS:
   6796   1.1     joerg Implements the ROL instruction and side effects.
   6797   1.1     joerg ****************************************************************************/
   6798   1.1     joerg static uint32_t
   6799   1.1     joerg rol_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   6800   1.1     joerg {
   6801   1.1     joerg 	uint32_t res, cnt, mask;
   6802   1.1     joerg 
   6803   1.1     joerg 	res = d;
   6804   1.1     joerg 	if ((cnt = s % 32) != 0) {
   6805   1.1     joerg 		res = (d << cnt);
   6806   1.1     joerg 		mask = (1 << cnt) - 1;
   6807   1.1     joerg 		res |= (d >> (32 - cnt)) & mask;
   6808   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6809   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 &&
   6810   1.1     joerg 		    XOR2((res & 0x1) + ((res >> 30) & 0x2)),
   6811   1.1     joerg 		    F_OF);
   6812   1.1     joerg 	} if (s != 0) {
   6813   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6814   1.1     joerg 		 * of the result!!!                               */
   6815   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
   6816   1.1     joerg 	}
   6817   1.1     joerg 	return res;
   6818   1.1     joerg }
   6819   1.1     joerg /****************************************************************************
   6820   1.1     joerg REMARKS:
   6821   1.1     joerg Implements the ROR instruction and side effects.
   6822   1.1     joerg ****************************************************************************/
   6823   1.1     joerg static uint8_t
   6824   1.1     joerg ror_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6825   1.1     joerg {
   6826   1.1     joerg 	unsigned int res, cnt, mask;
   6827   1.1     joerg 
   6828   1.1     joerg 	/* rotate right */
   6829   1.1     joerg 	/* s is the rotate distance.  It varies from 0 - 8. d is the byte
   6830   1.1     joerg 	 * object rotated.
   6831   1.1     joerg 	 *
   6832   1.1     joerg 	 * have
   6833   1.1     joerg 	 *
   6834   1.1     joerg 	 * B_7 ... B_0
   6835   1.1     joerg 	 *
   6836   1.1     joerg 	 * The rotate is done mod 8.
   6837   1.1     joerg 	 *
   6838   1.1     joerg 	 * IF n > 0 1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) 2) B_(7) ..
   6839   1.1     joerg 	 * B_(8-n) <-  b_(n-1) .. b_(0) */
   6840   1.1     joerg 	res = d;
   6841   1.1     joerg 	if ((cnt = s % 8) != 0) {	/* not a typo, do nada if cnt==0 */
   6842   1.1     joerg 		/* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
   6843   1.1     joerg 		res = (d << (8 - cnt));
   6844   1.1     joerg 
   6845   1.1     joerg 		/* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
   6846   1.1     joerg 		mask = (1 << (8 - cnt)) - 1;
   6847   1.1     joerg 		res |= (d >> (cnt)) & mask;
   6848   1.1     joerg 
   6849   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6850   1.1     joerg 		 * of the result!!!                               */
   6851   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
   6852   1.1     joerg 		/* OVERFLOW is set *IFF* s==1, then it is the xor of the two
   6853   1.1     joerg 		 * most significant bits.  Blecck. */
   6854   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
   6855   1.1     joerg 	} else if (s != 0) {
   6856   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6857   1.1     joerg 		 * of the result!!!                               */
   6858   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
   6859   1.1     joerg 	}
   6860   1.1     joerg 	return (uint8_t) res;
   6861   1.1     joerg }
   6862   1.1     joerg /****************************************************************************
   6863   1.1     joerg REMARKS:
   6864   1.1     joerg Implements the ROR instruction and side effects.
   6865   1.1     joerg ****************************************************************************/
   6866   1.1     joerg static uint16_t
   6867   1.1     joerg ror_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   6868   1.1     joerg {
   6869   1.1     joerg 	unsigned int res, cnt, mask;
   6870   1.1     joerg 
   6871   1.1     joerg 	res = d;
   6872   1.1     joerg 	if ((cnt = s % 16) != 0) {
   6873   1.1     joerg 		res = (d << (16 - cnt));
   6874   1.1     joerg 		mask = (1 << (16 - cnt)) - 1;
   6875   1.1     joerg 		res |= (d >> (cnt)) & mask;
   6876   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
   6877   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
   6878   1.1     joerg 	} else if (s != 0) {
   6879   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6880   1.1     joerg 		 * of the result!!!                               */
   6881   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
   6882   1.1     joerg 	}
   6883   1.1     joerg 	return (uint16_t) res;
   6884   1.1     joerg }
   6885   1.1     joerg /****************************************************************************
   6886   1.1     joerg REMARKS:
   6887   1.1     joerg Implements the ROR instruction and side effects.
   6888   1.1     joerg ****************************************************************************/
   6889   1.1     joerg static uint32_t
   6890   1.1     joerg ror_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   6891   1.1     joerg {
   6892   1.1     joerg 	uint32_t res, cnt, mask;
   6893   1.1     joerg 
   6894   1.1     joerg 	res = d;
   6895   1.1     joerg 	if ((cnt = s % 32) != 0) {
   6896   1.1     joerg 		res = (d << (32 - cnt));
   6897   1.1     joerg 		mask = (1 << (32 - cnt)) - 1;
   6898   1.1     joerg 		res |= (d >> (cnt)) & mask;
   6899   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
   6900   1.1     joerg 		CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
   6901   1.1     joerg 	} else if (s != 0) {
   6902   1.1     joerg 		/* set the new carry flag, Note that it is the low order bit
   6903   1.1     joerg 		 * of the result!!!                               */
   6904   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
   6905   1.1     joerg 	}
   6906   1.1     joerg 	return res;
   6907   1.1     joerg }
   6908   1.1     joerg /****************************************************************************
   6909   1.1     joerg REMARKS:
   6910   1.1     joerg Implements the SHL instruction and side effects.
   6911   1.1     joerg ****************************************************************************/
   6912   1.1     joerg static uint8_t
   6913   1.1     joerg shl_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   6914   1.1     joerg {
   6915   1.1     joerg 	unsigned int cnt, res, cf;
   6916   1.1     joerg 
   6917   1.1     joerg 	if (s < 8) {
   6918   1.1     joerg 		cnt = s % 8;
   6919   1.1     joerg 
   6920   1.1     joerg 		/* last bit shifted out goes into carry flag */
   6921   1.1     joerg 		if (cnt > 0) {
   6922   1.1     joerg 			res = d << cnt;
   6923   1.1     joerg 			cf = d & (1 << (8 - cnt));
   6924   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   6925   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   6926   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   6927   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6928   1.1     joerg 		} else {
   6929   1.1     joerg 			res = (uint8_t) d;
   6930   1.1     joerg 		}
   6931   1.1     joerg 
   6932   1.1     joerg 		if (cnt == 1) {
   6933   1.1     joerg 			/* Needs simplification. */
   6934   1.1     joerg 			CONDITIONAL_SET_FLAG(
   6935   1.1     joerg 			    (((res & 0x80) == 0x80) ^
   6936   1.1     joerg 				(ACCESS_FLAG(F_CF) != 0)),
   6937   1.1     joerg 			/* was (emu->x86.R_FLG&F_CF)==F_CF)), */
   6938   1.1     joerg 			    F_OF);
   6939   1.1     joerg 		} else {
   6940   1.1     joerg 			CLEAR_FLAG(F_OF);
   6941   1.1     joerg 		}
   6942   1.1     joerg 	} else {
   6943   1.1     joerg 		res = 0;
   6944   1.1     joerg 		CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
   6945   1.1     joerg 		CLEAR_FLAG(F_OF);
   6946   1.1     joerg 		CLEAR_FLAG(F_SF);
   6947   1.1     joerg 		SET_FLAG(F_PF);
   6948   1.1     joerg 		SET_FLAG(F_ZF);
   6949   1.1     joerg 	}
   6950   1.1     joerg 	return (uint8_t) res;
   6951   1.1     joerg }
   6952   1.1     joerg /****************************************************************************
   6953   1.1     joerg REMARKS:
   6954   1.1     joerg Implements the SHL instruction and side effects.
   6955   1.1     joerg ****************************************************************************/
   6956   1.1     joerg static uint16_t
   6957   1.1     joerg shl_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   6958   1.1     joerg {
   6959   1.1     joerg 	unsigned int cnt, res, cf;
   6960   1.1     joerg 
   6961   1.1     joerg 	if (s < 16) {
   6962   1.1     joerg 		cnt = s % 16;
   6963   1.1     joerg 		if (cnt > 0) {
   6964   1.1     joerg 			res = d << cnt;
   6965   1.1     joerg 			cf = d & (1 << (16 - cnt));
   6966   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   6967   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   6968   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   6969   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   6970   1.1     joerg 		} else {
   6971   1.1     joerg 			res = (uint16_t) d;
   6972   1.1     joerg 		}
   6973   1.1     joerg 
   6974   1.1     joerg 		if (cnt == 1) {
   6975   1.1     joerg 			CONDITIONAL_SET_FLAG(
   6976   1.1     joerg 			    (((res & 0x8000) == 0x8000) ^
   6977   1.1     joerg 				(ACCESS_FLAG(F_CF) != 0)),
   6978   1.1     joerg 			    F_OF);
   6979   1.1     joerg 		} else {
   6980   1.1     joerg 			CLEAR_FLAG(F_OF);
   6981   1.1     joerg 		}
   6982   1.1     joerg 	} else {
   6983   1.1     joerg 		res = 0;
   6984   1.1     joerg 		CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
   6985   1.1     joerg 		CLEAR_FLAG(F_OF);
   6986   1.1     joerg 		CLEAR_FLAG(F_SF);
   6987   1.1     joerg 		SET_FLAG(F_PF);
   6988   1.1     joerg 		SET_FLAG(F_ZF);
   6989   1.1     joerg 	}
   6990   1.1     joerg 	return (uint16_t) res;
   6991   1.1     joerg }
   6992   1.1     joerg /****************************************************************************
   6993   1.1     joerg REMARKS:
   6994   1.1     joerg Implements the SHL instruction and side effects.
   6995   1.1     joerg ****************************************************************************/
   6996   1.1     joerg static uint32_t
   6997   1.1     joerg shl_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   6998   1.1     joerg {
   6999   1.1     joerg 	unsigned int cnt, res, cf;
   7000   1.1     joerg 
   7001   1.1     joerg 	if (s < 32) {
   7002   1.1     joerg 		cnt = s % 32;
   7003   1.1     joerg 		if (cnt > 0) {
   7004   1.1     joerg 			res = d << cnt;
   7005   1.1     joerg 			cf = d & (1 << (32 - cnt));
   7006   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7007   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7008   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7009   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7010   1.1     joerg 		} else {
   7011   1.1     joerg 			res = d;
   7012   1.1     joerg 		}
   7013   1.1     joerg 		if (cnt == 1) {
   7014   1.1     joerg 			CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
   7015   1.1     joerg 				(ACCESS_FLAG(F_CF) != 0)), F_OF);
   7016   1.1     joerg 		} else {
   7017   1.1     joerg 			CLEAR_FLAG(F_OF);
   7018   1.1     joerg 		}
   7019   1.1     joerg 	} else {
   7020   1.1     joerg 		res = 0;
   7021   1.1     joerg 		CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
   7022   1.1     joerg 		CLEAR_FLAG(F_OF);
   7023   1.1     joerg 		CLEAR_FLAG(F_SF);
   7024   1.1     joerg 		SET_FLAG(F_PF);
   7025   1.1     joerg 		SET_FLAG(F_ZF);
   7026   1.1     joerg 	}
   7027   1.1     joerg 	return res;
   7028   1.1     joerg }
   7029   1.1     joerg /****************************************************************************
   7030   1.1     joerg REMARKS:
   7031   1.1     joerg Implements the SHR instruction and side effects.
   7032   1.1     joerg ****************************************************************************/
   7033   1.1     joerg static uint8_t
   7034   1.1     joerg shr_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7035   1.1     joerg {
   7036   1.1     joerg 	unsigned int cnt, res, cf;
   7037   1.1     joerg 
   7038   1.1     joerg 	if (s < 8) {
   7039   1.1     joerg 		cnt = s % 8;
   7040   1.1     joerg 		if (cnt > 0) {
   7041   1.1     joerg 			cf = d & (1 << (cnt - 1));
   7042   1.1     joerg 			res = d >> cnt;
   7043   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7044   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   7045   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7046   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7047   1.1     joerg 		} else {
   7048   1.1     joerg 			res = (uint8_t) d;
   7049   1.1     joerg 		}
   7050   1.1     joerg 
   7051   1.1     joerg 		if (cnt == 1) {
   7052   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
   7053   1.1     joerg 		} else {
   7054   1.1     joerg 			CLEAR_FLAG(F_OF);
   7055   1.1     joerg 		}
   7056   1.1     joerg 	} else {
   7057   1.1     joerg 		res = 0;
   7058   1.1     joerg 		CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
   7059   1.1     joerg 		CLEAR_FLAG(F_OF);
   7060   1.1     joerg 		CLEAR_FLAG(F_SF);
   7061   1.1     joerg 		SET_FLAG(F_PF);
   7062   1.1     joerg 		SET_FLAG(F_ZF);
   7063   1.1     joerg 	}
   7064   1.1     joerg 	return (uint8_t) res;
   7065   1.1     joerg }
   7066   1.1     joerg /****************************************************************************
   7067   1.1     joerg REMARKS:
   7068   1.1     joerg Implements the SHR instruction and side effects.
   7069   1.1     joerg ****************************************************************************/
   7070   1.1     joerg static uint16_t
   7071   1.1     joerg shr_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   7072   1.1     joerg {
   7073   1.1     joerg 	unsigned int cnt, res, cf;
   7074   1.1     joerg 
   7075   1.1     joerg 	if (s < 16) {
   7076   1.1     joerg 		cnt = s % 16;
   7077   1.1     joerg 		if (cnt > 0) {
   7078   1.1     joerg 			cf = d & (1 << (cnt - 1));
   7079   1.1     joerg 			res = d >> cnt;
   7080   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7081   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7082   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7083   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7084   1.1     joerg 		} else {
   7085   1.1     joerg 			res = d;
   7086   1.1     joerg 		}
   7087   1.1     joerg 
   7088   1.1     joerg 		if (cnt == 1) {
   7089   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
   7090   1.1     joerg 		} else {
   7091   1.1     joerg 			CLEAR_FLAG(F_OF);
   7092   1.1     joerg 		}
   7093   1.1     joerg 	} else {
   7094   1.1     joerg 		res = 0;
   7095   1.1     joerg 		CLEAR_FLAG(F_CF);
   7096   1.1     joerg 		CLEAR_FLAG(F_OF);
   7097   1.1     joerg 		SET_FLAG(F_ZF);
   7098   1.1     joerg 		CLEAR_FLAG(F_SF);
   7099   1.1     joerg 		CLEAR_FLAG(F_PF);
   7100   1.1     joerg 	}
   7101   1.1     joerg 	return (uint16_t) res;
   7102   1.1     joerg }
   7103   1.1     joerg /****************************************************************************
   7104   1.1     joerg REMARKS:
   7105   1.1     joerg Implements the SHR instruction and side effects.
   7106   1.1     joerg ****************************************************************************/
   7107   1.1     joerg static uint32_t
   7108   1.1     joerg shr_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   7109   1.1     joerg {
   7110   1.1     joerg 	unsigned int cnt, res, cf;
   7111   1.1     joerg 
   7112   1.1     joerg 	if (s < 32) {
   7113   1.1     joerg 		cnt = s % 32;
   7114   1.1     joerg 		if (cnt > 0) {
   7115   1.1     joerg 			cf = d & (1 << (cnt - 1));
   7116   1.1     joerg 			res = d >> cnt;
   7117   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7118   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7119   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7120   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7121   1.1     joerg 		} else {
   7122   1.1     joerg 			res = d;
   7123   1.1     joerg 		}
   7124   1.1     joerg 		if (cnt == 1) {
   7125   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
   7126   1.1     joerg 		} else {
   7127   1.1     joerg 			CLEAR_FLAG(F_OF);
   7128   1.1     joerg 		}
   7129   1.1     joerg 	} else {
   7130   1.1     joerg 		res = 0;
   7131   1.1     joerg 		CLEAR_FLAG(F_CF);
   7132   1.1     joerg 		CLEAR_FLAG(F_OF);
   7133   1.1     joerg 		SET_FLAG(F_ZF);
   7134   1.1     joerg 		CLEAR_FLAG(F_SF);
   7135   1.1     joerg 		CLEAR_FLAG(F_PF);
   7136   1.1     joerg 	}
   7137   1.1     joerg 	return res;
   7138   1.1     joerg }
   7139   1.1     joerg /****************************************************************************
   7140   1.1     joerg REMARKS:
   7141   1.1     joerg Implements the SAR instruction and side effects.
   7142   1.1     joerg ****************************************************************************/
   7143   1.1     joerg static uint8_t
   7144   1.1     joerg sar_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7145   1.1     joerg {
   7146   1.1     joerg 	unsigned int cnt, res, cf, mask, sf;
   7147   1.1     joerg 
   7148   1.1     joerg 	res = d;
   7149   1.1     joerg 	sf = d & 0x80;
   7150   1.1     joerg 	cnt = s % 8;
   7151   1.1     joerg 	if (cnt > 0 && cnt < 8) {
   7152   1.1     joerg 		mask = (1 << (8 - cnt)) - 1;
   7153   1.1     joerg 		cf = d & (1 << (cnt - 1));
   7154   1.1     joerg 		res = (d >> cnt) & mask;
   7155   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   7156   1.1     joerg 		if (sf) {
   7157   1.1     joerg 			res |= ~mask;
   7158   1.1     joerg 		}
   7159   1.1     joerg 		CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   7160   1.1     joerg 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7161   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7162   1.1     joerg 	} else if (cnt >= 8) {
   7163   1.1     joerg 		if (sf) {
   7164   1.1     joerg 			res = 0xff;
   7165   1.1     joerg 			SET_FLAG(F_CF);
   7166   1.1     joerg 			CLEAR_FLAG(F_ZF);
   7167   1.1     joerg 			SET_FLAG(F_SF);
   7168   1.1     joerg 			SET_FLAG(F_PF);
   7169   1.1     joerg 		} else {
   7170   1.1     joerg 			res = 0;
   7171   1.1     joerg 			CLEAR_FLAG(F_CF);
   7172   1.1     joerg 			SET_FLAG(F_ZF);
   7173   1.1     joerg 			CLEAR_FLAG(F_SF);
   7174   1.1     joerg 			CLEAR_FLAG(F_PF);
   7175   1.1     joerg 		}
   7176   1.1     joerg 	}
   7177   1.1     joerg 	return (uint8_t) res;
   7178   1.1     joerg }
   7179   1.1     joerg /****************************************************************************
   7180   1.1     joerg REMARKS:
   7181   1.1     joerg Implements the SAR instruction and side effects.
   7182   1.1     joerg ****************************************************************************/
   7183   1.1     joerg static uint16_t
   7184   1.1     joerg sar_word(struct X86EMU *emu, uint16_t d, uint8_t s)
   7185   1.1     joerg {
   7186   1.1     joerg 	unsigned int cnt, res, cf, mask, sf;
   7187   1.1     joerg 
   7188   1.1     joerg 	sf = d & 0x8000;
   7189   1.1     joerg 	cnt = s % 16;
   7190   1.1     joerg 	res = d;
   7191   1.1     joerg 	if (cnt > 0 && cnt < 16) {
   7192   1.1     joerg 		mask = (1 << (16 - cnt)) - 1;
   7193   1.1     joerg 		cf = d & (1 << (cnt - 1));
   7194   1.1     joerg 		res = (d >> cnt) & mask;
   7195   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   7196   1.1     joerg 		if (sf) {
   7197   1.1     joerg 			res |= ~mask;
   7198   1.1     joerg 		}
   7199   1.1     joerg 		CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7200   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7201   1.1     joerg 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7202   1.1     joerg 	} else if (cnt >= 16) {
   7203   1.1     joerg 		if (sf) {
   7204   1.1     joerg 			res = 0xffff;
   7205   1.1     joerg 			SET_FLAG(F_CF);
   7206   1.1     joerg 			CLEAR_FLAG(F_ZF);
   7207   1.1     joerg 			SET_FLAG(F_SF);
   7208   1.1     joerg 			SET_FLAG(F_PF);
   7209   1.1     joerg 		} else {
   7210   1.1     joerg 			res = 0;
   7211   1.1     joerg 			CLEAR_FLAG(F_CF);
   7212   1.1     joerg 			SET_FLAG(F_ZF);
   7213   1.1     joerg 			CLEAR_FLAG(F_SF);
   7214   1.1     joerg 			CLEAR_FLAG(F_PF);
   7215   1.1     joerg 		}
   7216   1.1     joerg 	}
   7217   1.1     joerg 	return (uint16_t) res;
   7218   1.1     joerg }
   7219   1.1     joerg /****************************************************************************
   7220   1.1     joerg REMARKS:
   7221   1.1     joerg Implements the SAR instruction and side effects.
   7222   1.1     joerg ****************************************************************************/
   7223   1.1     joerg static uint32_t
   7224   1.1     joerg sar_long(struct X86EMU *emu, uint32_t d, uint8_t s)
   7225   1.1     joerg {
   7226   1.1     joerg 	uint32_t cnt, res, cf, mask, sf;
   7227   1.1     joerg 
   7228   1.1     joerg 	sf = d & 0x80000000;
   7229   1.1     joerg 	cnt = s % 32;
   7230   1.1     joerg 	res = d;
   7231   1.1     joerg 	if (cnt > 0 && cnt < 32) {
   7232   1.1     joerg 		mask = (1 << (32 - cnt)) - 1;
   7233   1.1     joerg 		cf = d & (1 << (cnt - 1));
   7234   1.1     joerg 		res = (d >> cnt) & mask;
   7235   1.1     joerg 		CONDITIONAL_SET_FLAG(cf, F_CF);
   7236   1.1     joerg 		if (sf) {
   7237   1.1     joerg 			res |= ~mask;
   7238   1.1     joerg 		}
   7239   1.1     joerg 		CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7240   1.1     joerg 		CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7241   1.1     joerg 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7242   1.1     joerg 	} else if (cnt >= 32) {
   7243   1.1     joerg 		if (sf) {
   7244   1.1     joerg 			res = 0xffffffff;
   7245   1.1     joerg 			SET_FLAG(F_CF);
   7246   1.1     joerg 			CLEAR_FLAG(F_ZF);
   7247   1.1     joerg 			SET_FLAG(F_SF);
   7248   1.1     joerg 			SET_FLAG(F_PF);
   7249   1.1     joerg 		} else {
   7250   1.1     joerg 			res = 0;
   7251   1.1     joerg 			CLEAR_FLAG(F_CF);
   7252   1.1     joerg 			SET_FLAG(F_ZF);
   7253   1.1     joerg 			CLEAR_FLAG(F_SF);
   7254   1.1     joerg 			CLEAR_FLAG(F_PF);
   7255   1.1     joerg 		}
   7256   1.1     joerg 	}
   7257   1.1     joerg 	return res;
   7258   1.1     joerg }
   7259   1.1     joerg /****************************************************************************
   7260   1.1     joerg REMARKS:
   7261   1.1     joerg Implements the SHLD instruction and side effects.
   7262   1.1     joerg ****************************************************************************/
   7263   1.1     joerg static uint16_t
   7264   1.1     joerg shld_word(struct X86EMU *emu, uint16_t d, uint16_t fill, uint8_t s)
   7265   1.1     joerg {
   7266   1.1     joerg 	unsigned int cnt, res, cf;
   7267   1.1     joerg 
   7268   1.1     joerg 	if (s < 16) {
   7269   1.1     joerg 		cnt = s % 16;
   7270   1.1     joerg 		if (cnt > 0) {
   7271   1.1     joerg 			res = (d << cnt) | (fill >> (16 - cnt));
   7272   1.1     joerg 			cf = d & (1 << (16 - cnt));
   7273   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7274   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7275   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7276   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7277   1.1     joerg 		} else {
   7278   1.1     joerg 			res = d;
   7279   1.1     joerg 		}
   7280   1.1     joerg 		if (cnt == 1) {
   7281   1.1     joerg 			CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
   7282   1.1     joerg 				(ACCESS_FLAG(F_CF) != 0)), F_OF);
   7283   1.1     joerg 		} else {
   7284   1.1     joerg 			CLEAR_FLAG(F_OF);
   7285   1.1     joerg 		}
   7286   1.1     joerg 	} else {
   7287   1.1     joerg 		res = 0;
   7288   1.1     joerg 		CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
   7289   1.1     joerg 		CLEAR_FLAG(F_OF);
   7290   1.1     joerg 		CLEAR_FLAG(F_SF);
   7291   1.1     joerg 		SET_FLAG(F_PF);
   7292   1.1     joerg 		SET_FLAG(F_ZF);
   7293   1.1     joerg 	}
   7294   1.1     joerg 	return (uint16_t) res;
   7295   1.1     joerg }
   7296   1.1     joerg /****************************************************************************
   7297   1.1     joerg REMARKS:
   7298   1.1     joerg Implements the SHLD instruction and side effects.
   7299   1.1     joerg ****************************************************************************/
   7300   1.1     joerg static uint32_t
   7301   1.1     joerg shld_long(struct X86EMU *emu, uint32_t d, uint32_t fill, uint8_t s)
   7302   1.1     joerg {
   7303   1.1     joerg 	unsigned int cnt, res, cf;
   7304   1.1     joerg 
   7305   1.1     joerg 	if (s < 32) {
   7306   1.1     joerg 		cnt = s % 32;
   7307   1.1     joerg 		if (cnt > 0) {
   7308   1.1     joerg 			res = (d << cnt) | (fill >> (32 - cnt));
   7309   1.1     joerg 			cf = d & (1 << (32 - cnt));
   7310   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7311   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7312   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7313   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7314   1.1     joerg 		} else {
   7315   1.1     joerg 			res = d;
   7316   1.1     joerg 		}
   7317   1.1     joerg 		if (cnt == 1) {
   7318   1.1     joerg 			CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
   7319   1.1     joerg 				(ACCESS_FLAG(F_CF) != 0)), F_OF);
   7320   1.1     joerg 		} else {
   7321   1.1     joerg 			CLEAR_FLAG(F_OF);
   7322   1.1     joerg 		}
   7323   1.1     joerg 	} else {
   7324   1.1     joerg 		res = 0;
   7325   1.1     joerg 		CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
   7326   1.1     joerg 		CLEAR_FLAG(F_OF);
   7327   1.1     joerg 		CLEAR_FLAG(F_SF);
   7328   1.1     joerg 		SET_FLAG(F_PF);
   7329   1.1     joerg 		SET_FLAG(F_ZF);
   7330   1.1     joerg 	}
   7331   1.1     joerg 	return res;
   7332   1.1     joerg }
   7333   1.1     joerg /****************************************************************************
   7334   1.1     joerg REMARKS:
   7335   1.1     joerg Implements the SHRD instruction and side effects.
   7336   1.1     joerg ****************************************************************************/
   7337   1.1     joerg static uint16_t
   7338   1.1     joerg shrd_word(struct X86EMU *emu, uint16_t d, uint16_t fill, uint8_t s)
   7339   1.1     joerg {
   7340   1.1     joerg 	unsigned int cnt, res, cf;
   7341   1.1     joerg 
   7342   1.1     joerg 	if (s < 16) {
   7343   1.1     joerg 		cnt = s % 16;
   7344   1.1     joerg 		if (cnt > 0) {
   7345   1.1     joerg 			cf = d & (1 << (cnt - 1));
   7346   1.1     joerg 			res = (d >> cnt) | (fill << (16 - cnt));
   7347   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7348   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7349   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7350   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7351   1.1     joerg 		} else {
   7352   1.1     joerg 			res = d;
   7353   1.1     joerg 		}
   7354   1.1     joerg 
   7355   1.1     joerg 		if (cnt == 1) {
   7356   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
   7357   1.1     joerg 		} else {
   7358   1.1     joerg 			CLEAR_FLAG(F_OF);
   7359   1.1     joerg 		}
   7360   1.1     joerg 	} else {
   7361   1.1     joerg 		res = 0;
   7362   1.1     joerg 		CLEAR_FLAG(F_CF);
   7363   1.1     joerg 		CLEAR_FLAG(F_OF);
   7364   1.1     joerg 		SET_FLAG(F_ZF);
   7365   1.1     joerg 		CLEAR_FLAG(F_SF);
   7366   1.1     joerg 		CLEAR_FLAG(F_PF);
   7367   1.1     joerg 	}
   7368   1.1     joerg 	return (uint16_t) res;
   7369   1.1     joerg }
   7370   1.1     joerg /****************************************************************************
   7371   1.1     joerg REMARKS:
   7372   1.1     joerg Implements the SHRD instruction and side effects.
   7373   1.1     joerg ****************************************************************************/
   7374   1.1     joerg static uint32_t
   7375   1.1     joerg shrd_long(struct X86EMU *emu, uint32_t d, uint32_t fill, uint8_t s)
   7376   1.1     joerg {
   7377   1.1     joerg 	unsigned int cnt, res, cf;
   7378   1.1     joerg 
   7379   1.1     joerg 	if (s < 32) {
   7380   1.1     joerg 		cnt = s % 32;
   7381   1.1     joerg 		if (cnt > 0) {
   7382   1.1     joerg 			cf = d & (1 << (cnt - 1));
   7383   1.1     joerg 			res = (d >> cnt) | (fill << (32 - cnt));
   7384   1.1     joerg 			CONDITIONAL_SET_FLAG(cf, F_CF);
   7385   1.1     joerg 			CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7386   1.1     joerg 			CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7387   1.1     joerg 			CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7388   1.1     joerg 		} else {
   7389   1.1     joerg 			res = d;
   7390   1.1     joerg 		}
   7391   1.1     joerg 		if (cnt == 1) {
   7392   1.1     joerg 			CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
   7393   1.1     joerg 		} else {
   7394   1.1     joerg 			CLEAR_FLAG(F_OF);
   7395   1.1     joerg 		}
   7396   1.1     joerg 	} else {
   7397   1.1     joerg 		res = 0;
   7398   1.1     joerg 		CLEAR_FLAG(F_CF);
   7399   1.1     joerg 		CLEAR_FLAG(F_OF);
   7400   1.1     joerg 		SET_FLAG(F_ZF);
   7401   1.1     joerg 		CLEAR_FLAG(F_SF);
   7402   1.1     joerg 		CLEAR_FLAG(F_PF);
   7403   1.1     joerg 	}
   7404   1.1     joerg 	return res;
   7405   1.1     joerg }
   7406   1.1     joerg /****************************************************************************
   7407   1.1     joerg REMARKS:
   7408   1.1     joerg Implements the SBB instruction and side effects.
   7409   1.1     joerg ****************************************************************************/
   7410   1.1     joerg static uint8_t
   7411   1.1     joerg sbb_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7412   1.1     joerg {
   7413   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7414   1.1     joerg 	uint32_t bc;
   7415   1.1     joerg 
   7416   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   7417   1.1     joerg 		res = d - s - 1;
   7418   1.1     joerg 	else
   7419   1.1     joerg 		res = d - s;
   7420   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7421   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   7422   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7423   1.1     joerg 
   7424   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7425   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7426   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
   7427   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   7428   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7429   1.1     joerg 	return (uint8_t) res;
   7430   1.1     joerg }
   7431   1.1     joerg /****************************************************************************
   7432   1.1     joerg REMARKS:
   7433   1.1     joerg Implements the SBB instruction and side effects.
   7434   1.1     joerg ****************************************************************************/
   7435   1.1     joerg static uint16_t
   7436   1.1     joerg sbb_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   7437   1.1     joerg {
   7438   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7439   1.1     joerg 	uint32_t bc;
   7440   1.1     joerg 
   7441   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   7442   1.1     joerg 		res = d - s - 1;
   7443   1.1     joerg 	else
   7444   1.1     joerg 		res = d - s;
   7445   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7446   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7447   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7448   1.1     joerg 
   7449   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7450   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7451   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
   7452   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   7453   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7454   1.1     joerg 	return (uint16_t) res;
   7455   1.1     joerg }
   7456   1.1     joerg /****************************************************************************
   7457   1.1     joerg REMARKS:
   7458   1.1     joerg Implements the SBB instruction and side effects.
   7459   1.1     joerg ****************************************************************************/
   7460   1.1     joerg static uint32_t
   7461   1.1     joerg sbb_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   7462   1.1     joerg {
   7463   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7464   1.1     joerg 	uint32_t bc;
   7465   1.1     joerg 
   7466   1.1     joerg 	if (ACCESS_FLAG(F_CF))
   7467   1.1     joerg 		res = d - s - 1;
   7468   1.1     joerg 	else
   7469   1.1     joerg 		res = d - s;
   7470   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7471   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7472   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7473   1.1     joerg 
   7474   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7475   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7476   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
   7477   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   7478   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7479   1.1     joerg 	return res;
   7480   1.1     joerg }
   7481   1.1     joerg /****************************************************************************
   7482   1.1     joerg REMARKS:
   7483   1.1     joerg Implements the SUB instruction and side effects.
   7484   1.1     joerg ****************************************************************************/
   7485   1.1     joerg static uint8_t
   7486   1.1     joerg sub_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7487   1.1     joerg {
   7488   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7489   1.1     joerg 	uint32_t bc;
   7490   1.1     joerg 
   7491   1.1     joerg 	res = d - s;
   7492   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7493   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
   7494   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7495   1.1     joerg 
   7496   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7497   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7498   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
   7499   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
   7500   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7501   1.1     joerg 	return (uint8_t) res;
   7502   1.1     joerg }
   7503   1.1     joerg /****************************************************************************
   7504   1.1     joerg REMARKS:
   7505   1.1     joerg Implements the SUB instruction and side effects.
   7506   1.1     joerg ****************************************************************************/
   7507   1.1     joerg static uint16_t
   7508   1.1     joerg sub_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   7509   1.1     joerg {
   7510   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7511   1.1     joerg 	uint32_t bc;
   7512   1.1     joerg 
   7513   1.1     joerg 	res = d - s;
   7514   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7515   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
   7516   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7517   1.1     joerg 
   7518   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7519   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7520   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
   7521   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
   7522   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7523   1.1     joerg 	return (uint16_t) res;
   7524   1.1     joerg }
   7525   1.1     joerg /****************************************************************************
   7526   1.1     joerg REMARKS:
   7527   1.1     joerg Implements the SUB instruction and side effects.
   7528   1.1     joerg ****************************************************************************/
   7529   1.1     joerg static uint32_t
   7530   1.1     joerg sub_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   7531   1.1     joerg {
   7532   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7533   1.1     joerg 	uint32_t bc;
   7534   1.1     joerg 
   7535   1.1     joerg 	res = d - s;
   7536   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7537   1.1     joerg 	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
   7538   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7539   1.1     joerg 
   7540   1.1     joerg 	/* calculate the borrow chain.  See note at top */
   7541   1.1     joerg 	bc = (res & (~d | s)) | (~d & s);
   7542   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
   7543   1.1     joerg 	CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
   7544   1.1     joerg 	CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
   7545   1.1     joerg 	return res;
   7546   1.1     joerg }
   7547   1.1     joerg /****************************************************************************
   7548   1.1     joerg REMARKS:
   7549   1.1     joerg Implements the TEST instruction and side effects.
   7550   1.1     joerg ****************************************************************************/
   7551   1.1     joerg static void
   7552   1.1     joerg test_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7553   1.1     joerg {
   7554   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7555   1.1     joerg 
   7556   1.1     joerg 	res = d & s;
   7557   1.1     joerg 
   7558   1.1     joerg 	CLEAR_FLAG(F_OF);
   7559   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7560   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7561   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7562   1.1     joerg 	/* AF == dont care */
   7563   1.1     joerg 	CLEAR_FLAG(F_CF);
   7564   1.1     joerg }
   7565   1.1     joerg /****************************************************************************
   7566   1.1     joerg REMARKS:
   7567   1.1     joerg Implements the TEST instruction and side effects.
   7568   1.1     joerg ****************************************************************************/
   7569   1.1     joerg static void
   7570   1.1     joerg test_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   7571   1.1     joerg {
   7572   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7573   1.1     joerg 
   7574   1.1     joerg 	res = d & s;
   7575   1.1     joerg 
   7576   1.1     joerg 	CLEAR_FLAG(F_OF);
   7577   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7578   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7579   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7580   1.1     joerg 	/* AF == dont care */
   7581   1.1     joerg 	CLEAR_FLAG(F_CF);
   7582   1.1     joerg }
   7583   1.1     joerg /****************************************************************************
   7584   1.1     joerg REMARKS:
   7585   1.1     joerg Implements the TEST instruction and side effects.
   7586   1.1     joerg ****************************************************************************/
   7587   1.1     joerg static void
   7588   1.1     joerg test_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   7589   1.1     joerg {
   7590   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7591   1.1     joerg 
   7592   1.1     joerg 	res = d & s;
   7593   1.1     joerg 
   7594   1.1     joerg 	CLEAR_FLAG(F_OF);
   7595   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7596   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7597   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7598   1.1     joerg 	/* AF == dont care */
   7599   1.1     joerg 	CLEAR_FLAG(F_CF);
   7600   1.1     joerg }
   7601   1.1     joerg /****************************************************************************
   7602   1.1     joerg REMARKS:
   7603   1.1     joerg Implements the XOR instruction and side effects.
   7604   1.1     joerg ****************************************************************************/
   7605   1.1     joerg static uint8_t
   7606   1.1     joerg xor_byte(struct X86EMU *emu, uint8_t d, uint8_t s)
   7607   1.1     joerg {
   7608   1.1     joerg 	uint8_t res;	/* all operands in native machine order */
   7609   1.1     joerg 
   7610   1.1     joerg 	res = d ^ s;
   7611   1.1     joerg 	CLEAR_FLAG(F_OF);
   7612   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
   7613   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7614   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
   7615   1.1     joerg 	CLEAR_FLAG(F_CF);
   7616   1.1     joerg 	CLEAR_FLAG(F_AF);
   7617   1.1     joerg 	return res;
   7618   1.1     joerg }
   7619   1.1     joerg /****************************************************************************
   7620   1.1     joerg REMARKS:
   7621   1.1     joerg Implements the XOR instruction and side effects.
   7622   1.1     joerg ****************************************************************************/
   7623   1.1     joerg static uint16_t
   7624   1.1     joerg xor_word(struct X86EMU *emu, uint16_t d, uint16_t s)
   7625   1.1     joerg {
   7626   1.1     joerg 	uint16_t res;	/* all operands in native machine order */
   7627   1.1     joerg 
   7628   1.1     joerg 	res = d ^ s;
   7629   1.1     joerg 	CLEAR_FLAG(F_OF);
   7630   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
   7631   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7632   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7633   1.1     joerg 	CLEAR_FLAG(F_CF);
   7634   1.1     joerg 	CLEAR_FLAG(F_AF);
   7635   1.1     joerg 	return res;
   7636   1.1     joerg }
   7637   1.1     joerg /****************************************************************************
   7638   1.1     joerg REMARKS:
   7639   1.1     joerg Implements the XOR instruction and side effects.
   7640   1.1     joerg ****************************************************************************/
   7641   1.1     joerg static uint32_t
   7642   1.1     joerg xor_long(struct X86EMU *emu, uint32_t d, uint32_t s)
   7643   1.1     joerg {
   7644   1.1     joerg 	uint32_t res;	/* all operands in native machine order */
   7645   1.1     joerg 
   7646   1.1     joerg 	res = d ^ s;
   7647   1.1     joerg 	CLEAR_FLAG(F_OF);
   7648   1.1     joerg 	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
   7649   1.1     joerg 	CONDITIONAL_SET_FLAG(res == 0, F_ZF);
   7650   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
   7651   1.1     joerg 	CLEAR_FLAG(F_CF);
   7652   1.1     joerg 	CLEAR_FLAG(F_AF);
   7653   1.1     joerg 	return res;
   7654   1.1     joerg }
   7655   1.1     joerg /****************************************************************************
   7656   1.1     joerg REMARKS:
   7657   1.1     joerg Implements the IMUL instruction and side effects.
   7658   1.1     joerg ****************************************************************************/
   7659   1.1     joerg static void
   7660   1.1     joerg imul_byte(struct X86EMU *emu, uint8_t s)
   7661   1.1     joerg {
   7662   1.1     joerg 	int16_t res = (int16_t) ((int8_t) emu->x86.R_AL * (int8_t) s);
   7663   1.1     joerg 
   7664   1.1     joerg 	emu->x86.R_AX = res;
   7665   1.1     joerg 	if (((emu->x86.R_AL & 0x80) == 0 && emu->x86.R_AH == 0x00) ||
   7666   1.1     joerg 	    ((emu->x86.R_AL & 0x80) != 0 && emu->x86.R_AH == 0xFF)) {
   7667   1.1     joerg 		CLEAR_FLAG(F_CF);
   7668   1.1     joerg 		CLEAR_FLAG(F_OF);
   7669   1.1     joerg 	} else {
   7670   1.1     joerg 		SET_FLAG(F_CF);
   7671   1.1     joerg 		SET_FLAG(F_OF);
   7672   1.1     joerg 	}
   7673   1.1     joerg }
   7674   1.1     joerg /****************************************************************************
   7675   1.1     joerg REMARKS:
   7676   1.1     joerg Implements the IMUL instruction and side effects.
   7677   1.1     joerg ****************************************************************************/
   7678   1.1     joerg static void
   7679   1.1     joerg imul_word(struct X86EMU *emu, uint16_t s)
   7680   1.1     joerg {
   7681   1.1     joerg 	int32_t res = (int16_t) emu->x86.R_AX * (int16_t) s;
   7682   1.1     joerg 
   7683   1.1     joerg 	emu->x86.R_AX = (uint16_t) res;
   7684   1.1     joerg 	emu->x86.R_DX = (uint16_t) (res >> 16);
   7685   1.1     joerg 	if (((emu->x86.R_AX & 0x8000) == 0 && emu->x86.R_DX == 0x00) ||
   7686   1.1     joerg 	    ((emu->x86.R_AX & 0x8000) != 0 && emu->x86.R_DX == 0xFF)) {
   7687   1.1     joerg 		CLEAR_FLAG(F_CF);
   7688   1.1     joerg 		CLEAR_FLAG(F_OF);
   7689   1.1     joerg 	} else {
   7690   1.1     joerg 		SET_FLAG(F_CF);
   7691   1.1     joerg 		SET_FLAG(F_OF);
   7692   1.1     joerg 	}
   7693   1.1     joerg }
   7694   1.1     joerg /****************************************************************************
   7695   1.1     joerg REMARKS:
   7696   1.1     joerg Implements the IMUL instruction and side effects.
   7697   1.1     joerg ****************************************************************************/
   7698   1.1     joerg static void
   7699   1.1     joerg imul_long(struct X86EMU *emu, uint32_t s)
   7700   1.1     joerg {
   7701   1.1     joerg 	int64_t res;
   7702   1.1     joerg 
   7703   1.1     joerg 	res = (int64_t)(int32_t)emu->x86.R_EAX * (int32_t)s;
   7704   1.1     joerg 	emu->x86.R_EAX = (uint32_t)res;
   7705   1.1     joerg 	emu->x86.R_EDX = ((uint64_t)res) >> 32;
   7706   1.1     joerg 	if (((emu->x86.R_EAX & 0x80000000) == 0 && emu->x86.R_EDX == 0x00) ||
   7707   1.1     joerg 	    ((emu->x86.R_EAX & 0x80000000) != 0 && emu->x86.R_EDX == 0xFF)) {
   7708   1.1     joerg 		CLEAR_FLAG(F_CF);
   7709   1.1     joerg 		CLEAR_FLAG(F_OF);
   7710   1.1     joerg 	} else {
   7711   1.1     joerg 		SET_FLAG(F_CF);
   7712   1.1     joerg 		SET_FLAG(F_OF);
   7713   1.1     joerg 	}
   7714   1.1     joerg }
   7715   1.1     joerg /****************************************************************************
   7716   1.1     joerg REMARKS:
   7717   1.1     joerg Implements the MUL instruction and side effects.
   7718   1.1     joerg ****************************************************************************/
   7719   1.1     joerg static void
   7720   1.1     joerg mul_byte(struct X86EMU *emu, uint8_t s)
   7721   1.1     joerg {
   7722   1.1     joerg 	uint16_t res = (uint16_t) (emu->x86.R_AL * s);
   7723   1.1     joerg 
   7724   1.1     joerg 	emu->x86.R_AX = res;
   7725   1.1     joerg 	if (emu->x86.R_AH == 0) {
   7726   1.1     joerg 		CLEAR_FLAG(F_CF);
   7727   1.1     joerg 		CLEAR_FLAG(F_OF);
   7728   1.1     joerg 	} else {
   7729   1.1     joerg 		SET_FLAG(F_CF);
   7730   1.1     joerg 		SET_FLAG(F_OF);
   7731   1.1     joerg 	}
   7732   1.1     joerg }
   7733   1.1     joerg /****************************************************************************
   7734   1.1     joerg REMARKS:
   7735   1.1     joerg Implements the MUL instruction and side effects.
   7736   1.1     joerg ****************************************************************************/
   7737   1.1     joerg static void
   7738   1.1     joerg mul_word(struct X86EMU *emu, uint16_t s)
   7739   1.1     joerg {
   7740   1.1     joerg 	uint32_t res = emu->x86.R_AX * s;
   7741   1.1     joerg 
   7742   1.1     joerg 	emu->x86.R_AX = (uint16_t) res;
   7743   1.1     joerg 	emu->x86.R_DX = (uint16_t) (res >> 16);
   7744   1.1     joerg 	if (emu->x86.R_DX == 0) {
   7745   1.1     joerg 		CLEAR_FLAG(F_CF);
   7746   1.1     joerg 		CLEAR_FLAG(F_OF);
   7747   1.1     joerg 	} else {
   7748   1.1     joerg 		SET_FLAG(F_CF);
   7749   1.1     joerg 		SET_FLAG(F_OF);
   7750   1.1     joerg 	}
   7751   1.1     joerg }
   7752   1.1     joerg /****************************************************************************
   7753   1.1     joerg REMARKS:
   7754   1.1     joerg Implements the MUL instruction and side effects.
   7755   1.1     joerg ****************************************************************************/
   7756   1.1     joerg static void
   7757   1.1     joerg mul_long(struct X86EMU *emu, uint32_t s)
   7758   1.1     joerg {
   7759   1.1     joerg 	uint64_t res = (uint64_t) emu->x86.R_EAX * s;
   7760   1.1     joerg 
   7761   1.1     joerg 	emu->x86.R_EAX = (uint32_t) res;
   7762   1.1     joerg 	emu->x86.R_EDX = (uint32_t) (res >> 32);
   7763   1.1     joerg 
   7764   1.1     joerg 	if (emu->x86.R_EDX == 0) {
   7765   1.1     joerg 		CLEAR_FLAG(F_CF);
   7766   1.1     joerg 		CLEAR_FLAG(F_OF);
   7767   1.1     joerg 	} else {
   7768   1.1     joerg 		SET_FLAG(F_CF);
   7769   1.1     joerg 		SET_FLAG(F_OF);
   7770   1.1     joerg 	}
   7771   1.1     joerg }
   7772   1.1     joerg /****************************************************************************
   7773   1.1     joerg REMARKS:
   7774   1.1     joerg Implements the IDIV instruction and side effects.
   7775   1.1     joerg ****************************************************************************/
   7776   1.1     joerg static void
   7777   1.1     joerg idiv_byte(struct X86EMU *emu, uint8_t s)
   7778   1.1     joerg {
   7779   1.1     joerg 	int32_t dvd, div, mod;
   7780   1.1     joerg 
   7781   1.1     joerg 	dvd = (int16_t) emu->x86.R_AX;
   7782   1.1     joerg 	if (s == 0) {
   7783   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7784   1.1     joerg 		return;
   7785   1.1     joerg 	}
   7786   1.1     joerg 	div = dvd / (int8_t) s;
   7787   1.1     joerg 	mod = dvd % (int8_t) s;
   7788   1.1     joerg 	if (div > 0x7f || div < -0x7f) {
   7789   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7790   1.1     joerg 		return;
   7791   1.1     joerg 	}
   7792   1.1     joerg 	emu->x86.R_AL = (int8_t) div;
   7793   1.1     joerg 	emu->x86.R_AH = (int8_t) mod;
   7794   1.1     joerg }
   7795   1.1     joerg /****************************************************************************
   7796   1.1     joerg REMARKS:
   7797   1.1     joerg Implements the IDIV instruction and side effects.
   7798   1.1     joerg ****************************************************************************/
   7799   1.1     joerg static void
   7800   1.1     joerg idiv_word(struct X86EMU *emu, uint16_t s)
   7801   1.1     joerg {
   7802   1.1     joerg 	int32_t dvd, div, mod;
   7803   1.1     joerg 
   7804   1.1     joerg 	dvd = (((int32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
   7805   1.1     joerg 	if (s == 0) {
   7806   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7807   1.1     joerg 		return;
   7808   1.1     joerg 	}
   7809   1.1     joerg 	div = dvd / (int16_t) s;
   7810   1.1     joerg 	mod = dvd % (int16_t) s;
   7811   1.1     joerg 	if (div > 0x7fff || div < -0x7fff) {
   7812   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7813   1.1     joerg 		return;
   7814   1.1     joerg 	}
   7815   1.1     joerg 	CLEAR_FLAG(F_CF);
   7816   1.1     joerg 	CLEAR_FLAG(F_SF);
   7817   1.1     joerg 	CONDITIONAL_SET_FLAG(div == 0, F_ZF);
   7818   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   7819   1.1     joerg 
   7820   1.1     joerg 	emu->x86.R_AX = (uint16_t) div;
   7821   1.1     joerg 	emu->x86.R_DX = (uint16_t) mod;
   7822   1.1     joerg }
   7823   1.1     joerg /****************************************************************************
   7824   1.1     joerg REMARKS:
   7825   1.1     joerg Implements the IDIV instruction and side effects.
   7826   1.1     joerg ****************************************************************************/
   7827   1.1     joerg static void
   7828   1.1     joerg idiv_long(struct X86EMU *emu, uint32_t s)
   7829   1.1     joerg {
   7830   1.1     joerg 	int64_t dvd, div, mod;
   7831   1.1     joerg 
   7832   1.1     joerg 	dvd = (((int64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
   7833   1.1     joerg 	if (s == 0) {
   7834   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7835   1.1     joerg 		return;
   7836   1.1     joerg 	}
   7837   1.1     joerg 	div = dvd / (int32_t) s;
   7838   1.1     joerg 	mod = dvd % (int32_t) s;
   7839   1.1     joerg 	if (div > 0x7fffffff || div < -0x7fffffff) {
   7840   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7841   1.1     joerg 		return;
   7842   1.1     joerg 	}
   7843   1.1     joerg 	CLEAR_FLAG(F_CF);
   7844   1.1     joerg 	CLEAR_FLAG(F_AF);
   7845   1.1     joerg 	CLEAR_FLAG(F_SF);
   7846   1.1     joerg 	SET_FLAG(F_ZF);
   7847   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   7848   1.1     joerg 
   7849   1.1     joerg 	emu->x86.R_EAX = (uint32_t) div;
   7850   1.1     joerg 	emu->x86.R_EDX = (uint32_t) mod;
   7851   1.1     joerg }
   7852   1.1     joerg /****************************************************************************
   7853   1.1     joerg REMARKS:
   7854   1.1     joerg Implements the DIV instruction and side effects.
   7855   1.1     joerg ****************************************************************************/
   7856   1.1     joerg static void
   7857   1.1     joerg div_byte(struct X86EMU *emu, uint8_t s)
   7858   1.1     joerg {
   7859   1.1     joerg 	uint32_t dvd, div, mod;
   7860   1.1     joerg 
   7861   1.1     joerg 	dvd = emu->x86.R_AX;
   7862   1.1     joerg 	if (s == 0) {
   7863   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7864   1.1     joerg 		return;
   7865   1.1     joerg 	}
   7866   1.1     joerg 	div = dvd / (uint8_t) s;
   7867   1.1     joerg 	mod = dvd % (uint8_t) s;
   7868   1.1     joerg 	if (div > 0xff) {
   7869   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7870   1.1     joerg 		return;
   7871   1.1     joerg 	}
   7872   1.1     joerg 	emu->x86.R_AL = (uint8_t) div;
   7873   1.1     joerg 	emu->x86.R_AH = (uint8_t) mod;
   7874   1.1     joerg }
   7875   1.1     joerg /****************************************************************************
   7876   1.1     joerg REMARKS:
   7877   1.1     joerg Implements the DIV instruction and side effects.
   7878   1.1     joerg ****************************************************************************/
   7879   1.1     joerg static void
   7880   1.1     joerg div_word(struct X86EMU *emu, uint16_t s)
   7881   1.1     joerg {
   7882   1.1     joerg 	uint32_t dvd, div, mod;
   7883   1.1     joerg 
   7884   1.1     joerg 	dvd = (((uint32_t) emu->x86.R_DX) << 16) | emu->x86.R_AX;
   7885   1.1     joerg 	if (s == 0) {
   7886   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7887   1.1     joerg 		return;
   7888   1.1     joerg 	}
   7889   1.1     joerg 	div = dvd / (uint16_t) s;
   7890   1.1     joerg 	mod = dvd % (uint16_t) s;
   7891   1.1     joerg 	if (div > 0xffff) {
   7892   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7893   1.1     joerg 		return;
   7894   1.1     joerg 	}
   7895   1.1     joerg 	CLEAR_FLAG(F_CF);
   7896   1.1     joerg 	CLEAR_FLAG(F_SF);
   7897   1.1     joerg 	CONDITIONAL_SET_FLAG(div == 0, F_ZF);
   7898   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   7899   1.1     joerg 
   7900   1.1     joerg 	emu->x86.R_AX = (uint16_t) div;
   7901   1.1     joerg 	emu->x86.R_DX = (uint16_t) mod;
   7902   1.1     joerg }
   7903   1.1     joerg /****************************************************************************
   7904   1.1     joerg REMARKS:
   7905   1.1     joerg Implements the DIV instruction and side effects.
   7906   1.1     joerg ****************************************************************************/
   7907   1.1     joerg static void
   7908   1.1     joerg div_long(struct X86EMU *emu, uint32_t s)
   7909   1.1     joerg {
   7910   1.1     joerg 	uint64_t dvd, div, mod;
   7911   1.1     joerg 
   7912   1.1     joerg 	dvd = (((uint64_t) emu->x86.R_EDX) << 32) | emu->x86.R_EAX;
   7913   1.1     joerg 	if (s == 0) {
   7914   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7915   1.1     joerg 		return;
   7916   1.1     joerg 	}
   7917   1.1     joerg 	div = dvd / (uint32_t) s;
   7918   1.1     joerg 	mod = dvd % (uint32_t) s;
   7919   1.1     joerg 	if (div > 0xffffffff) {
   7920   1.5     joerg 		x86emu_intr_raise(emu, 8);
   7921   1.1     joerg 		return;
   7922   1.1     joerg 	}
   7923   1.1     joerg 	CLEAR_FLAG(F_CF);
   7924   1.1     joerg 	CLEAR_FLAG(F_AF);
   7925   1.1     joerg 	CLEAR_FLAG(F_SF);
   7926   1.1     joerg 	SET_FLAG(F_ZF);
   7927   1.1     joerg 	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
   7928   1.1     joerg 
   7929   1.1     joerg 	emu->x86.R_EAX = (uint32_t) div;
   7930   1.1     joerg 	emu->x86.R_EDX = (uint32_t) mod;
   7931   1.1     joerg }
   7932   1.1     joerg /****************************************************************************
   7933   1.1     joerg REMARKS:
   7934   1.1     joerg Implements the IN string instruction and side effects.
   7935   1.1     joerg ****************************************************************************/
   7936   1.1     joerg static void
   7937   1.1     joerg ins(struct X86EMU *emu, int size)
   7938   1.1     joerg {
   7939   1.1     joerg 	int inc = size;
   7940   1.1     joerg 
   7941   1.1     joerg 	if (ACCESS_FLAG(F_DF)) {
   7942   1.1     joerg 		inc = -size;
   7943   1.1     joerg 	}
   7944   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   7945   1.1     joerg 		/* dont care whether REPE or REPNE */
   7946   1.1     joerg 		/* in until CX is ZERO. */
   7947   1.1     joerg 		uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
   7948   1.1     joerg 		    emu->x86.R_ECX : emu->x86.R_CX);
   7949   1.1     joerg 		switch (size) {
   7950   1.1     joerg 		case 1:
   7951   1.1     joerg 			while (count--) {
   7952   1.1     joerg 				store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
   7953   1.1     joerg 				    (*emu->emu_inb) (emu, emu->x86.R_DX));
   7954   1.1     joerg 				emu->x86.R_DI += inc;
   7955   1.1     joerg 			}
   7956   1.1     joerg 			break;
   7957   1.1     joerg 
   7958   1.1     joerg 		case 2:
   7959   1.1     joerg 			while (count--) {
   7960   1.1     joerg 				store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
   7961   1.1     joerg 				    (*emu->emu_inw) (emu, emu->x86.R_DX));
   7962   1.1     joerg 				emu->x86.R_DI += inc;
   7963   1.1     joerg 			}
   7964   1.1     joerg 			break;
   7965   1.1     joerg 		case 4:
   7966   1.1     joerg 			while (count--) {
   7967   1.1     joerg 				store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
   7968   1.1     joerg 				    (*emu->emu_inl) (emu, emu->x86.R_DX));
   7969   1.1     joerg 				emu->x86.R_DI += inc;
   7970   1.1     joerg 				break;
   7971   1.1     joerg 			}
   7972   1.1     joerg 		}
   7973   1.1     joerg 		emu->x86.R_CX = 0;
   7974   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   7975   1.1     joerg 			emu->x86.R_ECX = 0;
   7976   1.1     joerg 		}
   7977   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   7978   1.1     joerg 	} else {
   7979   1.1     joerg 		switch (size) {
   7980   1.1     joerg 		case 1:
   7981   1.1     joerg 			store_byte(emu, emu->x86.R_ES, emu->x86.R_DI,
   7982   1.1     joerg 			    (*emu->emu_inb) (emu, emu->x86.R_DX));
   7983   1.1     joerg 			break;
   7984   1.1     joerg 		case 2:
   7985   1.1     joerg 			store_word(emu, emu->x86.R_ES, emu->x86.R_DI,
   7986   1.1     joerg 			    (*emu->emu_inw) (emu, emu->x86.R_DX));
   7987   1.1     joerg 			break;
   7988   1.1     joerg 		case 4:
   7989   1.1     joerg 			store_long(emu, emu->x86.R_ES, emu->x86.R_DI,
   7990   1.1     joerg 			    (*emu->emu_inl) (emu, emu->x86.R_DX));
   7991   1.1     joerg 			break;
   7992   1.1     joerg 		}
   7993   1.1     joerg 		emu->x86.R_DI += inc;
   7994   1.1     joerg 	}
   7995   1.1     joerg }
   7996   1.1     joerg /****************************************************************************
   7997   1.1     joerg REMARKS:
   7998   1.1     joerg Implements the OUT string instruction and side effects.
   7999   1.1     joerg ****************************************************************************/
   8000   1.1     joerg static void
   8001   1.1     joerg outs(struct X86EMU *emu, int size)
   8002   1.1     joerg {
   8003   1.1     joerg 	int inc = size;
   8004   1.1     joerg 
   8005   1.1     joerg 	if (ACCESS_FLAG(F_DF)) {
   8006   1.1     joerg 		inc = -size;
   8007   1.1     joerg 	}
   8008   1.1     joerg 	if (emu->x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
   8009   1.1     joerg 		/* dont care whether REPE or REPNE */
   8010   1.1     joerg 		/* out until CX is ZERO. */
   8011   1.1     joerg 		uint32_t count = ((emu->x86.mode & SYSMODE_PREFIX_DATA) ?
   8012   1.1     joerg 		    emu->x86.R_ECX : emu->x86.R_CX);
   8013   1.1     joerg 		switch (size) {
   8014   1.1     joerg 		case 1:
   8015   1.1     joerg 			while (count--) {
   8016   1.1     joerg 				(*emu->emu_outb) (emu, emu->x86.R_DX,
   8017   1.1     joerg 				    fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
   8018   1.1     joerg 				emu->x86.R_SI += inc;
   8019   1.1     joerg 			}
   8020   1.1     joerg 			break;
   8021   1.1     joerg 
   8022   1.1     joerg 		case 2:
   8023   1.1     joerg 			while (count--) {
   8024   1.1     joerg 				(*emu->emu_outw) (emu, emu->x86.R_DX,
   8025   1.1     joerg 				    fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
   8026   1.1     joerg 				emu->x86.R_SI += inc;
   8027   1.1     joerg 			}
   8028   1.1     joerg 			break;
   8029   1.1     joerg 		case 4:
   8030   1.1     joerg 			while (count--) {
   8031   1.1     joerg 				(*emu->emu_outl) (emu, emu->x86.R_DX,
   8032   1.1     joerg 				    fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
   8033   1.1     joerg 				emu->x86.R_SI += inc;
   8034   1.1     joerg 				break;
   8035   1.1     joerg 			}
   8036   1.1     joerg 		}
   8037   1.1     joerg 		emu->x86.R_CX = 0;
   8038   1.1     joerg 		if (emu->x86.mode & SYSMODE_PREFIX_DATA) {
   8039   1.1     joerg 			emu->x86.R_ECX = 0;
   8040   1.1     joerg 		}
   8041   1.1     joerg 		emu->x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
   8042   1.1     joerg 	} else {
   8043   1.1     joerg 		switch (size) {
   8044   1.1     joerg 		case 1:
   8045   1.1     joerg 			(*emu->emu_outb) (emu, emu->x86.R_DX,
   8046   1.1     joerg 			    fetch_byte(emu, emu->x86.R_ES, emu->x86.R_SI));
   8047   1.1     joerg 			break;
   8048   1.1     joerg 		case 2:
   8049   1.1     joerg 			(*emu->emu_outw) (emu, emu->x86.R_DX,
   8050   1.1     joerg 			    fetch_word(emu, emu->x86.R_ES, emu->x86.R_SI));
   8051   1.1     joerg 			break;
   8052   1.1     joerg 		case 4:
   8053   1.1     joerg 			(*emu->emu_outl) (emu, emu->x86.R_DX,
   8054   1.1     joerg 			    fetch_long(emu, emu->x86.R_ES, emu->x86.R_SI));
   8055   1.1     joerg 			break;
   8056   1.1     joerg 		}
   8057   1.1     joerg 		emu->x86.R_SI += inc;
   8058   1.1     joerg 	}
   8059   1.1     joerg }
   8060   1.1     joerg /****************************************************************************
   8061   1.1     joerg REMARKS:
   8062   1.1     joerg Pushes a word onto the stack.
   8063   1.1     joerg 
   8064   1.1     joerg NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
   8065   1.1     joerg ****************************************************************************/
   8066   1.1     joerg static void
   8067   1.1     joerg push_word(struct X86EMU *emu, uint16_t w)
   8068   1.1     joerg {
   8069   1.1     joerg 	emu->x86.R_SP -= 2;
   8070   1.1     joerg 	store_word(emu, emu->x86.R_SS, emu->x86.R_SP, w);
   8071   1.1     joerg }
   8072   1.1     joerg /****************************************************************************
   8073   1.1     joerg REMARKS:
   8074   1.1     joerg Pushes a long onto the stack.
   8075   1.1     joerg 
   8076   1.1     joerg NOTE: Do not inline this, as (*emu->emu_wrX) is already inline!
   8077   1.1     joerg ****************************************************************************/
   8078   1.1     joerg static void
   8079   1.1     joerg push_long(struct X86EMU *emu, uint32_t w)
   8080   1.1     joerg {
   8081   1.1     joerg 	emu->x86.R_SP -= 4;
   8082   1.1     joerg 	store_long(emu, emu->x86.R_SS, emu->x86.R_SP, w);
   8083   1.1     joerg }
   8084   1.1     joerg /****************************************************************************
   8085   1.1     joerg REMARKS:
   8086   1.1     joerg Pops a word from the stack.
   8087   1.1     joerg 
   8088   1.1     joerg NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
   8089   1.1     joerg ****************************************************************************/
   8090   1.1     joerg static uint16_t
   8091   1.1     joerg pop_word(struct X86EMU *emu)
   8092   1.1     joerg {
   8093   1.1     joerg 	uint16_t res;
   8094   1.1     joerg 
   8095   1.1     joerg 	res = fetch_word(emu, emu->x86.R_SS, emu->x86.R_SP);
   8096   1.1     joerg 	emu->x86.R_SP += 2;
   8097   1.1     joerg 	return res;
   8098   1.1     joerg }
   8099   1.1     joerg /****************************************************************************
   8100   1.1     joerg REMARKS:
   8101   1.1     joerg Pops a long from the stack.
   8102   1.1     joerg 
   8103   1.1     joerg NOTE: Do not inline this, as (*emu->emu_rdX) is already inline!
   8104   1.1     joerg ****************************************************************************/
   8105   1.1     joerg static uint32_t
   8106   1.1     joerg pop_long(struct X86EMU *emu)
   8107   1.1     joerg {
   8108   1.1     joerg 	uint32_t res;
   8109   1.1     joerg 
   8110   1.1     joerg 	res = fetch_long(emu, emu->x86.R_SS, emu->x86.R_SP);
   8111   1.1     joerg 	emu->x86.R_SP += 4;
   8112   1.1     joerg 	return res;
   8113   1.1     joerg }
   8114