diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index b44ac807..ddf557fd 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -82,7 +82,7 @@ static CPUCaps Detect() {
         caps.vendor = CPUVendor::OTHER;
 
     // Set reasonable default brand string even if brand string not available
-    strcpy_s(caps.cpu_string, caps.brand_string);
+    strcpy_s(caps.cpu_string, sizeof(caps.cpu_string), caps.brand_string);
 
     // Detect family and other miscellaneous features
     if (max_std_fn >= 1) {
diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/decoder/thumb16.h
index d59e1d86..9bc9d065 100644
--- a/src/frontend/decoder/thumb16.h
+++ b/src/frontend/decoder/thumb16.h
@@ -125,7 +125,7 @@ boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
         INST(&V::thumb16_UXTH,           "UXTH",                     "1011001010mmmddd"), // v6
         INST(&V::thumb16_UXTB,           "UXTB",                     "1011001011mmmddd"), // v6
         INST(&V::thumb16_PUSH,           "PUSH",                     "1011010Mxxxxxxxx"), // v4T
-        //INST(&V::thumb16_POP,            "POP",                      "1011110rxxxxxxxx"), // v4T
+        INST(&V::thumb16_POP,            "POP",                      "1011110Pxxxxxxxx"), // v4T
         //INST(&V::thumb16_SETEND,         "SETEND",                   "101101100101x000"), // v6
         //INST(&V::thumb16_CPS,            "CPS",                      "10110110011m0aif"), // v6
         INST(&V::thumb16_REV,            "REV",                      "1011101000mmmddd"), // v6
diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/disassembler/disassembler_thumb.cpp
index 25ab21f8..235ce780 100644
--- a/src/frontend/disassembler/disassembler_thumb.cpp
+++ b/src/frontend/disassembler/disassembler_thumb.cpp
@@ -298,6 +298,24 @@ public:
         return ret;
     }
 
+    std::string thumb16_POP(bool P, RegList reg_list) {
+        if (P)
+            reg_list |= 1 << 15;
+
+        std::string ret = "PUSH ";
+        bool first_reg = true;
+        for (size_t i = 0; i < 16; i++) {
+            if (Common::Bit(i, reg_list)) {
+                if (!first_reg)
+                    ret += ", ";
+                ret += RegStr(static_cast<Reg>(i));
+                first_reg = false;
+            }
+        }
+
+        return ret;
+    }
+
     std::string thumb16_REV(Reg m, Reg d) {
         return Common::StringFromFormat("rev %s, %s", RegStr(d), RegStr(m));
     }
diff --git a/src/frontend/translate/translate_thumb.cpp b/src/frontend/translate/translate_thumb.cpp
index 6f1f5993..98bb5fd4 100644
--- a/src/frontend/translate/translate_thumb.cpp
+++ b/src/frontend/translate/translate_thumb.cpp
@@ -515,11 +515,12 @@ struct ThumbTranslatorVisitor final {
         }
         // PUSH <reg_list>
         // reg_list cannot encode for R15.
-        u32 num_bytes_to_push = static_cast<u32>(4 * Common::BitCount(reg_list));
+        const u32 num_bytes_to_push = static_cast<u32>(4 * Common::BitCount(reg_list));
         const auto final_address = ir.Sub(ir.GetRegister(Reg::SP), ir.Imm32(num_bytes_to_push));
         auto address = final_address;
         for (size_t i = 0; i < 16; i++) {
             if (Common::Bit(i, reg_list)) {
+                // TODO: Deal with alignment
                 auto Ri = ir.GetRegister(static_cast<Reg>(i));
                 ir.WriteMemory32(address, Ri);
                 address = ir.Add(address, ir.Imm32(4));
@@ -530,6 +531,26 @@ struct ThumbTranslatorVisitor final {
         return true;
     }
 
+    bool thumb16_POP(bool P, RegList reg_list) {
+        if (P) reg_list |= 1 << 15;
+        if (Common::BitCount(reg_list) < 1) {
+            return UnpredictableInstruction();
+        }
+        // POP <reg_list>
+        auto address = ir.GetRegister(Reg::SP);
+        for (size_t i = 0; i < 15; i++) {
+            if (Common::Bit(i, reg_list)) {
+                // TODO: Deal with alignment
+                auto data = ir.ReadMemory32(address);
+                ir.SetRegister(static_cast<Reg>(i), data);
+                address = ir.Add(address, ir.Imm32(4));
+            }
+        }
+        ir.SetRegister(Reg::SP, address);
+        // TODO(optimization): Possible location for an RSB push.
+        return true;
+    }
+
     bool thumb16_REV(Reg m, Reg d) {
         // REV <Rd>, <Rm>
         // Rd cannot encode R15.
diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp
index db61bdb7..d2834eb6 100644
--- a/tests/arm/fuzz_arm.cpp
+++ b/tests/arm/fuzz_arm.cpp
@@ -391,4 +391,4 @@ TEST_CASE("Fuzz ARM reversal instructions", "[JitX64]") {
             return reg_instructions[2].Generate();
         });
     }
-}
\ No newline at end of file
+}
diff --git a/tests/arm/fuzz_thumb.cpp b/tests/arm/fuzz_thumb.cpp
index 608e6dc2..49d0b3a9 100644
--- a/tests/arm/fuzz_thumb.cpp
+++ b/tests/arm/fuzz_thumb.cpp
@@ -163,7 +163,6 @@ static bool DoesBehaviorMatch(const ARMul_State& interp, const Dynarmic::Jit& ji
             && interp_write_records == jit_write_records;
 }
 
-
 void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_execute_count, const size_t run_count, const std::function<u16()> instruction_generator) {
     // Prepare memory
     code_mem.fill(0xE7FE); // b +#0
@@ -274,7 +273,8 @@ TEST_CASE("Fuzz Thumb instructions set 1", "[JitX64][Thumb]") {
         ThumbInstGen("1001xxxxxxxxxxxx"), // LDR/STR Rd, [SP, #]
         ThumbInstGen("10110100xxxxxxxx",  // PUSH (R = 0)
                      [](u16 inst){ return Dynarmic::Common::Bits<0, 7>(inst) != 0; }), // Empty reg_list is UNPREDICTABLE
-        ThumbInstGen("10111100xxxxxxxx"), // POP (R = 0)
+        ThumbInstGen("10111100xxxxxxxx", // POP (R = 0)
+                     [](u16 inst){ return Dynarmic::Common::Bits<0, 7>(inst) != 0; }), // Empty reg_list is UNPREDICTABLE
         ThumbInstGen("1100xxxxxxxxxxxx"), // STMIA/LDMIA
         //ThumbInstGen("101101100101x000"), // SETEND
     }};