diff --git a/target/arm/translate.c b/target/arm/translate.c
index 66cf28c8cb..eb25895876 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3970,6 +3970,7 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                         tcg_gen_or_i32(tmp, tmp, tmp2);
                         tcg_temp_free_i32(tmp2);
                         gen_vfp_msr(tmp);
+                        dp = 0; /* always a single precision result */
                         break;
                     }
                     case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
@@ -3993,20 +3994,25 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                         tcg_gen_or_i32(tmp, tmp, tmp2);
                         tcg_temp_free_i32(tmp2);
                         gen_vfp_msr(tmp);
+                        dp = 0; /* always a single precision result */
                         break;
                     }
                     case 8: /* cmp */
                         gen_vfp_cmp(dp);
+                        dp = -1; /* no write back */
                         break;
                     case 9: /* cmpe */
                         gen_vfp_cmpe(dp);
+                        dp = -1; /* no write back */
                         break;
                     case 10: /* cmpz */
                         gen_vfp_cmp(dp);
+                        dp = -1; /* no write back */
                         break;
                     case 11: /* cmpez */
                         gen_vfp_F1_ld0(dp);
                         gen_vfp_cmpe(dp);
+                        dp = -1; /* no write back */
                         break;
                     case 12: /* vrintr */
                     {
@@ -4047,10 +4053,12 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                         break;
                     }
                     case 15: /* single<->double conversion */
-                        if (dp)
+                        if (dp) {
                             gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
-                        else
+                        } else {
                             gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
+                        }
+                        dp = !dp; /* result size is opposite */
                         break;
                     case 16: /* fuito */
                         gen_vfp_uito(dp, 0);
@@ -4084,15 +4092,19 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                         break;
                     case 24: /* ftoui */
                         gen_vfp_toui(dp, 0);
+                        dp = 0; /* always an integer result */
                         break;
                     case 25: /* ftouiz */
                         gen_vfp_touiz(dp, 0);
+                        dp = 0; /* always an integer result */
                         break;
                     case 26: /* ftosi */
                         gen_vfp_tosi(dp, 0);
+                        dp = 0; /* always an integer result */
                         break;
                     case 27: /* ftosiz */
                         gen_vfp_tosiz(dp, 0);
+                        dp = 0; /* always an integer result */
                         break;
                     case 28: /* ftosh */
                         if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
@@ -4126,20 +4138,8 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                     return 1;
                 }
 
-                /* Write back the result.  */
-                if (op == 15 && (rn >= 8 && rn <= 11)) {
-                    /* Comparison, do nothing.  */
-                } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
-                                              (rn & 0x1e) == 0x6)) {
-                    /* VCVT double to int: always integer result.
-                     * VCVT double to half precision is always a single
-                     * precision result.
-                     */
-                    gen_mov_vreg_F0(0, rd);
-                } else if (op == 15 && rn == 15) {
-                    /* conversion */
-                    gen_mov_vreg_F0(!dp, rd);
-                } else {
+                /* Write back the result, if any.  */
+                if (dp >= 0) {
                     gen_mov_vreg_F0(dp, rd);
                 }
 
