Commit ff8263a951c5ce22bef919c792d20e5cbf5066b3
1 parent
04d81be8
ARM saturating arithmetic fixes (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1431 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
22 additions
and
10 deletions
target-arm/op.c
@@ -805,6 +805,23 @@ void OPPROTO op_subl_T0_T1_saturate(void) | @@ -805,6 +805,23 @@ void OPPROTO op_subl_T0_T1_saturate(void) | ||
805 | FORCE_RET(); | 805 | FORCE_RET(); |
806 | } | 806 | } |
807 | 807 | ||
808 | +void OPPROTO op_double_T1_saturate(void) | ||
809 | +{ | ||
810 | + int32_t val; | ||
811 | + | ||
812 | + val = T1; | ||
813 | + if (val >= 0x40000000) { | ||
814 | + T1 = 0x7fffffff; | ||
815 | + env->QF = 1; | ||
816 | + } else if (val <= (int32_t)0xc0000000) { | ||
817 | + T1 = 0x80000000; | ||
818 | + env->QF = 1; | ||
819 | + } else { | ||
820 | + T1 = val << 1; | ||
821 | + } | ||
822 | + FORCE_RET(); | ||
823 | +} | ||
824 | + | ||
808 | /* thumb shift by immediate */ | 825 | /* thumb shift by immediate */ |
809 | void OPPROTO op_shll_T0_im_thumb(void) | 826 | void OPPROTO op_shll_T0_im_thumb(void) |
810 | { | 827 | { |
target-arm/translate.c
@@ -1019,20 +1019,15 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -1019,20 +1019,15 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
1019 | case 0x5: /* saturating add/subtract */ | 1019 | case 0x5: /* saturating add/subtract */ |
1020 | rd = (insn >> 12) & 0xf; | 1020 | rd = (insn >> 12) & 0xf; |
1021 | rn = (insn >> 16) & 0xf; | 1021 | rn = (insn >> 16) & 0xf; |
1022 | - gen_movl_T0_reg(s, rn); | ||
1023 | - if (op1 & 2) { | ||
1024 | - gen_movl_T1_reg(s, rn); | ||
1025 | - if (op1 & 1) | ||
1026 | - gen_op_subl_T0_T1_saturate(); | ||
1027 | - else | ||
1028 | - gen_op_addl_T0_T1_saturate(); | ||
1029 | - } | ||
1030 | - gen_movl_T1_reg(s, rm); | 1022 | + gen_movl_T0_reg(s, rm); |
1023 | + gen_movl_T1_reg(s, rn); | ||
1024 | + if (op1 & 2) | ||
1025 | + gen_op_double_T1_saturate(); | ||
1031 | if (op1 & 1) | 1026 | if (op1 & 1) |
1032 | gen_op_subl_T0_T1_saturate(); | 1027 | gen_op_subl_T0_T1_saturate(); |
1033 | else | 1028 | else |
1034 | gen_op_addl_T0_T1_saturate(); | 1029 | gen_op_addl_T0_T1_saturate(); |
1035 | - gen_movl_reg_T0(s, rn); | 1030 | + gen_movl_reg_T0(s, rd); |
1036 | break; | 1031 | break; |
1037 | case 0x8: /* signed multiply */ | 1032 | case 0x8: /* signed multiply */ |
1038 | case 0xa: | 1033 | case 0xa: |