From 8cd72428c9c7314cc7add4b5619b62eab035977f Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Thu, 14 May 2015 15:41:40 -0400
Subject: [PATCH] dyncom: Add ARMv6K NOP and hint instructions to the decoding
 table

---
 src/core/arm/dyncom/arm_dyncom_dec.cpp        |  10 ++
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 154 ++++++++++++++++--
 2 files changed, 152 insertions(+), 12 deletions(-)

diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index d0d37bea05..3887189f10 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -198,6 +198,11 @@ const ISEITEM arm_instruction[] = {
     { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 },
     { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 },
     { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 },
+    { "nop", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000000 },
+    { "yield", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000001 },
+    { "wfe", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000002 },
+    { "wfi", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000003 },
+    { "sev", 5, ARMV6K, 23, 27, 0x00000006, 22, 22, 0x00000000, 20, 21, 0x00000002, 16, 19, 0x00000000, 0, 7, 0x00000004 },
     { "swi", 1, 0, 24, 27, 0x0000000f },
     { "bbl", 1, 0, 25, 27, 0x00000005 },
 };
@@ -395,6 +400,11 @@ const ISEITEM arm_exclusion_code[] = {
     { "strexd", 0, ARMV6K, 0 },
     { "ldrexh", 0, ARMV6K, 0 },
     { "strexh", 0, ARMV6K, 0 },
+    { "nop", 0, ARMV6K, 0 },
+    { "yield", 0, ARMV6K, 0 },
+    { "wfe", 0, ARMV6K, 0 },
+    { "wfi", 0, ARMV6K, 0 },
+    { "sev", 0, ARMV6K, 0 },
     { "swi", 0, 0, 0 },
     { "bbl", 0, 0, 0 },
 
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 7e8032b307..cb45cfb387 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -2052,6 +2052,19 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
     return inst_base;
 }
 
+// NOP introduced in ARMv6K.
+static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index)
+{
+    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+    inst_base->cond     = BITS(inst, 28, 31);
+    inst_base->idx      = index;
+    inst_base->br       = NON_BRANCH;
+    inst_base->load_r15 = 0;
+
+    return inst_base;
+}
+
 static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
 {
     arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
@@ -2343,6 +2356,18 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index)
     return inst_base;
 }
 
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index)
+{
+    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+    inst_base->cond     = BITS(inst, 28, 31);
+    inst_base->idx      = index;
+    inst_base->br       = NON_BRANCH;
+    inst_base->load_r15 = 0;
+
+    return inst_base;
+}
+
 static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
 {
     arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
@@ -3347,6 +3372,40 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
     return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
 }
 
+static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index)
+{
+    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+    inst_base->cond     = BITS(inst, 28, 31);
+    inst_base->idx      = index;
+    inst_base->br       = NON_BRANCH;
+    inst_base->load_r15 = 0;
+
+    return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index)
+{
+    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+    inst_base->cond     = BITS(inst, 28, 31);
+    inst_base->idx      = index;
+    inst_base->br       = NON_BRANCH;
+    inst_base->load_r15 = 0;
+
+    return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
+{
+    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+    inst_base->cond     = BITS(inst, 28, 31);
+    inst_base->idx      = index;
+    inst_base->br       = NON_BRANCH;
+    inst_base->load_r15 = 0;
+
+    return inst_base;
+}
+
 // Floating point VFPv3 structures and instructions
 
 #define VFP_INTERPRETER_STRUCT
@@ -3552,6 +3611,11 @@ const transop_fp_t arm_instruction_trans[] = {
     INTERPRETER_TRANSLATE(strexd),
     INTERPRETER_TRANSLATE(ldrexh),
     INTERPRETER_TRANSLATE(strexh),
+    INTERPRETER_TRANSLATE(nop),
+    INTERPRETER_TRANSLATE(yield),
+    INTERPRETER_TRANSLATE(wfe),
+    INTERPRETER_TRANSLATE(wfi),
+    INTERPRETER_TRANSLATE(sev),
     INTERPRETER_TRANSLATE(swi),
     INTERPRETER_TRANSLATE(bbl),
 
@@ -3727,7 +3791,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \
                        inst_base = (arm_inst *)&inst_buf[ptr]
 
-    #define INC_PC(l) ptr += sizeof(arm_inst) + l
+    #define INC_PC(l)   ptr += sizeof(arm_inst) + l
+    #define INC_PC_STUB ptr += sizeof(arm_inst)
 
 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
 // clunky switch statement.
@@ -3932,16 +3997,21 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
     case 188: goto STREXD_INST; \
     case 189: goto LDREXH_INST; \
     case 190: goto STREXH_INST; \
-    case 191: goto SWI_INST; \
-    case 192: goto BBL_INST; \
-    case 193: goto B_2_THUMB ; \
-    case 194: goto B_COND_THUMB ; \
-    case 195: goto BL_1_THUMB ; \
-    case 196: goto BL_2_THUMB ; \
-    case 197: goto BLX_1_THUMB ; \
-    case 198: goto DISPATCH; \
-    case 199: goto INIT_INST_LENGTH; \
-    case 200: goto END; \
+    case 191: goto NOP_INST; \
+    case 192: goto YIELD_INST; \
+    case 193: goto WFE_INST; \
+    case 194: goto WFI_INST; \
+    case 195: goto SEV_INST; \
+    case 196: goto SWI_INST; \
+    case 197: goto BBL_INST; \
+    case 198: goto B_2_THUMB ; \
+    case 199: goto B_COND_THUMB ; \
+    case 200: goto BL_1_THUMB ; \
+    case 201: goto BL_2_THUMB ; \
+    case 202: goto BLX_1_THUMB ; \
+    case 203: goto DISPATCH; \
+    case 204: goto INIT_INST_LENGTH; \
+    case 205: goto END; \
     }
 #endif
 
@@ -3990,7 +4060,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,
         &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST,
         &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST,
-        &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&SWI_INST,&&BBL_INST,
+        &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST,
         &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
         &&INIT_INST_LENGTH,&&END
         };
@@ -5044,6 +5114,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         GOTO_NEXT_INST;
     }
 
+    NOP_INST:
+    {
+        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        INC_PC_STUB;
+        FETCH_INST;
+        GOTO_NEXT_INST;
+    }
+
     PKHBT_INST:
     {
         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
@@ -5527,6 +5605,19 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         GOTO_NEXT_INST;
     }
 
+    SEV_INST:
+    {
+        // Stubbed, as SEV is a hint instruction.
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            LOG_TRACE(Core_ARM11, "SEV executed.");
+        }
+
+        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        INC_PC_STUB;
+        FETCH_INST;
+        GOTO_NEXT_INST;
+    }
+
     SHADD8_INST:
     SHADD16_INST:
     SHADDSUBX_INST:
@@ -6990,6 +7081,45 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
         GOTO_NEXT_INST;
     }
 
+    WFE_INST:
+    {
+        // Stubbed, as WFE is a hint instruction.
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            LOG_TRACE(Core_ARM11, "WFE executed.");
+        }
+
+        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        INC_PC_STUB;
+        FETCH_INST;
+        GOTO_NEXT_INST;
+    }
+
+    WFI_INST:
+    {
+        // Stubbed, as WFI is a hint instruction.
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            LOG_TRACE(Core_ARM11, "WFI executed.");
+        }
+
+        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        INC_PC_STUB;
+        FETCH_INST;
+        GOTO_NEXT_INST;
+    }
+
+    YIELD_INST:
+    {
+        // Stubbed, as YIELD is a hint instruction.
+        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+            LOG_TRACE(Core_ARM11, "YIELD executed.");
+        }
+
+        cpu->Reg[15] += GET_INST_SIZE(cpu);
+        INC_PC_STUB;
+        FETCH_INST;
+        GOTO_NEXT_INST;
+    }
+
     #define VFP_INTERPRETER_IMPL
     #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
     #undef VFP_INTERPRETER_IMPL
-- 
GitLab