diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp
index 9d648636..9625e995 100644
--- a/src/backend_x64/emit_x64.cpp
+++ b/src/backend_x64/emit_x64.cpp
@@ -602,6 +602,59 @@ void EmitX64::EmitNot(IR::Value* value_) {
     code->NOT(32, R(result));
 }
 
+void EmitX64::EmitSignExtendHalfToWord(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    // TODO: Remove unnecessary mov that may occur here
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->MOVSX(32, 16, result, R(result));
+}
+
+void EmitX64::EmitSignExtendByteToWord(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    // TODO: Remove unnecessary mov that may occur here
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->MOVSX(32, 8, result, R(result));
+}
+
+void EmitX64::EmitZeroExtendHalfToWord(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    // TODO: Remove unnecessary mov that may occur here
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->MOVZX(32, 16, result, R(result));
+}
+
+void EmitX64::EmitZeroExtendByteToWord(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    // TODO: Remove unnecessary mov that may occur here
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->MOVZX(32, 8, result, R(result));
+}
+
+void EmitX64::EmitByteReverseWord(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->BSWAP(32, result);
+}
+
+void EmitX64::EmitByteReverseHalf(IR::Value* value_) {
+    auto value = reinterpret_cast<IR::Inst*>(value_);
+
+    X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
+
+    code->ROL(16, R(result), Imm8(8));
+}
+
+
 void EmitX64::EmitReadMemory8(IR::Value* value_) {
     auto value = reinterpret_cast<IR::Inst*>(value_);
 
diff --git a/src/backend_x64/emit_x64.h b/src/backend_x64/emit_x64.h
index f61fe513..da19408a 100644
--- a/src/backend_x64/emit_x64.h
+++ b/src/backend_x64/emit_x64.h
@@ -66,6 +66,12 @@ private:
     void EmitEor(IR::Value* value);
     void EmitOr(IR::Value* value);
     void EmitNot(IR::Value* value);
+    void EmitSignExtendHalfToWord(IR::Value* value);
+    void EmitSignExtendByteToWord(IR::Value* value);
+    void EmitZeroExtendHalfToWord(IR::Value* value);
+    void EmitZeroExtendByteToWord(IR::Value* value);
+    void EmitByteReverseWord(IR::Value* value);
+    void EmitByteReverseHalf(IR::Value* value);
     void EmitReadMemory8(IR::Value* value);
     void EmitReadMemory16(IR::Value* value);
     void EmitReadMemory32(IR::Value* value);
diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/decoder/thumb16.h
index 35f8845f..25893785 100644
--- a/src/frontend/decoder/thumb16.h
+++ b/src/frontend/decoder/thumb16.h
@@ -56,7 +56,7 @@ private:
 };
 
 template <typename V>
-const std::array<Thumb16Matcher<V>, 36> g_thumb16_instruction_table = {
+const std::array<Thumb16Matcher<V>, 43> g_thumb16_instruction_table = {
 
 #define INST(fn, name, bitstring) detail::detail<Thumb16Matcher, u16, 16>::GetMatcher<decltype(fn), fn>(name, bitstring)
 
@@ -119,17 +119,17 @@ const std::array<Thumb16Matcher<V>, 36> g_thumb16_instruction_table = {
     // Miscellaneous 16-bit instructions
     //INST(&V::thumb16_ADD_spsp,       "ADD (imm to SP)",          "101100000vvvvvvv"), // v4T
     //INST(&V::thumb16_SUB_spsp,       "SUB (imm from SP)",        "101100001vvvvvvv"), // v4T
-    //INST(&V::thumb16_SXTH,           "SXTH",                     "1011001000mmmddd"), // v6
-    //INST(&V::thumb16_SXTB,           "SXTB",                     "1011001001mmmddd"), // v6
-    //INST(&V::thumb16_UXTH,           "UXTH",                     "1011001010mmmddd"), // v6
-    //INST(&V::thumb16_UXTB,           "UXTB",                     "1011001011mmmddd"), // v6
+    INST(&V::thumb16_SXTH,           "SXTH",                     "1011001000mmmddd"), // v6
+    INST(&V::thumb16_SXTB,           "SXTB",                     "1011001001mmmddd"), // v6
+    INST(&V::thumb16_UXTH,           "UXTH",                     "1011001010mmmddd"), // v6
+    INST(&V::thumb16_UXTB,           "UXTB",                     "1011001011mmmddd"), // v6
     //INST(&V::thumb16_PUSH,           "PUSH",                     "1011010rxxxxxxxx"), // v4T
     //INST(&V::thumb16_POP,            "POP",                      "1011110rxxxxxxxx"), // v4T
     //INST(&V::thumb16_SETEND,         "SETEND",                   "101101100101x000"), // v6
     //INST(&V::thumb16_CPS,            "CPS",                      "10110110011m0aif"), // v6
-    //INST(&V::thumb16_REV,            "REV",                      "1011101000nnnddd"), // v6
-    //INST(&V::thumb16_REV16,          "REV16",                    "1011101001nnnddd"), // v6
-    //INST(&V::thumb16_REVSH,          "REVSH",                    "1011101011nnnddd"), // v6
+    INST(&V::thumb16_REV,            "REV",                      "1011101000mmmddd"), // v6
+    INST(&V::thumb16_REV16,          "REV16",                    "1011101001mmmddd"), // v6
+    INST(&V::thumb16_REVSH,          "REVSH",                    "1011101011mmmddd"), // v6
     //INST(&V::thumb16_BKPT,           "BKPT",                     "10111110xxxxxxxx"), // v5
 
     // Store/Load multiple registers
diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/disassembler/disassembler_thumb.cpp
index e17fe8b2..ae796202 100644
--- a/src/frontend/disassembler/disassembler_thumb.cpp
+++ b/src/frontend/disassembler/disassembler_thumb.cpp
@@ -244,6 +244,34 @@ public:
         return Common::StringFromFormat("ldr %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
     }
 
+    std::string thumb16_SXTH(Reg m, Reg d) {
+        return Common::StringFromFormat("sxth %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_SXTB(Reg m, Reg d) {
+        return Common::StringFromFormat("sxtb %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_UXTH(Reg m, Reg d) {
+        return Common::StringFromFormat("uxth %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_UXTB(Reg m, Reg d) {
+        return Common::StringFromFormat("uxtb %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_REV(Reg m, Reg d) {
+        return Common::StringFromFormat("rev %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_REV16(Reg m, Reg d) {
+        return Common::StringFromFormat("rev16 %s, %s", RegStr(d), RegStr(m));
+    }
+
+    std::string thumb16_REVSH(Reg m, Reg d) {
+        return Common::StringFromFormat("revsh %s, %s", RegStr(d), RegStr(m));
+    }
+
     std::string thumb16_UDF() {
         return Common::StringFromFormat("udf");
     }
diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp
index d57929fe..1549ab31 100644
--- a/src/frontend/ir/ir_emitter.cpp
+++ b/src/frontend/ir/ir_emitter.cpp
@@ -171,6 +171,31 @@ IR::ValuePtr IREmitter::Not(IR::ValuePtr a) {
     return Inst(IR::Opcode::Not, {a});
 }
 
+IR::ValuePtr IREmitter::SignExtendHalfToWord(IR::ValuePtr a) {
+    return Inst(IR::Opcode::SignExtendHalfToWord, {a});
+}
+
+IR::ValuePtr IREmitter::SignExtendByteToWord(IR::ValuePtr a) {
+    return Inst(IR::Opcode::SignExtendByteToWord, {a});
+}
+
+IR::ValuePtr IREmitter::ZeroExtendHalfToWord(IR::ValuePtr a) {
+    return Inst(IR::Opcode::ZeroExtendHalfToWord, {a});
+}
+
+IR::ValuePtr IREmitter::ZeroExtendByteToWord(IR::ValuePtr a) {
+    return Inst(IR::Opcode::ZeroExtendByteToWord, {a});
+}
+
+IR::ValuePtr IREmitter::ByteReverseWord(IR::ValuePtr a) {
+    return Inst(IR::Opcode::ByteReverseWord, {a});
+}
+
+IR::ValuePtr IREmitter::ByteReverseHalf(IR::ValuePtr a) {
+    return Inst(IR::Opcode::ByteReverseHalf, {a});
+}
+
+
 IR::ValuePtr IREmitter::ReadMemory8(IR::ValuePtr vaddr) {
     return Inst(IR::Opcode::ReadMemory8, {vaddr});
 }
diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h
index df1f1070..a3a7d244 100644
--- a/src/frontend/ir/ir_emitter.h
+++ b/src/frontend/ir/ir_emitter.h
@@ -68,6 +68,12 @@ public:
     IR::ValuePtr Eor(IR::ValuePtr a, IR::ValuePtr b);
     IR::ValuePtr Or(IR::ValuePtr a, IR::ValuePtr b);
     IR::ValuePtr Not(IR::ValuePtr a);
+    IR::ValuePtr SignExtendHalfToWord(IR::ValuePtr a);
+    IR::ValuePtr SignExtendByteToWord(IR::ValuePtr a);
+    IR::ValuePtr ZeroExtendHalfToWord(IR::ValuePtr a);
+    IR::ValuePtr ZeroExtendByteToWord(IR::ValuePtr a);
+    IR::ValuePtr ByteReverseWord(IR::ValuePtr a);
+    IR::ValuePtr ByteReverseHalf(IR::ValuePtr a);
 
     IR::ValuePtr ReadMemory8(IR::ValuePtr vaddr);
     IR::ValuePtr ReadMemory16(IR::ValuePtr vaddr);
diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc
index db787890..b516dc2e 100644
--- a/src/frontend/ir/opcodes.inc
+++ b/src/frontend/ir/opcodes.inc
@@ -39,6 +39,12 @@ OPCODE(And,                     T::U32,         T::U32,         T::U32
 OPCODE(Eor,                     T::U32,         T::U32,         T::U32                          )
 OPCODE(Or,                      T::U32,         T::U32,         T::U32                          )
 OPCODE(Not,                     T::U32,         T::U32                                          )
+OPCODE(SignExtendHalfToWord,    T::U32,         T::U16                                          )
+OPCODE(SignExtendByteToWord,    T::U32,         T::U8                                           )
+OPCODE(ZeroExtendHalfToWord,    T::U32,         T::U16                                          )
+OPCODE(ZeroExtendByteToWord,    T::U32,         T::U8                                           )
+OPCODE(ByteReverseWord,         T::U32,         T::U32                                          )
+OPCODE(ByteReverseHalf,         T::U16,         T::U16                                          )
 
 // Memory access
 OPCODE(ReadMemory8,             T::U8,          T::U32                                          )
diff --git a/src/frontend/translate/translate_thumb.cpp b/src/frontend/translate/translate_thumb.cpp
index a6a1ad2a..47cd841a 100644
--- a/src/frontend/translate/translate_thumb.cpp
+++ b/src/frontend/translate/translate_thumb.cpp
@@ -440,6 +440,68 @@ struct ThumbTranslatorVisitor final {
         return true;
     }
 
+    bool thumb16_SXTH(Reg m, Reg d) {
+        // SXTH <Rd>, <Rm>
+        // Rd cannot encode R15.
+        auto half = ir.LeastSignificantHalf(ir.GetRegister(m));
+        ir.SetRegister(d, ir.SignExtendHalfToWord(half));
+        return true;
+    }
+
+    bool thumb16_SXTB(Reg m, Reg d) {
+        // SXTB <Rd>, <Rm>
+        // Rd cannot encode R15.
+        auto byte = ir.LeastSignificantByte(ir.GetRegister(m));
+        ir.SetRegister(d, ir.SignExtendByteToWord(byte));
+        return true;
+    }
+
+    bool thumb16_UXTH(Reg m, Reg d) {
+        // UXTH <Rd>, <Rm>
+        // Rd cannot encode R15.
+        auto half = ir.LeastSignificantHalf(ir.GetRegister(m));
+        ir.SetRegister(d, ir.ZeroExtendHalfToWord(half));
+        return true;
+    }
+
+    bool thumb16_UXTB(Reg m, Reg d) {
+        // UXTB <Rd>, <Rm>
+        // Rd cannot encode R15.
+        auto byte = ir.LeastSignificantByte(ir.GetRegister(m));
+        ir.SetRegister(d, ir.ZeroExtendByteToWord(byte));
+        return true;
+    }
+
+    bool thumb16_REV(Reg m, Reg d) {
+        // REV <Rd>, <Rm>
+        // Rd cannot encode R15.
+        ir.SetRegister(d, ir.ByteReverseWord(ir.GetRegister(m)));
+        return true;
+    }
+
+    bool thumb16_REV16(Reg m, Reg d) {
+        // REV16 <Rd>, <Rm>
+        // Rd cannot encode R15.
+        // TODO: Consider optimizing
+        auto Rm = ir.GetRegister(m);
+        auto upper_half = ir.LeastSignificantHalf(ir.LogicalShiftRight(Rm, ir.Imm8(16), ir.Imm1(0)).result);
+        auto lower_half = ir.LeastSignificantHalf(Rm);
+        auto rev_upper_half = ir.ZeroExtendHalfToWord(ir.ByteReverseHalf(upper_half));
+        auto rev_lower_half = ir.ZeroExtendHalfToWord(ir.ByteReverseHalf(lower_half));
+        auto result = ir.Or(ir.LogicalShiftLeft(rev_upper_half, ir.Imm8(16), ir.Imm1(0)).result,
+                            rev_lower_half);
+        ir.SetRegister(d, result);
+        return true;
+    }
+
+    bool thumb16_REVSH(Reg m, Reg d) {
+        // REVSH <Rd>, <Rm>
+        // Rd cannot encode R15.
+        auto rev_half = ir.ByteReverseHalf(ir.LeastSignificantHalf(ir.GetRegister(m)));
+        ir.SetRegister(d, ir.SignExtendHalfToWord(rev_half));
+        return true;
+    }
+
     bool thumb16_UDF() {
         return InterpretThisInstruction();
     }