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 | 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 | 825 | /* thumb shift by immediate */ |
809 | 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 | 1019 | case 0x5: /* saturating add/subtract */ |
1020 | 1020 | rd = (insn >> 12) & 0xf; |
1021 | 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 | 1026 | if (op1 & 1) |
1032 | 1027 | gen_op_subl_T0_T1_saturate(); |
1033 | 1028 | else |
1034 | 1029 | gen_op_addl_T0_T1_saturate(); |
1035 | - gen_movl_reg_T0(s, rn); | |
1030 | + gen_movl_reg_T0(s, rd); | |
1036 | 1031 | break; |
1037 | 1032 | case 0x8: /* signed multiply */ |
1038 | 1033 | case 0xa: | ... | ... |