mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
more complete ARM shift fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1168 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
88920f344d
commit
1e8d4eec48
2 changed files with 70 additions and 7 deletions
|
@ -463,6 +463,7 @@ void OPPROTO op_swpl_T0_T1(void)
|
||||||
/* shifts */
|
/* shifts */
|
||||||
|
|
||||||
/* T1 based */
|
/* T1 based */
|
||||||
|
|
||||||
void OPPROTO op_shll_T1_im(void)
|
void OPPROTO op_shll_T1_im(void)
|
||||||
{
|
{
|
||||||
T1 = T1 << PARAM1;
|
T1 = T1 << PARAM1;
|
||||||
|
@ -473,11 +474,21 @@ void OPPROTO op_shrl_T1_im(void)
|
||||||
T1 = (uint32_t)T1 >> PARAM1;
|
T1 = (uint32_t)T1 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_shrl_T1_0(void)
|
||||||
|
{
|
||||||
|
T1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_sarl_T1_im(void)
|
void OPPROTO op_sarl_T1_im(void)
|
||||||
{
|
{
|
||||||
T1 = (int32_t)T1 >> PARAM1;
|
T1 = (int32_t)T1 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_sarl_T1_0(void)
|
||||||
|
{
|
||||||
|
T1 = (int32_t)T1 >> 31;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_rorl_T1_im(void)
|
void OPPROTO op_rorl_T1_im(void)
|
||||||
{
|
{
|
||||||
int shift;
|
int shift;
|
||||||
|
@ -503,12 +514,24 @@ void OPPROTO op_shrl_T1_im_cc(void)
|
||||||
T1 = (uint32_t)T1 >> PARAM1;
|
T1 = (uint32_t)T1 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_shrl_T1_0_cc(void)
|
||||||
|
{
|
||||||
|
env->CF = (T1 >> 31) & 1;
|
||||||
|
T1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_sarl_T1_im_cc(void)
|
void OPPROTO op_sarl_T1_im_cc(void)
|
||||||
{
|
{
|
||||||
env->CF = (T1 >> (PARAM1 - 1)) & 1;
|
env->CF = (T1 >> (PARAM1 - 1)) & 1;
|
||||||
T1 = (int32_t)T1 >> PARAM1;
|
T1 = (int32_t)T1 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_sarl_T1_0_cc(void)
|
||||||
|
{
|
||||||
|
env->CF = (T1 >> 31) & 1;
|
||||||
|
T1 = (int32_t)T1 >> 31;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_rorl_T1_im_cc(void)
|
void OPPROTO op_rorl_T1_im_cc(void)
|
||||||
{
|
{
|
||||||
int shift;
|
int shift;
|
||||||
|
@ -536,11 +559,21 @@ void OPPROTO op_shrl_T2_im(void)
|
||||||
T2 = (uint32_t)T2 >> PARAM1;
|
T2 = (uint32_t)T2 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_shrl_T2_0(void)
|
||||||
|
{
|
||||||
|
T2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_sarl_T2_im(void)
|
void OPPROTO op_sarl_T2_im(void)
|
||||||
{
|
{
|
||||||
T2 = (int32_t)T2 >> PARAM1;
|
T2 = (int32_t)T2 >> PARAM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_sarl_T2_0(void)
|
||||||
|
{
|
||||||
|
T2 = (int32_t)T2 >> 31;
|
||||||
|
}
|
||||||
|
|
||||||
void OPPROTO op_rorl_T2_im(void)
|
void OPPROTO op_rorl_T2_im(void)
|
||||||
{
|
{
|
||||||
int shift;
|
int shift;
|
||||||
|
@ -548,6 +581,11 @@ void OPPROTO op_rorl_T2_im(void)
|
||||||
T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
|
T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_rrxl_T2(void)
|
||||||
|
{
|
||||||
|
T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
|
||||||
|
}
|
||||||
|
|
||||||
/* T1 based, use T0 as shift count */
|
/* T1 based, use T0 as shift count */
|
||||||
|
|
||||||
void OPPROTO op_shll_T1_T0(void)
|
void OPPROTO op_shll_T1_T0(void)
|
||||||
|
|
|
@ -94,6 +94,13 @@ static GenOpFunc1 *gen_shift_T1_im[4] = {
|
||||||
gen_op_rorl_T1_im,
|
gen_op_rorl_T1_im,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GenOpFunc *gen_shift_T1_0[4] = {
|
||||||
|
NULL,
|
||||||
|
gen_op_shrl_T1_0,
|
||||||
|
gen_op_sarl_T1_0,
|
||||||
|
gen_op_rrxl_T1,
|
||||||
|
};
|
||||||
|
|
||||||
static GenOpFunc1 *gen_shift_T2_im[4] = {
|
static GenOpFunc1 *gen_shift_T2_im[4] = {
|
||||||
gen_op_shll_T2_im,
|
gen_op_shll_T2_im,
|
||||||
gen_op_shrl_T2_im,
|
gen_op_shrl_T2_im,
|
||||||
|
@ -101,6 +108,13 @@ static GenOpFunc1 *gen_shift_T2_im[4] = {
|
||||||
gen_op_rorl_T2_im,
|
gen_op_rorl_T2_im,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GenOpFunc *gen_shift_T2_0[4] = {
|
||||||
|
NULL,
|
||||||
|
gen_op_shrl_T2_0,
|
||||||
|
gen_op_sarl_T2_0,
|
||||||
|
gen_op_rrxl_T2,
|
||||||
|
};
|
||||||
|
|
||||||
static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
|
static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
|
||||||
gen_op_shll_T1_im_cc,
|
gen_op_shll_T1_im_cc,
|
||||||
gen_op_shrl_T1_im_cc,
|
gen_op_shrl_T1_im_cc,
|
||||||
|
@ -108,6 +122,13 @@ static GenOpFunc1 *gen_shift_T1_im_cc[4] = {
|
||||||
gen_op_rorl_T1_im_cc,
|
gen_op_rorl_T1_im_cc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GenOpFunc *gen_shift_T1_0_cc[4] = {
|
||||||
|
NULL,
|
||||||
|
gen_op_shrl_T1_0_cc,
|
||||||
|
gen_op_sarl_T1_0_cc,
|
||||||
|
gen_op_rrxl_T1_cc,
|
||||||
|
};
|
||||||
|
|
||||||
static GenOpFunc *gen_shift_T1_T0[4] = {
|
static GenOpFunc *gen_shift_T1_T0[4] = {
|
||||||
gen_op_shll_T1_T0,
|
gen_op_shll_T1_T0,
|
||||||
gen_op_shrl_T1_T0,
|
gen_op_shrl_T1_T0,
|
||||||
|
@ -272,7 +293,7 @@ static inline void gen_movl_reg_T1(DisasContext *s, int reg)
|
||||||
|
|
||||||
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
|
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
|
||||||
{
|
{
|
||||||
int val, rm, shift;
|
int val, rm, shift, shiftop;
|
||||||
|
|
||||||
if (!(insn & (1 << 25))) {
|
if (!(insn & (1 << 25))) {
|
||||||
/* immediate */
|
/* immediate */
|
||||||
|
@ -286,8 +307,11 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
|
||||||
rm = (insn) & 0xf;
|
rm = (insn) & 0xf;
|
||||||
shift = (insn >> 7) & 0x1f;
|
shift = (insn >> 7) & 0x1f;
|
||||||
gen_movl_T2_reg(s, rm);
|
gen_movl_T2_reg(s, rm);
|
||||||
|
shiftop = (insn >> 5) & 3;
|
||||||
if (shift != 0) {
|
if (shift != 0) {
|
||||||
gen_shift_T2_im[(insn >> 5) & 3](shift);
|
gen_shift_T2_im[shiftop](shift);
|
||||||
|
} else if (shiftop != 0) {
|
||||||
|
gen_shift_T2_0[shiftop]();
|
||||||
}
|
}
|
||||||
if (!(insn & (1 << 23)))
|
if (!(insn & (1 << 23)))
|
||||||
gen_op_subl_T1_T2();
|
gen_op_subl_T1_T2();
|
||||||
|
@ -365,11 +389,12 @@ static void disas_arm_insn(DisasContext *s)
|
||||||
} else {
|
} else {
|
||||||
gen_shift_T1_im[shiftop](shift);
|
gen_shift_T1_im[shiftop](shift);
|
||||||
}
|
}
|
||||||
} else if (shiftop == 3) {
|
} else if (shiftop != 0) {
|
||||||
if (logic_cc)
|
if (logic_cc) {
|
||||||
gen_op_rrxl_T1_cc();
|
gen_shift_T1_0_cc[shiftop]();
|
||||||
else
|
} else {
|
||||||
gen_op_rrxl_T1();
|
gen_shift_T1_0[shiftop]();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rs = (insn >> 8) & 0xf;
|
rs = (insn >> 8) & 0xf;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue