Arm saturating arithmetic bugs.
PATCH 1/1 Arm saturating arithmetic bugs.
The patch below fixes a couple of bugs in the arm saturating arithmetic instructions. It uses the correct registers, and makes sure the intermediate result is saturated properly.
Paul
? target-arm/p
Index: target-arm/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/op.c,v
retrieving revision 1.13
op.c +17 -0
@@ -805,6 +805,23 @@ void OPPROTO op_subl_T0_T1_saturate(voidFORCE_RET (); } +void OPPROTO op_double_T1_saturate(void) +{ +int32_t val; + + val =T1 ; +if (val >=0x40000000 ) { +T1 =0x7fffffff ; + env->QF =1 ; + }else if (val <= (int32_t )0xc0000000 ) { +T1 =0x80000000 ; + env->QF =1 ; + }else { +T1 = val <<1 ; + } +FORCE_RET (); +} +/* thumb shift by immediate */ void OPPROTO op_shll_T0_im_thumb(void) {
Index: target-arm/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-arm/translate.c,v retrieving revision 1.24
translate.c +5 -10
@@ -1019,20 +1019,15 @@ static void disas_arm_insn(CPUState * encase 0x5 :/* saturating add/subtract */ rd = (insn >>12 ) &0xf ; rn = (insn >>16 ) &0xf ; -gen_movl_T0_reg (s, rn); -if (op1 &2 ) { -gen_movl_T1_reg (s, rn); -if (op1 &1 ) -gen_op_subl_T0_T1_saturate (); -else -gen_op_addl_T0_T1_saturate (); - } -gen_movl_T1_reg (s, rm); +gen_movl_T0_reg (s, rm); +gen_movl_T1_reg (s, rn); +if (op1 &2 ) +gen_op_double_T1_saturate ();if (op1 &1 )gen_op_subl_T0_T1_saturate ();else gen_op_addl_T0_T1_saturate (); -gen_movl_reg_T0 (s, rn); +gen_movl_reg_T0 (s, rd);break ;case 0x8 :/* signed multiply */ case 0xa :