2010-11-05 05:55:33 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2002-2010 The DOSBox Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* $Id: operators.h,v 1.8 2009-06-25 19:31:43 c2woody Exp $ */
|
|
|
|
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=(Bit8u)(lf_var1b+lf_var2b);
|
|
|
|
lflags.type=t_ADDb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return op1+op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=(Bit8u)(lf_var1b+lf_var2b+lflags.oldcf);
|
|
|
|
lflags.type=t_ADCb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return (Bit8u)(op1+op2+(Bitu)(get_CF()!=0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=(Bit8u)(lf_var1b-lf_var2b);
|
|
|
|
lflags.type=t_SUBb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return op1-op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=(Bit8u)(lf_var1b-(lf_var2b+lflags.oldcf));
|
|
|
|
lflags.type=t_SBBb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return (Bit8u)(op1-(op2+(Bitu)(get_CF()!=0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=(Bit8u)(lf_var1b-lf_var2b);
|
|
|
|
lflags.type=t_CMPb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b ^ lf_var2b;
|
|
|
|
lflags.type=t_XORb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return op1 ^ op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b & lf_var2b;
|
|
|
|
lflags.type=t_ANDb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return op1 & op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b | lf_var2b;
|
|
|
|
lflags.type=t_ORb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
return op1 | op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b & lf_var2b;
|
|
|
|
lflags.type=t_TESTb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=(Bit16u)(lf_var1w+lf_var2w);
|
|
|
|
lflags.type=t_ADDw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return op1+op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=(Bit16u)(lf_var1w+lf_var2w+lflags.oldcf);
|
|
|
|
lflags.type=t_ADCw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return (Bit16u)(op1+op2+(Bitu)(get_CF()!=0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=(Bit16u)(lf_var1w-lf_var2w);
|
|
|
|
lflags.type=t_SUBw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return op1-op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=(Bit16u)(lf_var1w-(lf_var2w+lflags.oldcf));
|
|
|
|
lflags.type=t_SBBw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return (Bit16u)(op1-(op2+(Bitu)(get_CF()!=0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=(Bit16u)(lf_var1w-lf_var2w);
|
|
|
|
lflags.type=t_CMPw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=lf_var1w ^ lf_var2w;
|
|
|
|
lflags.type=t_XORw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return op1 ^ op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=lf_var1w & lf_var2w;
|
|
|
|
lflags.type=t_ANDw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return op1 & op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=lf_var1w | lf_var2w;
|
|
|
|
lflags.type=t_ORw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
return op1 | op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) {
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2w=op2;
|
|
|
|
lf_resw=lf_var1w & lf_var2w;
|
|
|
|
lflags.type=t_TESTw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d+lf_var2d;
|
|
|
|
lflags.type=t_ADDd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1 + op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d+lf_var2d+lflags.oldcf;
|
|
|
|
lflags.type=t_ADCd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1+op2+(Bitu)(get_CF()!=0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d-lf_var2d;
|
|
|
|
lflags.type=t_SUBd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1-op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lflags.oldcf=get_CF()!=0;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d-(lf_var2d+lflags.oldcf);
|
|
|
|
lflags.type=t_SBBd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1-(op2+(Bitu)(get_CF()!=0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d-lf_var2d;
|
|
|
|
lflags.type=t_CMPd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d ^ lf_var2d;
|
|
|
|
lflags.type=t_XORd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1 ^ op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d & lf_var2d;
|
|
|
|
lflags.type=t_ANDd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1 & op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d | lf_var2d;
|
|
|
|
lflags.type=t_ORd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
return op1 | op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2d=op2;
|
|
|
|
lf_resd=lf_var1d & lf_var2d;
|
|
|
|
lflags.type=t_TESTd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void dyn_dop_byte_gencall(DualOps op) {
|
|
|
|
switch (op) {
|
|
|
|
case DOP_ADD:
|
|
|
|
InvalidateFlags((void*)&dynrec_add_byte_simple,t_ADDb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_add_byte);
|
|
|
|
break;
|
|
|
|
case DOP_ADC:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_adc_byte_simple,t_ADCb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_adc_byte);
|
|
|
|
break;
|
|
|
|
case DOP_SUB:
|
|
|
|
InvalidateFlags((void*)&dynrec_sub_byte_simple,t_SUBb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sub_byte);
|
|
|
|
break;
|
|
|
|
case DOP_SBB:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sbb_byte_simple,t_SBBb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sbb_byte);
|
|
|
|
break;
|
|
|
|
case DOP_CMP:
|
|
|
|
InvalidateFlags((void*)&dynrec_cmp_byte_simple,t_CMPb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_cmp_byte);
|
|
|
|
break;
|
|
|
|
case DOP_XOR:
|
|
|
|
InvalidateFlags((void*)&dynrec_xor_byte_simple,t_XORb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_xor_byte);
|
|
|
|
break;
|
|
|
|
case DOP_AND:
|
|
|
|
InvalidateFlags((void*)&dynrec_and_byte_simple,t_ANDb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_and_byte);
|
|
|
|
break;
|
|
|
|
case DOP_OR:
|
|
|
|
InvalidateFlags((void*)&dynrec_or_byte_simple,t_ORb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_or_byte);
|
|
|
|
break;
|
|
|
|
case DOP_TEST:
|
|
|
|
InvalidateFlags((void*)&dynrec_test_byte_simple,t_TESTb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_test_byte);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_dop_byte_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_dop_word_gencall(DualOps op,bool dword) {
|
|
|
|
if (dword) {
|
|
|
|
switch (op) {
|
|
|
|
case DOP_ADD:
|
|
|
|
InvalidateFlags((void*)&dynrec_add_dword_simple,t_ADDd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_add_dword);
|
|
|
|
break;
|
|
|
|
case DOP_ADC:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_adc_dword_simple,t_ADCd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_adc_dword);
|
|
|
|
break;
|
|
|
|
case DOP_SUB:
|
|
|
|
InvalidateFlags((void*)&dynrec_sub_dword_simple,t_SUBd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sub_dword);
|
|
|
|
break;
|
|
|
|
case DOP_SBB:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sbb_dword_simple,t_SBBd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sbb_dword);
|
|
|
|
break;
|
|
|
|
case DOP_CMP:
|
|
|
|
InvalidateFlags((void*)&dynrec_cmp_dword_simple,t_CMPd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_cmp_dword);
|
|
|
|
break;
|
|
|
|
case DOP_XOR:
|
|
|
|
InvalidateFlags((void*)&dynrec_xor_dword_simple,t_XORd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_xor_dword);
|
|
|
|
break;
|
|
|
|
case DOP_AND:
|
|
|
|
InvalidateFlags((void*)&dynrec_and_dword_simple,t_ANDd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_and_dword);
|
|
|
|
break;
|
|
|
|
case DOP_OR:
|
|
|
|
InvalidateFlags((void*)&dynrec_or_dword_simple,t_ORd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_or_dword);
|
|
|
|
break;
|
|
|
|
case DOP_TEST:
|
|
|
|
InvalidateFlags((void*)&dynrec_test_dword_simple,t_TESTd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_test_dword);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_dop_dword_gencall");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (op) {
|
|
|
|
case DOP_ADD:
|
|
|
|
InvalidateFlags((void*)&dynrec_add_word_simple,t_ADDw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_add_word);
|
|
|
|
break;
|
|
|
|
case DOP_ADC:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_adc_word_simple,t_ADCw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_adc_word);
|
|
|
|
break;
|
|
|
|
case DOP_SUB:
|
|
|
|
InvalidateFlags((void*)&dynrec_sub_word_simple,t_SUBw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sub_word);
|
|
|
|
break;
|
|
|
|
case DOP_SBB:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sbb_word_simple,t_SBBw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sbb_word);
|
|
|
|
break;
|
|
|
|
case DOP_CMP:
|
|
|
|
InvalidateFlags((void*)&dynrec_cmp_word_simple,t_CMPw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_cmp_word);
|
|
|
|
break;
|
|
|
|
case DOP_XOR:
|
|
|
|
InvalidateFlags((void*)&dynrec_xor_word_simple,t_XORw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_xor_word);
|
|
|
|
break;
|
|
|
|
case DOP_AND:
|
|
|
|
InvalidateFlags((void*)&dynrec_and_word_simple,t_ANDw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_and_word);
|
|
|
|
break;
|
|
|
|
case DOP_OR:
|
|
|
|
InvalidateFlags((void*)&dynrec_or_word_simple,t_ORw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_or_word);
|
|
|
|
break;
|
|
|
|
case DOP_TEST:
|
|
|
|
InvalidateFlags((void*)&dynrec_test_word_simple,t_TESTw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_test_word);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_dop_word_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1b=op;
|
|
|
|
lf_resb=lf_var1b+1;
|
|
|
|
lflags.type=t_INCb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) {
|
|
|
|
return op+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1b=op;
|
|
|
|
lf_resb=lf_var1b-1;
|
|
|
|
lflags.type=t_DECb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) {
|
|
|
|
return op-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) {
|
|
|
|
return ~op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) {
|
|
|
|
lf_var1b=op;
|
|
|
|
lf_resb=0-lf_var1b;
|
|
|
|
lflags.type=t_NEGb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) {
|
|
|
|
return 0-op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1w=op;
|
|
|
|
lf_resw=lf_var1w+1;
|
|
|
|
lflags.type=t_INCw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) {
|
|
|
|
return op+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1w=op;
|
|
|
|
lf_resw=lf_var1w-1;
|
|
|
|
lflags.type=t_DECw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) {
|
|
|
|
return op-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) {
|
|
|
|
return ~op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) {
|
|
|
|
lf_var1w=op;
|
|
|
|
lf_resw=0-lf_var1w;
|
|
|
|
lflags.type=t_NEGw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) {
|
|
|
|
return 0-op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1d=op;
|
|
|
|
lf_resd=lf_var1d+1;
|
|
|
|
lflags.type=t_INCd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) {
|
|
|
|
return op+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) {
|
|
|
|
LoadCF;
|
|
|
|
lf_var1d=op;
|
|
|
|
lf_resd=lf_var1d-1;
|
|
|
|
lflags.type=t_DECd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) {
|
|
|
|
return op-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) {
|
|
|
|
return ~op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) {
|
|
|
|
lf_var1d=op;
|
|
|
|
lf_resd=0-lf_var1d;
|
|
|
|
lflags.type=t_NEGd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) {
|
|
|
|
return 0-op;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void dyn_sop_byte_gencall(SingleOps op) {
|
|
|
|
switch (op) {
|
|
|
|
case SOP_INC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_inc_byte_simple,t_INCb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_inc_byte);
|
|
|
|
break;
|
|
|
|
case SOP_DEC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dec_byte_simple,t_DECb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_dec_byte);
|
|
|
|
break;
|
|
|
|
case SOP_NOT:
|
|
|
|
gen_call_function_raw((void*)&dynrec_not_byte);
|
|
|
|
break;
|
|
|
|
case SOP_NEG:
|
|
|
|
InvalidateFlags((void*)&dynrec_neg_byte_simple,t_NEGb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_neg_byte);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_sop_byte_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_sop_word_gencall(SingleOps op,bool dword) {
|
|
|
|
if (dword) {
|
|
|
|
switch (op) {
|
|
|
|
case SOP_INC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_inc_dword_simple,t_INCd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_inc_dword);
|
|
|
|
break;
|
|
|
|
case SOP_DEC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dec_dword_simple,t_DECd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_dec_dword);
|
|
|
|
break;
|
|
|
|
case SOP_NOT:
|
|
|
|
gen_call_function_raw((void*)&dynrec_not_dword);
|
|
|
|
break;
|
|
|
|
case SOP_NEG:
|
|
|
|
InvalidateFlags((void*)&dynrec_neg_dword_simple,t_NEGd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_neg_dword);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_sop_dword_gencall");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (op) {
|
|
|
|
case SOP_INC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_inc_word_simple,t_INCw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_inc_word);
|
|
|
|
break;
|
|
|
|
case SOP_DEC:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dec_word_simple,t_DECw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_dec_word);
|
|
|
|
break;
|
|
|
|
case SOP_NOT:
|
|
|
|
gen_call_function_raw((void*)&dynrec_not_word);
|
|
|
|
break;
|
|
|
|
case SOP_NEG:
|
|
|
|
InvalidateFlags((void*)&dynrec_neg_word_simple,t_NEGw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_neg_word);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_sop_word_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0x7)) {
|
|
|
|
if (op2&0x18) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
SETFLAGBIT(CF,op1 & 1);
|
|
|
|
SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7));
|
|
|
|
}
|
|
|
|
return op1;
|
|
|
|
}
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2&0x07;
|
|
|
|
lf_resb=(lf_var1b << lf_var2b) | (lf_var1b >> (8-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resb & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7));
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0x7)) return op1;
|
|
|
|
return (op1 << (op2&0x07)) | (op1 >> (8-(op2&0x07)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0x7)) {
|
|
|
|
if (op2&0x18) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
SETFLAGBIT(CF,op1>>7);
|
|
|
|
SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1));
|
|
|
|
}
|
|
|
|
return op1;
|
|
|
|
}
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2&0x07;
|
|
|
|
lf_resb=(lf_var1b >> lf_var2b) | (lf_var1b << (8-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resb & 0x80);
|
|
|
|
SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80);
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0x7)) return op1;
|
|
|
|
return (op1 >> (op2&0x07)) | (op1 << (8-(op2&0x07)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (op2%9) {
|
|
|
|
Bit8u cf=(Bit8u)FillFlags()&0x1;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2%9;
|
|
|
|
lf_resb=(lf_var1b << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1b >> (9-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1));
|
|
|
|
SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7));
|
|
|
|
return lf_resb;
|
|
|
|
} else return op1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (op2%9) {
|
|
|
|
Bit8u cf=(Bit8u)FillFlags()&0x1;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2%9;
|
|
|
|
lf_resb=(lf_var1b >> lf_var2b) | (cf << (8-lf_var2b)) | (lf_var1b << (9-lf_var2b)); \
|
|
|
|
SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80);
|
|
|
|
return lf_resb;
|
|
|
|
} else return op1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b << lf_var2b;
|
|
|
|
lflags.type=t_SHLb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 << op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resb=lf_var1b >> lf_var2b;
|
|
|
|
lflags.type=t_SHRb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1b=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
if (lf_var2b>8) lf_var2b=8;
|
|
|
|
if (lf_var1b & 0x80) {
|
|
|
|
lf_resb=(lf_var1b >> lf_var2b)| (0xff << (8 - lf_var2b));
|
|
|
|
} else {
|
|
|
|
lf_resb=lf_var1b >> lf_var2b;
|
|
|
|
}
|
|
|
|
lflags.type=t_SARb;
|
|
|
|
return lf_resb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
if (op2>8) op2=8;
|
|
|
|
if (op1 & 0x80) return (op1 >> op2) | (0xff << (8 - op2));
|
|
|
|
else return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0xf)) {
|
|
|
|
if (op2&0x10) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
SETFLAGBIT(CF,op1 & 1);
|
|
|
|
SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15));
|
|
|
|
}
|
|
|
|
return op1;
|
|
|
|
}
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2&0xf;
|
|
|
|
lf_resw=(lf_var1w << lf_var2b) | (lf_var1w >> (16-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resw & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15));
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0xf)) return op1;
|
|
|
|
return (op1 << (op2&0xf)) | (op1 >> (16-(op2&0xf)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0xf)) {
|
|
|
|
if (op2&0x10) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
SETFLAGBIT(CF,op1>>15);
|
|
|
|
SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1));
|
|
|
|
}
|
|
|
|
return op1;
|
|
|
|
}
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2&0xf;
|
|
|
|
lf_resw=(lf_var1w >> lf_var2b) | (lf_var1w << (16-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resw & 0x8000);
|
|
|
|
SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000);
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!(op2&0xf)) return op1;
|
|
|
|
return (op1 >> (op2&0xf)) | (op1 << (16-(op2&0xf)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (op2%17) {
|
|
|
|
Bit16u cf=(Bit16u)FillFlags()&0x1;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2%17;
|
|
|
|
lf_resw=(lf_var1w << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1w >> (17-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1));
|
|
|
|
SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15));
|
|
|
|
return lf_resw;
|
|
|
|
} else return op1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (op2%17) {
|
|
|
|
Bit16u cf=(Bit16u)FillFlags()&0x1;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2%17;
|
|
|
|
lf_resw=(lf_var1w >> lf_var2b) | (cf << (16-lf_var2b)) | (lf_var1w << (17-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000);
|
|
|
|
return lf_resw;
|
|
|
|
} else return op1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resw=lf_var1w << lf_var2b;
|
|
|
|
lflags.type=t_SHLw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 << op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resw=lf_var1w >> lf_var2b;
|
|
|
|
lflags.type=t_SHRw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1w=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
if (lf_var2b>16) lf_var2b=16;
|
|
|
|
if (lf_var1w & 0x8000) {
|
|
|
|
lf_resw=(lf_var1w >> lf_var2b) | (0xffff << (16 - lf_var2b));
|
|
|
|
} else {
|
|
|
|
lf_resw=lf_var1w >> lf_var2b;
|
|
|
|
}
|
|
|
|
lflags.type=t_SARw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
if (op2>16) op2=16;
|
|
|
|
if (op1 & 0x8000) return (op1 >> op2) | (0xffff << (16 - op2));
|
|
|
|
else return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resd=(lf_var1d << lf_var2b) | (lf_var1d >> (32-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resd & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31));
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return (op1 << op2) | (op1 >> (32-op2));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resd=(lf_var1d >> lf_var2b) | (lf_var1d << (32-lf_var2b));
|
|
|
|
SETFLAGBIT(CF,lf_resd & 0x80000000);
|
|
|
|
SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000);
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return (op1 >> op2) | (op1 << (32-op2));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
Bit32u cf=(Bit32u)FillFlags()&0x1;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
if (lf_var2b==1) {
|
|
|
|
lf_resd=(lf_var1d << 1) | cf;
|
|
|
|
} else {
|
|
|
|
lf_resd=(lf_var1d << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1d >> (33-lf_var2b));
|
|
|
|
}
|
|
|
|
SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1));
|
|
|
|
SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31));
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (op2) {
|
|
|
|
Bit32u cf=(Bit32u)FillFlags()&0x1;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
if (lf_var2b==1) {
|
|
|
|
lf_resd=lf_var1d >> 1 | cf << 31;
|
|
|
|
} else {
|
|
|
|
lf_resd=(lf_var1d >> lf_var2b) | (cf << (32-lf_var2b)) | (lf_var1d << (33-lf_var2b));
|
|
|
|
}
|
|
|
|
SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1);
|
|
|
|
SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000);
|
|
|
|
return lf_resd;
|
|
|
|
} else return op1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resd=lf_var1d << lf_var2b;
|
|
|
|
lflags.type=t_SHLd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 << op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_resd=lf_var1d >> lf_var2b;
|
|
|
|
lflags.type=t_SHRd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
lf_var2b=op2;
|
|
|
|
lf_var1d=op1;
|
|
|
|
if (lf_var1d & 0x80000000) {
|
|
|
|
lf_resd=(lf_var1d >> lf_var2b) | (0xffffffff << (32 - lf_var2b));
|
|
|
|
} else {
|
|
|
|
lf_resd=lf_var1d >> lf_var2b;
|
|
|
|
}
|
|
|
|
lflags.type=t_SARd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) {
|
|
|
|
if (!op2) return op1;
|
|
|
|
if (op1 & 0x80000000) return (op1 >> op2) | (0xffffffff << (32 - op2));
|
|
|
|
else return op1 >> op2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_shift_byte_gencall(ShiftOps op) {
|
|
|
|
switch (op) {
|
|
|
|
case SHIFT_ROL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_rol_byte_simple,t_ROLb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rol_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_ROR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_ror_byte_simple,t_RORb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_ror_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCL:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcl_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCR:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcr_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHL:
|
|
|
|
case SHIFT_SAL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shl_byte_simple,t_SHLb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shl_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shr_byte_simple,t_SHRb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shr_byte);
|
|
|
|
break;
|
|
|
|
case SHIFT_SAR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sar_byte_simple,t_SARb);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sar_byte);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_shift_byte_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_shift_word_gencall(ShiftOps op,bool dword) {
|
|
|
|
if (dword) {
|
|
|
|
switch (op) {
|
|
|
|
case SHIFT_ROL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_rol_dword_simple,t_ROLd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rol_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_ROR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_ror_dword_simple,t_RORd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_ror_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCL:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcl_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCR:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcr_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHL:
|
|
|
|
case SHIFT_SAL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shl_dword_simple,t_SHLd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shl_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shr_dword_simple,t_SHRd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shr_dword);
|
|
|
|
break;
|
|
|
|
case SHIFT_SAR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sar_dword_simple,t_SARd);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sar_dword);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_shift_dword_gencall");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (op) {
|
|
|
|
case SHIFT_ROL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_rol_word_simple,t_ROLw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rol_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_ROR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_ror_word_simple,t_RORw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_ror_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCL:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcl_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_RCR:
|
|
|
|
AcquireFlags(FLAG_CF);
|
|
|
|
gen_call_function_raw((void*)&dynrec_rcr_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHL:
|
|
|
|
case SHIFT_SAL:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shl_word_simple,t_SHLw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shl_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_SHR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_shr_word_simple,t_SHRw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_shr_word);
|
|
|
|
break;
|
|
|
|
case SHIFT_SAR:
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_sar_word_simple,t_SARw);
|
|
|
|
gen_call_function_raw((void*)&dynrec_sar_word);
|
|
|
|
break;
|
|
|
|
default: IllegalOptionDynrec("dyn_shift_word_gencall");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
lf_var2b=val;
|
|
|
|
lf_var1d=(op1<<16)|op2;
|
|
|
|
Bit32u tempd=lf_var1d << lf_var2b;
|
|
|
|
if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16));
|
|
|
|
lf_resw=(Bit16u)(tempd >> 16);
|
|
|
|
lflags.type=t_DSHLw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
Bit32u tempd=(Bit32u)((((Bit32u)op1)<<16)|op2) << val;
|
|
|
|
if (val>16) tempd |= (op2 << (val - 16));
|
|
|
|
return (Bit16u)(tempd >> 16);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
lf_var2b=val;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b));
|
|
|
|
lflags.type=t_DSHLd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
return (op1 << val) | (op2 >> (32-val));
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
lf_var2b=val;
|
|
|
|
lf_var1d=(op2<<16)|op1;
|
|
|
|
Bit32u tempd=lf_var1d >> lf_var2b;
|
|
|
|
if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b ));
|
|
|
|
lf_resw=(Bit16u)(tempd);
|
|
|
|
lflags.type=t_DSHRw;
|
|
|
|
return lf_resw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
Bit32u tempd=(Bit32u)((((Bit32u)op2)<<16)|op1) >> val;
|
|
|
|
if (val>16) tempd |= (op2 << (32-val));
|
|
|
|
return (Bit16u)(tempd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
lf_var2b=val;
|
|
|
|
lf_var1d=op1;
|
|
|
|
lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b));
|
|
|
|
lflags.type=t_DSHRd;
|
|
|
|
return lf_resd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) {
|
|
|
|
Bit8u val=op3 & 0x1f;
|
|
|
|
if (!val) return op1;
|
|
|
|
return (op1 >> val) | (op2 << (32-val));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_dpshift_word_gencall(bool left) {
|
|
|
|
if (left) {
|
|
|
|
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_OP3);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dshl_word_simple,proc_addr,t_DSHLw);
|
|
|
|
} else {
|
|
|
|
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_OP3);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dshr_word_simple,proc_addr,t_DSHRw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dyn_dpshift_dword_gencall(bool left) {
|
|
|
|
if (left) {
|
|
|
|
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_OP3);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dshl_dword_simple,proc_addr,t_DSHLd);
|
|
|
|
} else {
|
|
|
|
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_OP3);
|
|
|
|
InvalidateFlagsPartially((void*)&dynrec_dshr_dword_simple,proc_addr,t_DSHRd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_of(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_of(void) { return TFLG_O; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nof(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nof(void) { return TFLG_NO; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_cf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_cf(void) { return TFLG_B; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) { return TFLG_NB; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_zf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_zf(void) { return TFLG_Z; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) { return TFLG_NZ; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf(void) { return TFLG_S; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) { return TFLG_NS; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_pf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_pf(void) { return TFLG_P; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_npf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_npf(void) { return TFLG_NP; }
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) { return TFLG_BE; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) { return TFLG_NBE; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) { return TFLG_L; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) { return TFLG_NL; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) { return TFLG_LE; }
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) { return TFLG_NLE; }
|
|
|
|
|
|
|
|
|
|
|
|
static void dyn_branchflag_to_reg(BranchTypes btype) {
|
|
|
|
switch (btype) {
|
|
|
|
case BR_O:gen_call_function_raw((void*)&dynrec_get_of);break;
|
|
|
|
case BR_NO:gen_call_function_raw((void*)&dynrec_get_nof);break;
|
|
|
|
case BR_B:gen_call_function_raw((void*)&dynrec_get_cf);break;
|
|
|
|
case BR_NB:gen_call_function_raw((void*)&dynrec_get_ncf);break;
|
|
|
|
case BR_Z:gen_call_function_raw((void*)&dynrec_get_zf);break;
|
|
|
|
case BR_NZ:gen_call_function_raw((void*)&dynrec_get_nzf);break;
|
|
|
|
case BR_BE:gen_call_function_raw((void*)&dynrec_get_cf_or_zf);break;
|
|
|
|
case BR_NBE:gen_call_function_raw((void*)&dynrec_get_ncf_and_nzf);break;
|
|
|
|
|
|
|
|
case BR_S:gen_call_function_raw((void*)&dynrec_get_sf);break;
|
|
|
|
case BR_NS:gen_call_function_raw((void*)&dynrec_get_nsf);break;
|
|
|
|
case BR_P:gen_call_function_raw((void*)&dynrec_get_pf);break;
|
|
|
|
case BR_NP:gen_call_function_raw((void*)&dynrec_get_npf);break;
|
|
|
|
case BR_L:gen_call_function_raw((void*)&dynrec_get_sf_neq_of);break;
|
|
|
|
case BR_NL:gen_call_function_raw((void*)&dynrec_get_sf_eq_of);break;
|
|
|
|
case BR_LE:gen_call_function_raw((void*)&dynrec_get_zf_or_sf_neq_of);break;
|
|
|
|
case BR_NLE:gen_call_function_raw((void*)&dynrec_get_nzf_and_sf_eq_of);break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
reg_ax=reg_al*op;
|
|
|
|
SETFLAGBIT(ZF,reg_al == 0);
|
|
|
|
if (reg_ax & 0xff00) {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
reg_ax=((Bit8s)reg_al) * ((Bit8s)op);
|
|
|
|
if ((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bitu tempu=(Bitu)reg_ax*(Bitu)op;
|
|
|
|
reg_ax=(Bit16u)(tempu);
|
|
|
|
reg_dx=(Bit16u)(tempu >> 16);
|
|
|
|
SETFLAGBIT(ZF,reg_ax == 0);
|
|
|
|
if (reg_dx) {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bits temps=((Bit16s)reg_ax)*((Bit16s)op);
|
|
|
|
reg_ax=(Bit16s)(temps);
|
|
|
|
reg_dx=(Bit16s)(temps >> 16);
|
|
|
|
if (((temps & 0xffff8000)==0xffff8000 || (temps & 0xffff8000)==0x0000)) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bit64u tempu=(Bit64u)reg_eax*(Bit64u)op;
|
|
|
|
reg_eax=(Bit32u)(tempu);
|
|
|
|
reg_edx=(Bit32u)(tempu >> 32);
|
|
|
|
SETFLAGBIT(ZF,reg_eax == 0);
|
|
|
|
if (reg_edx) {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bit64s temps=((Bit64s)((Bit32s)reg_eax))*((Bit64s)((Bit32s)op));
|
|
|
|
reg_eax=(Bit32u)(temps);
|
|
|
|
reg_edx=(Bit32u)(temps >> 32);
|
|
|
|
if ((reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else if ( (reg_edx==0x00000000) && (reg_eax< 0x80000000) ) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) {
|
|
|
|
Bitu val=op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bitu quo=reg_ax / val;
|
|
|
|
Bit8u rem=(Bit8u)(reg_ax % val);
|
|
|
|
Bit8u quo8=(Bit8u)(quo&0xff);
|
|
|
|
if (quo>0xff) return CPU_PrepareException(0,0);
|
|
|
|
reg_ah=rem;
|
|
|
|
reg_al=quo8;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) {
|
|
|
|
Bits val=(Bit8s)op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bits quo=((Bit16s)reg_ax) / val;
|
|
|
|
Bit8s rem=(Bit8s)((Bit16s)reg_ax % val);
|
|
|
|
Bit8s quo8s=(Bit8s)(quo&0xff);
|
|
|
|
if (quo!=(Bit16s)quo8s) return CPU_PrepareException(0,0);
|
|
|
|
reg_ah=rem;
|
|
|
|
reg_al=quo8s;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) {
|
|
|
|
Bitu val=op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bitu num=((Bit32u)reg_dx<<16)|reg_ax;
|
|
|
|
Bitu quo=num/val;
|
|
|
|
Bit16u rem=(Bit16u)(num % val);
|
|
|
|
Bit16u quo16=(Bit16u)(quo&0xffff);
|
|
|
|
if (quo!=(Bit32u)quo16) return CPU_PrepareException(0,0);
|
|
|
|
reg_dx=rem;
|
|
|
|
reg_ax=quo16;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) {
|
|
|
|
Bits val=(Bit16s)op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bits num=(Bit32s)((reg_dx<<16)|reg_ax);
|
|
|
|
Bits quo=num/val;
|
|
|
|
Bit16s rem=(Bit16s)(num % val);
|
|
|
|
Bit16s quo16s=(Bit16s)quo;
|
|
|
|
if (quo!=(Bit32s)quo16s) return CPU_PrepareException(0,0);
|
|
|
|
reg_dx=rem;
|
|
|
|
reg_ax=quo16s;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) {
|
|
|
|
Bitu val=op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
|
|
|
Bit64u quo=num/val;
|
|
|
|
Bit32u rem=(Bit32u)(num % val);
|
|
|
|
Bit32u quo32=(Bit32u)(quo&0xffffffff);
|
|
|
|
if (quo!=(Bit64u)quo32) return CPU_PrepareException(0,0);
|
|
|
|
reg_edx=rem;
|
|
|
|
reg_eax=quo32;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) DRC_FC;
|
|
|
|
static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) {
|
|
|
|
Bits val=(Bit32s)op;
|
|
|
|
if (val==0) return CPU_PrepareException(0,0);
|
|
|
|
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
|
|
|
Bit64s quo=num/val;
|
|
|
|
Bit32s rem=(Bit32s)(num % val);
|
|
|
|
Bit32s quo32s=(Bit32s)(quo&0xffffffff);
|
|
|
|
if (quo!=(Bit64s)quo32s) return CPU_PrepareException(0,0);
|
|
|
|
reg_edx=rem;
|
|
|
|
reg_eax=quo32s;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bits res=((Bit16s)op1) * ((Bit16s)op2);
|
|
|
|
if ((res>-32768) && (res<32767)) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
}
|
|
|
|
return (Bit16u)(res & 0xffff);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) {
|
|
|
|
FillFlagsNoCFOF();
|
|
|
|
Bit64s res=((Bit64s)((Bit32s)op1))*((Bit64s)((Bit32s)op2));
|
|
|
|
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
SETFLAGBIT(OF,false);
|
|
|
|
} else {
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
SETFLAGBIT(OF,true);
|
|
|
|
}
|
|
|
|
return (Bit32s)res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) {
|
|
|
|
return (Bit8s)op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) {
|
|
|
|
return (Bit16s)op;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) {
|
|
|
|
if (op & 0x8000) return 0xffff;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) {
|
|
|
|
if (op & 0x80000000) return 0xffffffff;
|
|
|
|
else return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_sahf(Bit16u op) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_sahf(Bit16u op) {
|
|
|
|
SETFLAGBIT(OF,get_OF());
|
|
|
|
lflags.type=t_UNKNOWN;
|
|
|
|
CPU_SetFlags(op>>8,FMASK_NORMAL & 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_cmc(void) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cmc(void) {
|
|
|
|
FillFlags();
|
|
|
|
SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
|
|
|
|
}
|
|
|
|
static void DRC_CALL_CONV dynrec_clc(void) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_clc(void) {
|
|
|
|
FillFlags();
|
|
|
|
SETFLAGBIT(CF,false);
|
|
|
|
}
|
|
|
|
static void DRC_CALL_CONV dynrec_stc(void) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_stc(void) {
|
|
|
|
FillFlags();
|
|
|
|
SETFLAGBIT(CF,true);
|
|
|
|
}
|
|
|
|
static void DRC_CALL_CONV dynrec_cld(void) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_cld(void) {
|
|
|
|
SETFLAGBIT(DF,false);
|
|
|
|
cpu.direction=1;
|
|
|
|
}
|
|
|
|
static void DRC_CALL_CONV dynrec_std(void) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_std(void) {
|
|
|
|
SETFLAGBIT(DF,true);
|
|
|
|
cpu.direction=-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writeb(di_base+reg_di,mem_readb(si_base+reg_si));
|
|
|
|
reg_si+=add_index;
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writeb(di_base+reg_edi,mem_readb(si_base+reg_esi));
|
|
|
|
reg_esi+=add_index;
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writew(di_base+reg_di,mem_readw(si_base+reg_si));
|
|
|
|
reg_si+=add_index;
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writew(di_base+reg_edi,mem_readw(si_base+reg_esi));
|
|
|
|
reg_esi+=add_index;
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writed(di_base+reg_di,mem_readd(si_base+reg_si));
|
|
|
|
reg_si+=add_index;
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writed(di_base+reg_edi,mem_readd(si_base+reg_esi));
|
|
|
|
reg_esi+=add_index;
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_al=mem_readb(si_base+reg_si);
|
|
|
|
reg_si+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_al=mem_readb(si_base+reg_esi);
|
|
|
|
reg_esi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_ax=mem_readw(si_base+reg_si);
|
|
|
|
reg_si+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_ax=mem_readw(si_base+reg_esi);
|
|
|
|
reg_esi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_eax=mem_readd(si_base+reg_si);
|
|
|
|
reg_si+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
reg_eax=mem_readd(si_base+reg_esi);
|
|
|
|
reg_esi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writeb(di_base+reg_di,reg_al);
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writeb(di_base+reg_edi,reg_al);
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writew(di_base+reg_di,reg_ax);
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=1;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writew(di_base+reg_edi,reg_ax);
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) {
|
|
|
|
Bit16u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=(Bit16u)(count-CPU_Cycles);
|
|
|
|
count=(Bit16u)CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writed(di_base+reg_di,reg_eax);
|
|
|
|
reg_di+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) {
|
|
|
|
Bit32u count_left;
|
|
|
|
if (count<(Bitu)CPU_Cycles) {
|
|
|
|
count_left=0;
|
|
|
|
} else {
|
|
|
|
count_left=count-CPU_Cycles;
|
|
|
|
count=CPU_Cycles;
|
|
|
|
CPU_Cycles=0;
|
|
|
|
}
|
|
|
|
add_index<<=2;
|
|
|
|
for (;count>0;count--) {
|
|
|
|
mem_writed(di_base+reg_edi,reg_eax);
|
|
|
|
reg_edi+=add_index;
|
|
|
|
}
|
|
|
|
return count_left;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_push_word(Bit16u value) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_push_word(Bit16u value) {
|
|
|
|
Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask);
|
|
|
|
mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask),value);
|
|
|
|
reg_esp=new_esp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) DRC_FC;
|
|
|
|
static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) {
|
|
|
|
Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask);
|
|
|
|
mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value);
|
|
|
|
reg_esp=new_esp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_pop_word(void) DRC_FC;
|
|
|
|
static Bit16u DRC_CALL_CONV dynrec_pop_word(void) {
|
|
|
|
Bit16u val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
|
|
|
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask);
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) DRC_FC;
|
|
|
|
static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) {
|
|
|
|
Bit32u val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
|
|
|
reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
|
|
|
|
return val;
|
|
|
|
}
|