提交 1e8d4eec 编写于 作者: B bellard

more complete ARM shift fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1168 c046a42c-6fe2-441c-8c8c-71466251a162
上级 88920f34
...@@ -463,6 +463,7 @@ void OPPROTO op_swpl_T0_T1(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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] = { ...@@ -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] = { ...@@ -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] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册