diff --git a/src/frontend/A32/decoder/asimd.inc b/src/frontend/A32/decoder/asimd.inc
index c5763906..51467c95 100644
--- a/src/frontend/A32/decoder/asimd.inc
+++ b/src/frontend/A32/decoder/asimd.inc
@@ -75,8 +75,8 @@ INST(asimd_VMLAL_scalar,    "VMLAL (scalar)",           "1111001U1dzznnnndddd0o1
 INST(asimd_VMUL_scalar,     "VMUL (scalar)",            "1111001Q1Dzznnnndddd100FN1M0mmmm") // ASIMD
 INST(asimd_VMULL_scalar,    "VMULL (scalar)",           "1111001U1Dzznnnndddd1010N1M0mmmm") // ASIMD
 //INST(asimd_VQDMULL_scalar,  "VQDMULL (scalar)",         "111100101-BB--------1011-1-0----") // ASIMD
-INST(asimd_VQDMULH_scalar,  "VQDMULH",                  "1111001Q1Dzznnnndddd1100N1M0mmmm") // ASIMD
-//INST(asimd_VQRDMULH_scalar, "VQRDMULH",                 "1111001U1-BB--------1101-1-0----") // ASIMD
+INST(asimd_VQDMULH_scalar,  "VQDMULH (scalar)",         "1111001Q1Dzznnnndddd1100N1M0mmmm") // ASIMD
+INST(asimd_VQRDMULH_scalar, "VQRDMULH (scalar)",        "1111001Q1Dzznnnndddd1101N1M0mmmm") // ASIMD
 
 // Two registers and a shift amount
 INST(asimd_SHR,             "SHR",                      "1111001U1Diiiiiidddd0000LQM1mmmm") // ASIMD
diff --git a/src/frontend/A32/translate/impl/asimd_two_regs_scalar.cpp b/src/frontend/A32/translate/impl/asimd_two_regs_scalar.cpp
index db859680..9e94b428 100644
--- a/src/frontend/A32/translate/impl/asimd_two_regs_scalar.cpp
+++ b/src/frontend/A32/translate/impl/asimd_two_regs_scalar.cpp
@@ -24,6 +24,11 @@ enum class MultiplyBehavior {
     MultiplySubtract,
 };
 
+enum class Rounding {
+    None,
+    Round,
+};
+
 bool ScalarMultiply(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm,
                     MultiplyBehavior multiply) {
     if (sz == 0b11) {
@@ -105,6 +110,43 @@ bool ScalarMultiplyLong(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size
     v.ir.SetVector(d, result);
     return true;
 }
+
+bool ScalarMultiplyReturnHigh(ArmTranslatorVisitor& v, bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm,
+                              Rounding round) {
+    if (sz == 0b11) {
+        // TODO: This should be a decode error.
+        return v.UndefinedInstruction();
+    }
+
+    if (sz == 0b00) {
+        return v.UndefinedInstruction();
+    }
+
+    if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn))) {
+        return v.UndefinedInstruction();
+    }
+
+    const size_t esize = 8U << sz;
+    const auto d = ToVector(Q, Vd, D);
+    const auto n = ToVector(Q, Vn, N);
+    const auto [m, index] = GetScalarLocation(esize, M, Vm);
+
+    const auto scalar = v.ir.VectorGetElement(esize, v.ir.GetVector(m), index);
+    const auto reg_n = v.ir.GetVector(n);
+    const auto reg_m = v.ir.VectorBroadcast(esize, scalar);
+    const auto result = [&] {
+        const auto tmp = v.ir.VectorSignedSaturatedDoublingMultiply(esize, reg_n, reg_m);
+
+        if (round == Rounding::Round) {
+            return v.ir.VectorAdd(esize, tmp.upper, v.ir.VectorLogicalShiftRight(esize, tmp.lower, static_cast<u8>(esize - 1)));
+        }
+
+        return tmp.upper;
+    }();
+
+    v.ir.SetVector(d, result);
+    return true;
+}
 } // Anonymous namespace
 
 bool ArmTranslatorVisitor::asimd_VMLA_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool F, bool N, bool M, size_t Vm) {
@@ -128,31 +170,11 @@ bool ArmTranslatorVisitor::asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t
 }
 
 bool ArmTranslatorVisitor::asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
-    if (sz == 0b11) {
-        // TODO: This should be a decode error.
-        return UndefinedInstruction();
-    }
+    return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::None);
+}
 
-    if (sz == 0b00) {
-        return UndefinedInstruction();
-    }
-
-    if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn))) {
-        return UndefinedInstruction();
-    }
-
-    const size_t esize = 8U << sz;
-    const auto d = ToVector(Q, Vd, D);
-    const auto n = ToVector(Q, Vn, N);
-    const auto [m, index] = GetScalarLocation(esize, M, Vm);
-
-    const auto scalar = ir.VectorGetElement(esize, ir.GetVector(m), index);
-    const auto reg_n = ir.GetVector(n);
-    const auto reg_m = ir.VectorBroadcast(esize, scalar);
-    const auto result = ir.VectorSignedSaturatedDoublingMultiply(esize, reg_n, reg_m).upper;
-
-    ir.SetVector(d, result);
-    return true;
+bool ArmTranslatorVisitor::asimd_VQRDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
+    return ScalarMultiplyReturnHigh(*this, Q, D, sz, Vn, Vd, N, M, Vm, Rounding::Round);
 }
 
 } // namespace Dynarmic::A32
diff --git a/src/frontend/A32/translate/impl/translate_arm.h b/src/frontend/A32/translate/impl/translate_arm.h
index f482a6e0..260888a1 100644
--- a/src/frontend/A32/translate/impl/translate_arm.h
+++ b/src/frontend/A32/translate/impl/translate_arm.h
@@ -511,6 +511,7 @@ struct ArmTranslatorVisitor final {
     bool asimd_VMUL_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm);
     bool asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
     bool asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
+    bool asimd_VQRDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
 
     // Two registers and a shift amount
     bool asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm);