From 53a22b84da9690865954f666694de885ccb7c286 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Fri, 12 Sep 2014 18:34:51 -0400
Subject: [PATCH] ARM: Integrate SkyEye faster "dyncom" interpreter.

Fixed typo (make protected member public)

Added license header back in. I originally removed this because I mostly rewrote the file, but meh

ARM: Fixed a type error in dyncom interpreter.

ARM: Updated dyncom to use unique_ptr for internal ARM state.
---
 src/core/CMakeLists.txt                       |   19 +-
 src/core/arm/dyncom/arm_dyncom.cpp            |  164 +
 src/core/arm/dyncom/arm_dyncom.h              |   90 +
 src/core/arm/dyncom/arm_dyncom_dec.cpp        |  402 +
 src/core/arm/dyncom/arm_dyncom_dec.h          |  155 +
 .../arm/dyncom/arm_dyncom_interpreter.cpp     | 6559 +++++++++++++++++
 src/core/arm/dyncom/arm_dyncom_interpreter.h  |    7 +
 src/core/arm/dyncom/arm_dyncom_run.cpp        |  120 +
 src/core/arm/dyncom/arm_dyncom_run.h          |   55 +
 src/core/arm/dyncom/arm_dyncom_thumb.cpp      |  521 ++
 src/core/arm/dyncom/arm_dyncom_thumb.h        |   51 +
 src/core/arm/interpreter/arm_interpreter.h    |    2 +-
 src/core/arm/interpreter/armsupp.cpp          |   15 +-
 src/core/arm/skyeye_common/arm_regformat.h    |    4 +-
 src/core/arm/skyeye_common/armcpu.h           |    5 +-
 src/core/arm/skyeye_common/armos.h            |    9 +-
 src/core/arm/skyeye_common/skyeye_defs.h      |    4 +-
 src/core/arm/skyeye_common/skyeye_types.h     |   55 +
 src/core/arm/skyeye_common/vfp/vfpinstr.cpp   |   48 +-
 src/core/hle/coprocessor.h                    |   20 -
 20 files changed, 8230 insertions(+), 75 deletions(-)
 create mode 100644 src/core/arm/dyncom/arm_dyncom.cpp
 create mode 100644 src/core/arm/dyncom/arm_dyncom.h
 create mode 100644 src/core/arm/dyncom/arm_dyncom_dec.cpp
 create mode 100644 src/core/arm/dyncom/arm_dyncom_dec.h
 create mode 100644 src/core/arm/dyncom/arm_dyncom_interpreter.cpp
 create mode 100644 src/core/arm/dyncom/arm_dyncom_interpreter.h
 create mode 100644 src/core/arm/dyncom/arm_dyncom_run.cpp
 create mode 100644 src/core/arm/dyncom/arm_dyncom_run.h
 create mode 100644 src/core/arm/dyncom/arm_dyncom_thumb.cpp
 create mode 100644 src/core/arm/dyncom/arm_dyncom_thumb.h
 create mode 100644 src/core/arm/skyeye_common/skyeye_types.h
 delete mode 100644 src/core/hle/coprocessor.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d87e5ad49..9f08277a1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,6 +1,11 @@
 set(SRCS
             arm/disassembler/arm_disasm.cpp
             arm/disassembler/load_symbol_map.cpp
+            arm/dyncom/arm_dyncom.cpp
+            arm/dyncom/arm_dyncom_dec.cpp
+            arm/dyncom/arm_dyncom_interpreter.cpp
+            arm/dyncom/arm_dyncom_run.cpp
+            arm/dyncom/arm_dyncom_thumb.cpp
             arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
             arm/interpreter/mmu/cache.cpp
             arm/interpreter/mmu/maverick.cpp
@@ -43,7 +48,6 @@ set(SRCS
             hle/service/service.cpp
             hle/service/srv.cpp
             hle/config_mem.cpp
-            hle/coprocessor.cpp
             hle/hle.cpp
             hle/svc.cpp
             hw/gpu.cpp
@@ -63,6 +67,11 @@ set(SRCS
 set(HEADERS
             arm/disassembler/arm_disasm.h
             arm/disassembler/load_symbol_map.h
+            arm/dyncom/arm_dyncom.h
+            arm/dyncom/arm_dyncom_dec.h
+            arm/dyncom/arm_dyncom_interpreter.h
+            arm/dyncom/arm_dyncom_run.h
+            arm/dyncom/arm_dyncom_thumb.h
             arm/interpreter/arm_interpreter.h
             arm/interpreter/mmu/arm1176jzf_s_mmu.h
             arm/interpreter/mmu/cache.h
@@ -70,9 +79,6 @@ set(HEADERS
             arm/interpreter/mmu/sa_mmu.h
             arm/interpreter/mmu/tlb.h
             arm/interpreter/mmu/wb.h
-            arm/skyeye_common/vfp/asm_vfp.h
-            arm/skyeye_common/vfp/vfp.h
-            arm/skyeye_common/vfp/vfp_helper.h
             arm/skyeye_common/arm_regformat.h
             arm/skyeye_common/armcpu.h
             arm/skyeye_common/armdefs.h
@@ -80,6 +86,10 @@ set(HEADERS
             arm/skyeye_common/armmmu.h
             arm/skyeye_common/armos.h
             arm/skyeye_common/skyeye_defs.h
+            arm/skyeye_common/skyeye_types.h
+            arm/skyeye_common/vfp/asm_vfp.h
+            arm/skyeye_common/vfp/vfp.h
+            arm/skyeye_common/vfp/vfp_helper.h
             arm/arm_interface.h
             file_sys/archive.h
             file_sys/archive_romfs.h
@@ -105,7 +115,6 @@ set(HEADERS
             hle/service/service.h
             hle/service/srv.h
             hle/config_mem.h
-            hle/coprocessor.h
             hle/function_wrappers.h
             hle/hle.h
             hle/svc.h
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
new file mode 100644
index 000000000..7a65669ef
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -0,0 +1,164 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include "core/arm/skyeye_common/armcpu.h"
+#include "core/arm/skyeye_common/armemu.h"
+#include "core/arm/skyeye_common/vfp/vfp.h"
+
+#include "core/arm/dyncom/arm_dyncom.h"
+#include "core/arm/dyncom/arm_dyncom_interpreter.h"
+
+const static cpu_config_t s_arm11_cpu_info = {
+    "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
+};
+
+ARM_DynCom::ARM_DynCom() : ticks(0) {
+    state = std::unique_ptr<ARMul_State>(new ARMul_State);
+
+    ARMul_EmulateInit();
+    memset(state.get(), 0, sizeof(ARMul_State));
+
+    ARMul_NewState((ARMul_State*)state.get());
+
+    state->abort_model = 0;
+    state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
+    state->bigendSig = LOW;
+
+    ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
+    state->lateabtSig = LOW;
+    mmu_init(state);
+
+    // Reset the core to initial state
+    ARMul_CoProInit(state.get());
+    ARMul_Reset(state.get());
+    state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
+    state->Emulate = 3;
+
+    state->pc = state->Reg[15] = 0x00000000;
+    state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
+    state->servaddr = 0xFFFF0000;
+    state->NirqSig = HIGH;
+
+    VFPInit(state.get()); // Initialize the VFP
+
+    ARMul_EmulateInit();
+}
+
+ARM_DynCom::~ARM_DynCom() {
+}
+
+/**
+ * Set the Program Counter to an address
+ * @param addr Address to set PC to
+ */
+void ARM_DynCom::SetPC(u32 pc) {
+    state->pc = state->Reg[15] = pc;
+}
+
+/*
+ * Get the current Program Counter
+ * @return Returns current PC
+ */
+u32 ARM_DynCom::GetPC() const {
+    return state->pc;
+}
+
+/**
+ * Get an ARM register
+ * @param index Register index (0-15)
+ * @return Returns the value in the register
+ */
+u32 ARM_DynCom::GetReg(int index) const {
+    return state->Reg[index];
+}
+
+/**
+ * Set an ARM register
+ * @param index Register index (0-15)
+ * @param value Value to set register to
+ */
+void ARM_DynCom::SetReg(int index, u32 value) {
+    state->Reg[index] = value;
+}
+
+/**
+ * Get the current CPSR register
+ * @return Returns the value of the CPSR register
+ */
+u32 ARM_DynCom::GetCPSR() const {
+    return state->Cpsr;
+}
+
+/**
+ * Set the current CPSR register
+ * @param cpsr Value to set CPSR to
+ */
+void ARM_DynCom::SetCPSR(u32 cpsr) {
+    state->Cpsr = cpsr;
+}
+
+/**
+ * Returns the number of clock ticks since the last reset
+ * @return Returns number of clock ticks
+ */
+u64 ARM_DynCom::GetTicks() const {
+    return ticks;
+}
+
+/**
+ * Executes the given number of instructions
+ * @param num_instructions Number of instructions to executes
+ */
+void ARM_DynCom::ExecuteInstructions(int num_instructions) {
+    ticks += num_instructions;
+    state->NumInstrsToExecute = num_instructions;
+    InterpreterMainLoop(state.get());
+}
+
+/**
+ * Saves the current CPU context
+ * @param ctx Thread context to save
+ * @todo Do we need to save Reg[15] and NextInstr?
+ */
+void ARM_DynCom::SaveContext(ThreadContext& ctx) {
+    memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
+    memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
+
+    ctx.sp = state->Reg[13];
+    ctx.lr = state->Reg[14];
+    ctx.pc = state->pc;
+    ctx.cpsr = state->Cpsr;
+
+    ctx.fpscr = state->VFP[1];
+    ctx.fpexc = state->VFP[2];
+
+    ctx.reg_15 = state->Reg[15];
+    ctx.mode = state->NextInstr;
+}
+
+/**
+ * Loads a CPU context
+ * @param ctx Thread context to load
+ * @param Do we need to load Reg[15] and NextInstr?
+ */
+void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
+    memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
+    memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+
+    state->Reg[13] = ctx.sp;
+    state->Reg[14] = ctx.lr;
+    state->pc = ctx.pc;
+    state->Cpsr = ctx.cpsr;
+
+    state->VFP[1] = ctx.fpscr;
+    state->VFP[2] = ctx.fpexc;
+
+    state->Reg[15] = ctx.reg_15;
+    state->NextInstr = ctx.mode;
+}
+
+/// Prepare core for thread reschedule (if needed to correctly handle state)
+void ARM_DynCom::PrepareReschedule() {
+    state->NumInstrsToExecute = 0;
+}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
new file mode 100644
index 000000000..9f88dd139
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -0,0 +1,90 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include <memory>
+
+#include "common/common_types.h"
+
+#include "core/arm/arm_interface.h"
+#include "core/arm/skyeye_common/armdefs.h"
+
+class ARM_DynCom final : virtual public ARM_Interface {
+public:
+
+    ARM_DynCom();
+    ~ARM_DynCom();
+
+    /**
+     * Set the Program Counter to an address
+     * @param addr Address to set PC to
+     */
+    void SetPC(u32 pc);
+
+    /*
+     * Get the current Program Counter
+     * @return Returns current PC
+     */
+    u32 GetPC() const;
+
+    /**
+     * Get an ARM register
+     * @param index Register index (0-15)
+     * @return Returns the value in the register
+     */
+    u32 GetReg(int index) const;
+
+    /**
+     * Set an ARM register
+     * @param index Register index (0-15)
+     * @param value Value to set register to
+     */
+    void SetReg(int index, u32 value);
+
+    /**
+     * Get the current CPSR register
+     * @return Returns the value of the CPSR register
+     */
+    u32 GetCPSR() const;
+
+    /**
+     * Set the current CPSR register
+     * @param cpsr Value to set CPSR to
+     */
+    void SetCPSR(u32 cpsr);
+
+    /**
+     * Returns the number of clock ticks since the last reset
+     * @return Returns number of clock ticks
+     */
+    u64 GetTicks() const;
+
+    /**
+     * Saves the current CPU context
+     * @param ctx Thread context to save
+     */
+    void SaveContext(ThreadContext& ctx);
+
+    /**
+     * Loads a CPU context
+     * @param ctx Thread context to load
+     */
+    void LoadContext(const ThreadContext& ctx);
+
+    /// Prepare core for thread reschedule (if needed to correctly handle state)
+    void PrepareReschedule();
+
+    /**
+     * Executes the given number of instructions
+     * @param num_instructions Number of instructions to executes
+     */
+    void ExecuteInstructions(int num_instructions);
+
+private:
+
+    std::unique_ptr<ARMul_State> state;
+    u64 ticks;
+
+};
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
new file mode 100644
index 000000000..5d174a08f
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -0,0 +1,402 @@
+/* Copyright (C) 
+* 2012 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+*/
+/**
+* @file arm_dyncom_dec.cpp
+* @brief Some common utility for arm decoder
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 7849
+* @date 2012-03-15
+*/
+
+#include "core/arm/skyeye_common/arm_regformat.h"
+#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/dyncom/arm_dyncom_dec.h"
+
+const ISEITEM arm_instruction[] = {
+	#define VFP_DECODE
+	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+	#undef VFP_DECODE
+	{"srs"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d,  8, 11, 0x00000005},
+	{"rfe"	,  4	,  6	, 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001,  8, 11, 0x0000000a},
+	{"bkpt"	,  2	,  3	, 20, 31, 0x00000e12,  4,  7, 0x00000007},
+	{"blx"	,  1	,  3	, 25, 31, 0x0000007d},
+	{"cps"	,  3	,  6	, 20, 31, 0x00000f10, 16, 16, 0x00000000,  5,  5, 0x00000000},
+	{"pld"	,  4	,  4	, 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f},
+	{"setend"	,  2	,  6	, 16, 31, 0x0000f101,  4,  7, 0x00000000},
+	{"clrex"	,  1	,  6	,  0, 31, 0xf57ff01f},
+	{"rev16"	,  2	,  6	, 16, 27, 0x000006bf,  4, 11, 0x000000fb},
+	{"usad8"	,  3	,  6	, 20, 27, 0x00000078, 12, 15, 0x0000000f,  4,  7, 0x00000001},
+	{"sxtb"	,  2	,  6	, 16, 27, 0x000006af,  4,  7, 0x00000007},
+	{"uxtb"	,  2	,  6	, 16, 27, 0x000006ef,  4,  7, 0x00000007},
+	{"sxth"	,  2	,  6	, 16, 27, 0x000006bf,  4,  7, 0x00000007},
+	{"sxtb16"	,  2	,  6	, 16, 27, 0x0000068f,  4,  7, 0x00000007},
+	{"uxth"	,  2	,  6	, 16, 27, 0x000006ff,  4,  7, 0x00000007},
+	{"uxtb16"	,  2	,  6	, 16, 27, 0x000006cf,  4,  7, 0x00000007},
+	{"cpy"	,  2	,  6	, 20, 27, 0x0000001a,  4, 11, 0x00000000},
+	{"uxtab"	,  2	,  6	, 20, 27, 0x0000006e,  4,  9, 0x00000007},
+	{"ssub8"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x0000000f},
+	{"shsub8"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x0000000f},
+	{"ssubaddx"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x00000005},
+	{"strex"	,  2	,  6	, 20, 27, 0x00000018,  4,  7, 0x00000009},
+	{"strexb"	,  2	,  7	, 20, 27, 0x0000001c,  4,  7, 0x00000009},
+	{"swp"	,  2	,  0	, 20, 27, 0x00000010,  4,  7, 0x00000009},
+	{"swpb"	,  2	,  0	, 20, 27, 0x00000014,  4,  7, 0x00000009},
+	{"ssub16"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x00000007},
+	{"ssat16"	,  2	,  6	, 20, 27, 0x0000006a,  4,  7, 0x00000003},
+	{"shsubaddx"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x00000005},
+	{"qsubaddx"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x00000005},
+	{"shaddsubx"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x00000003},
+	{"shadd8"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x00000009},
+	{"shadd16"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x00000001},
+	{"sel"	,  2	,  6	, 20, 27, 0x00000068,  4,  7, 0x0000000b},
+	{"saddsubx"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x00000003},
+	{"sadd8"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x00000009},
+	{"sadd16"	,  2	,  6	, 20, 27, 0x00000061,  4,  7, 0x00000001},
+	{"shsub16"	,  2	,  6	, 20, 27, 0x00000063,  4,  7, 0x00000007},
+	{"umaal"	,  2	,  6	, 20, 27, 0x00000004,  4,  7, 0x00000009},
+	{"uxtab16"	,  2	,  6	, 20, 27, 0x0000006c,  4,  7, 0x00000007},
+	{"usubaddx"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x00000005},
+	{"usub8"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x0000000f},
+	{"usub16"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x00000007},
+	{"usat16"	,  2	,  6	, 20, 27, 0x0000006e,  4,  7, 0x00000003},
+	{"usada8"	,  2	,  6	, 20, 27, 0x00000078,  4,  7, 0x00000001},
+	{"uqsubaddx"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x00000005},
+	{"uqsub8"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x0000000f},
+	{"uqsub16"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x00000007},
+	{"uqaddsubx"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x00000003},
+	{"uqadd8"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x00000009},
+	{"uqadd16"	,  2	,  6	, 20, 27, 0x00000066,  4,  7, 0x00000001},
+	{"sxtab"	,  2	,  6	, 20, 27, 0x0000006a,  4,  7, 0x00000007},
+	{"uhsubaddx"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x00000005},
+	{"uhsub8"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x0000000f},
+	{"uhsub16"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x00000007},
+	{"uhaddsubx"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x00000003},
+	{"uhadd8"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x00000009},
+	{"uhadd16"	,  2	,  6	, 20, 27, 0x00000067,  4,  7, 0x00000001},
+	{"uaddsubx"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x00000003},
+	{"uadd8"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x00000009},
+	{"uadd16"	,  2	,  6	, 20, 27, 0x00000065,  4,  7, 0x00000001},
+	{"sxtah"	,  2	,  6	, 20, 27, 0x0000006b,  4,  7, 0x00000007},
+	{"sxtab16"	,  2	,  6	, 20, 27, 0x00000068,  4,  7, 0x00000007},
+	{"qadd8"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x00000009},
+	{"bxj"	,  2	,  5	, 20, 27, 0x00000012,  4,  7, 0x00000002},
+	{"clz"	,  2	,  3	, 20, 27, 0x00000016,  4,  7, 0x00000001},
+	{"uxtah"	,  2	,  6	, 20, 27, 0x0000006f,  4,  7, 0x00000007},
+	{"bx"	,  2	,  2	, 20, 27, 0x00000012,  4,  7, 0x00000001},
+	{"rev"	,  2	,  6	, 20, 27, 0x0000006b,  4,  7, 0x00000003},
+	{"blx"	,  2	,  3	, 20, 27, 0x00000012,  4,  7, 0x00000003},
+	{"revsh"	,  2	,  6	, 20, 27, 0x0000006f,  4,  7, 0x0000000b},
+	{"qadd"	,  2	,  4	, 20, 27, 0x00000010,  4,  7, 0x00000005},
+	{"qadd16"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x00000001},
+	{"qaddsubx"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x00000003},
+	{"ldrex"	,  2	,  0	, 20, 27, 0x00000019,  4,  7, 0x00000009},
+	{"qdadd"	,  2	,  4	, 20, 27, 0x00000014,  4,  7, 0x00000005},
+	{"qdsub"	,  2	,  4	, 20, 27, 0x00000016,  4,  7, 0x00000005},
+	{"qsub"	,  2	,  4	, 20, 27, 0x00000012,  4,  7, 0x00000005},
+	{"ldrexb"	,  2	,  7	, 20, 27, 0x0000001d,  4,  7, 0x00000009},
+	{"qsub8"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x0000000f},
+	{"qsub16"	,  2	,  6	, 20, 27, 0x00000062,  4,  7, 0x00000007},
+	{"smuad"	,  4	,  6	, 20, 27, 0x00000070, 12, 15, 0x0000000f,  6,  7, 0x00000000,  4,  4, 0x00000001},
+	{"smmul"	,  4	,  6	, 20, 27, 0x00000075, 12, 15, 0x0000000f,  6,  7, 0x00000000,  4,  4, 0x00000001},
+	{"smusd"	,  4	,  6	, 20, 27, 0x00000070, 12, 15, 0x0000000f,  6,  7, 0x00000001,  4,  4, 0x00000001},
+	{"smlsd"	,  3	,  6	, 20, 27, 0x00000070,  6,  7, 0x00000001,  4,  4, 0x00000001},
+	{"smlsld"	,  3	,  6	, 20, 27, 0x00000074,  6,  7, 0x00000001,  4,  4, 0x00000001},
+	{"smmla"	,  3	,  6	, 20, 27, 0x00000075,  6,  7, 0x00000000,  4,  4, 0x00000001},
+	{"smmls"	,  3	,  6	, 20, 27, 0x00000075,  6,  7, 0x00000003,  4,  4, 0x00000001},
+	{"smlald"	,  3	,  6	, 20, 27, 0x00000074,  6,  7, 0x00000000,  4,  4, 0x00000001},
+	{"smlad"	,  3	,  6	, 20, 27, 0x00000070,  6,  7, 0x00000000,  4,  4, 0x00000001},
+	{"smlaw"	,  3	,  4	, 20, 27, 0x00000012,  7,  7, 0x00000001,  4,  5, 0x00000000},
+	{"smulw"	,  3	,  4	, 20, 27, 0x00000012,  7,  7, 0x00000001,  4,  5, 0x00000002},
+	{"pkhtb"	,  2	,  6	, 20, 27, 0x00000068,  4,  6, 0x00000005},
+	{"pkhbt"	,  2	,  6	, 20, 27, 0x00000068,  4,  6, 0x00000001},
+	{"smul"	,  3	,  4	, 20, 27, 0x00000016,  7,  7, 0x00000001,  4,  4, 0x00000000},
+	{"smlalxy"	,  3	,  4	, 20, 27, 0x00000014,  7,  7, 0x00000001,  4,  4, 0x00000000},
+//	{"smlal"	,  2	,  4	, 21, 27, 0x00000007,  4,  7, 0x00000009},
+	{"smla"	,  3	,  4	, 20, 27, 0x00000010,  7,  7, 0x00000001,  4,  4, 0x00000000},
+	{"mcrr"	,  1	,  6	, 20, 27, 0x000000c4},
+	{"mrrc"	,  1	,  6	, 20, 27, 0x000000c5},
+	{"cmp"	,  2	,  0	, 26, 27, 0x00000000, 20, 24, 0x00000015},
+	{"tst"	,  2	,  0	, 26, 27, 0x00000000, 20, 24, 0x00000011},
+	{"teq"	,  2	,  0	, 26, 27, 0x00000000, 20, 24, 0x00000013},
+	{"cmn"	,  2	,  0	, 26, 27, 0x00000000, 20, 24, 0x00000017},
+	{"smull"	,  2	,  0	, 21, 27, 0x00000006,  4,  7, 0x00000009},
+	{"umull"	,  2	,  0	, 21, 27, 0x00000004,  4,  7, 0x00000009},
+	{"umlal"	,  2	,  0	, 21, 27, 0x00000005,  4,  7, 0x00000009},
+	{"smlal"	,  2	,  0	, 21, 27, 0x00000007,  4,  7, 0x00000009},
+	{"mul"	,  2	,  0	, 21, 27, 0x00000000,  4,  7, 0x00000009},
+	{"mla"	,  2	,  0	, 21, 27, 0x00000001,  4,  7, 0x00000009},
+	{"ssat"	,  2	,  6	, 21, 27, 0x00000035,  4,  5, 0x00000001},
+	{"usat"	,  2	,  6	, 21, 27, 0x00000037,  4,  5, 0x00000001},
+	{"mrs"	,  4	,  0	, 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f,  0, 11, 0x00000000},
+	{"msr"	,  3	,  0	, 23, 27, 0x00000002, 20, 21, 0x00000002,  4,  7, 0x00000000},
+	{"and"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000000},
+	{"bic"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x0000000e},
+	{"ldm"	,  3	,  0	, 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000},
+	{"eor"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000001},
+	{"add"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000004},
+	{"rsb"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000003},
+	{"rsc"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000007},
+	{"sbc"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000006},
+	{"adc"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000005},
+	{"sub"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x00000002},
+	{"orr"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x0000000c},
+	{"mvn"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x0000000f},
+	{"mov"	,  2	,  0	, 26, 27, 0x00000000, 21, 24, 0x0000000d},
+	{"stm"	,  2	,  0	, 25, 27, 0x00000004, 20, 22, 0x00000004},
+	{"ldm"	,  4	,  0	, 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001},
+	{"ldrsh"	,  3	,  2	, 25, 27, 0x00000000, 20, 20, 0x00000001,  4,  7, 0x0000000f},
+	{"stm"	,  3	,  0	, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000},
+	{"ldm"	,  3	,  0	, 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001},
+	{"ldrsb"	,  3	,  2	, 25, 27, 0x00000000, 20, 20, 0x00000001,  4,  7, 0x0000000d},
+	{"strd"	,  3	,  4	, 25, 27, 0x00000000, 20, 20, 0x00000000,  4,  7, 0x0000000f},
+	{"ldrh"	,  3	,  0	, 25, 27, 0x00000000, 20, 20, 0x00000001,  4,  7, 0x0000000b},
+	{"strh"	,  3	,  0	, 25, 27, 0x00000000, 20, 20, 0x00000000,  4,  7, 0x0000000b},
+	{"ldrd"	,  3	,  4	, 25, 27, 0x00000000, 20, 20, 0x00000000,  4,  7, 0x0000000d},
+	{"strt"	,  3	,  0	, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002},
+	{"strbt"	,  3	,  0	, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006},
+	{"ldrbt"	,  3	,  0	, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007},
+	{"ldrt"	,  3	,  0	, 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003},
+	{"mrc"	,  3	,  6	, 24, 27, 0x0000000e, 20, 20, 0x00000001,  4,  4, 0x00000001},
+	{"mcr"	,  3	,  0	, 24, 27, 0x0000000e, 20, 20, 0x00000000,  4,  4, 0x00000001},
+	{"msr"	,  2	,  0	, 23, 27, 0x00000006, 20, 21, 0x00000002},
+	{"ldrb"	,  3	,  0	, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001},
+	{"strb"	,  3	,  0	, 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000},
+	{"ldr"	,  4	,  0	, 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
+	{"ldrcond"	,  3	,  0	, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
+	{"str"	,  3	,  0	, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000},
+	{"cdp"	,  2	,  0	, 24, 27, 0x0000000e,  4,  4, 0x00000000},
+	{"stc"	,  2	,  0	, 25, 27, 0x00000006, 20, 20, 0x00000000},
+	{"ldc"	,  2	,  0	, 25, 27, 0x00000006, 20, 20, 0x00000001},
+	{"swi"	,  1	,  0	, 24, 27, 0x0000000f},
+	{"bbl"	,  1	,  0	, 25, 27, 0x00000005},
+};
+
+const ISEITEM arm_exclusion_code[] = {
+	#define VFP_DECODE_EXCLUSION
+	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+	#undef VFP_DECODE_EXCLUSION
+	{"srs"	,  0	,  6	,  0},
+	{"rfe"	,  0	,  6	,  0},
+	{"bkpt"	,  0	,  3	,  0},
+	{"blx"	,  0	,  3	,  0},
+	{"cps"	,  0	,  6	,  0},
+	{"pld"	,  0	,  4	,  0},
+	{"setend"	,  0	,  6	,  0},
+	{"clrex"	,  0	,  6	,  0},
+	{"rev16"	,  0	,  6	,  0},
+	{"usad8"	,  0	,  6	,  0},
+	{"sxtb"	,  0	,  6	,  0},
+	{"uxtb"	,  0	,  6	,  0},
+	{"sxth"	,  0	,  6	,  0},
+	{"sxtb16"	,  0	,  6	,  0},
+	{"uxth"	,  0	,  6	,  0},
+	{"uxtb16"	,  0	,  6	,  0},
+	{"cpy"	,  0	,  6	,  0},
+	{"uxtab"	,  0	,  6	,  0},
+	{"ssub8"	,  0	,  6	,  0},
+	{"shsub8"	,  0	,  6	,  0},
+	{"ssubaddx"	,  0	,  6	,  0},
+	{"strex"	,  0	,  6	,  0},
+	{"strexb"	,  0	,  7	,  0},
+	{"swp"	,  0	,  0	,  0},
+	{"swpb"	,  0	,  0	,  0},
+	{"ssub16"	,  0	,  6	,  0},
+	{"ssat16"	,  0	,  6	,  0},
+	{"shsubaddx"	,  0	,  6	,  0},
+	{"qsubaddx"	,  0	,  6	,  0},
+	{"shaddsubx"	,  0	,  6	,  0},
+	{"shadd8"	,  0	,  6	,  0},
+	{"shadd16"	,  0	,  6	,  0},
+	{"sel"	,  0	,  6	,  0},
+	{"saddsubx"	,  0	,  6	,  0},
+	{"sadd8"	,  0	,  6	,  0},
+	{"sadd16"	,  0	,  6	,  0},
+	{"shsub16"	,  0	,  6	,  0},
+	{"umaal"	,  0	,  6	,  0},
+	{"uxtab16"	,  0	,  6	,  0},
+	{"usubaddx"	,  0	,  6	,  0},
+	{"usub8"	,  0	,  6	,  0},
+	{"usub16"	,  0	,  6	,  0},
+	{"usat16"	,  0	,  6	,  0},
+	{"usada8"	,  0	,  6	,  0},
+	{"uqsubaddx"	,  0	,  6	,  0},
+	{"uqsub8"	,  0	,  6	,  0},
+	{"uqsub16"	,  0	,  6	,  0},
+	{"uqaddsubx"	,  0	,  6	,  0},
+	{"uqadd8"	,  0	,  6	,  0},
+	{"uqadd16"	,  0	,  6	,  0},
+	{"sxtab"	,  0	,  6	,  0},
+	{"uhsubaddx"	,  0	,  6	,  0},
+	{"uhsub8"	,  0	,  6	,  0},
+	{"uhsub16"	,  0	,  6	,  0},
+	{"uhaddsubx"	,  0	,  6	,  0},
+	{"uhadd8"	,  0	,  6	,  0},
+	{"uhadd16"	,  0	,  6	,  0},
+	{"uaddsubx"	,  0	,  6	,  0},
+	{"uadd8"	,  0	,  6	,  0},
+	{"uadd16"	,  0	,  6	,  0},
+	{"sxtah"	,  0	,  6	,  0},
+	{"sxtab16"	,  0	,  6	,  0},
+	{"qadd8"	,  0	,  6	,  0},
+	{"bxj"	,  0	,  5	,  0},
+	{"clz"	,  0	,  3	,  0},
+	{"uxtah"	,  0	,  6	,  0},
+	{"bx"	,  0	,  2	,  0},
+	{"rev"	,  0	,  6	,  0},
+	{"blx"	,  0	,  3	,  0},
+	{"revsh"	,  0	,  6	,  0},
+	{"qadd"	,  0	,  4	,  0},
+	{"qadd16"	,  0	,  6	,  0},
+	{"qaddsubx"	,  0	,  6	,  0},
+	{"ldrex"	,  0	,  0	,  0},
+	{"qdadd"	,  0	,  4	,  0},
+	{"qdsub"	,  0	,  4	,  0},
+	{"qsub"	,  0	,  4	,  0},
+	{"ldrexb"	,  0	,  7	,  0},
+	{"qsub8"	,  0	,  6	,  0},
+	{"qsub16"	,  0	,  6	,  0},
+	{"smuad"	,  0	,  6	,  0},
+	{"smmul"	,  0	,  6	,  0},
+	{"smusd"	,  0	,  6	,  0},
+	{"smlsd"	,  0	,  6	,  0},
+	{"smlsld"	,  0	,  6	,  0},
+	{"smmla"	,  0	,  6	,  0},
+	{"smmls"	,  0	,  6	,  0},
+	{"smlald"	,  0	,  6	,  0},
+	{"smlad"	,  0	,  6	,  0},
+	{"smlaw"	,  0	,  4	,  0},
+	{"smulw"	,  0	,  4	,  0},
+	{"pkhtb"	,  0	,  6	,  0},
+	{"pkhbt"	,  0	,  6	,  0},
+	{"smul"	,  0	,  4	,  0},
+	{"smlal"	,  0	,  4	,  0},
+	{"smla"	,  0	,  4	,  0},
+	{"mcrr"	,  0	,  6	,  0},
+	{"mrrc"	,  0	,  6	,  0},
+	{"cmp"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"tst"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"teq"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"cmn"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"smull"	,  0	,  0	,  0},
+	{"umull"	,  0	,  0	,  0},
+	{"umlal"	,  0	,  0	,  0},
+	{"smlal"	,  0	,  0	,  0},
+	{"mul"	,  0	,  0	,  0},
+	{"mla"	,  0	,  0	,  0},
+	{"ssat"	,  0	,  6	,  0},
+	{"usat"	,  0	,  6	,  0},
+	{"mrs"	,  0	,  0	,  0},
+	{"msr"	,  0	,  0	,  0},
+	{"and"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"bic"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"ldm"	,  0	,  0	,  0},
+	{"eor"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"add"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"rsb"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"rsc"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"sbc"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"adc"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"sub"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"orr"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"mvn"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"mov"	,  3	,  0	,  4,  4, 0x00000001,  7,  7, 0x00000001, 25, 25, 0x00000000},
+	{"stm"	,  0	,  0	,  0},
+	{"ldm"	,  0	,  0	,  0},
+	{"ldrsh"	,  0	,  2	,  0},
+	{"stm"	,  0	,  0	,  0},
+	{"ldm"	,  0	,  0	,  0},
+	{"ldrsb"	,  0	,  2	,  0},
+	{"strd"	,  0	,  4	,  0},
+	{"ldrh"	,  0	,  0	,  0},
+	{"strh"	,  0	,  0	,  0},
+	{"ldrd"	,  0	,  4	,  0},
+	{"strt"	,  0	,  0	,  0},
+	{"strbt"	,  0	,  0	,  0},
+	{"ldrbt"	,  0	,  0	,  0},
+	{"ldrt"	,  0	,  0	,  0},
+	{"mrc"	,  0	,  6	,  0},
+	{"mcr"	,  0	,  0	,  0},
+	{"msr"	,  0	,  0	,  0},
+	{"ldrb"	,  0	,  0	,  0},
+	{"strb"	,  0	,  0	,  0},
+	{"ldr"	,  0	,  0	,  0},
+	{"ldrcond"	,  1	,  0	,  28, 31, 0x0000000e},
+	{"str"	,  0	,  0	,  0},
+	{"cdp"	,  0	,  0	,  0},
+	{"stc"	,  0	,  0	,  0},
+	{"ldc"	,  0	,  0	,  0},
+	{"swi"	,  0	,  0	,  0},
+	{"bbl"	,  0	,  0	,  0},
+        {"bl_1_thumb",      0,      INVALID, 0},/* should be table[-4] */         
+        {"bl_2_thumb",      0,      INVALID, 0}, /* should be located at the end of the table[-3] */
+	{"blx_1_thumb",      0,      INVALID, 0}, /* should be located at table[-2] */
+        {"invalid",      0,      INVALID, 0}         
+};
+
+int decode_arm_instr(uint32_t instr, int32_t *idx)
+{
+	int n = 0;
+	int base = 0;
+	int ret = DECODE_FAILURE;
+	int i = 0;
+	int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM);
+	for (i = 0; i < instr_slots; i++)
+	{
+//		ret = DECODE_SUCCESS;
+		n = arm_instruction[i].attribute_value;
+		base = 0;
+		while (n) {
+			if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
+				/* clrex */
+				if (instr != arm_instruction[i].content[base + 2]) {
+					break;
+				}
+			} else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
+				break;
+			}
+			base += 3;
+			n --;
+		}
+		//All conditions is satisfied.
+		if (n == 0)
+			ret = DECODE_SUCCESS;
+
+		if (ret == DECODE_SUCCESS) {
+			n = arm_exclusion_code[i].attribute_value;
+			if (n != 0) {
+				base = 0;
+				while (n) {
+					if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
+						break;					}
+					base += 3;
+					n --;
+				}
+				//All conditions is satisfied.
+				if (n == 0)
+					ret = DECODE_FAILURE;
+			}
+		}
+
+		if (ret == DECODE_SUCCESS) {
+			*idx = i;
+			return ret;
+		}
+	}
+	return ret;
+}
+
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
new file mode 100644
index 000000000..19d94f369
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -0,0 +1,155 @@
+/* Copyright (C) 
+* 2012 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+*/
+
+/**
+* @file arm_dyncom_dec.h
+* @brief Some common utility for arm instruction decoder
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 7849
+* @date 2012-03-15
+*/
+
+#ifndef __ARM_DYNCOM_DEC__
+#define __ARM_DYNCOM_DEC__
+
+#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
+#define BIT(n) ((instr >> (n)) & 1)
+#define BAD	do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0);
+#define ptr_N	cpu->ptr_N
+#define ptr_Z	cpu->ptr_Z
+#define ptr_C	cpu->ptr_C
+#define ptr_V	cpu->ptr_V
+#define ptr_I 	cpu->ptr_I
+#define ptr_T 	cpu->ptr_T
+#define	ptr_CPSR cpu->ptr_gpr[16]
+
+/* for MUL instructions */
+/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
+#define RDHi ((instr >> 16) & 0xF)
+/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
+#define RDLo ((instr >> 12) & 0xF)
+/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
+#define MUL_RD ((instr >> 16) & 0xF)
+/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
+#define MUL_RN ((instr >> 12) & 0xF)
+/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */
+#define RS ((instr >> 8) & 0xF)
+
+/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
+#define RD ((instr >> 12) & 0xF)
+/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
+#define RN ((instr >> 16) & 0xF)
+/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
+#define RM (instr & 0xF)
+#define BIT(n) ((instr >> (n)) & 1)
+#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
+
+/* CP15 registers */
+#define OPCODE_1        BITS(21, 23)
+#define CRn             BITS(16, 19)
+#define CRm             BITS(0, 3)
+#define OPCODE_2        BITS(5, 7)
+
+/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */
+#define I BIT(25)
+/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */
+#define S BIT(20)
+
+#define SHIFT BITS(5,6)
+#define SHIFT_IMM BITS(7,11)
+#define IMMH BITS(8,11)
+#define IMML BITS(0,3)
+
+#define LSPBIT  BIT(24)
+#define LSUBIT  BIT(23)
+#define LSBBIT  BIT(22)
+#define LSWBIT  BIT(21)
+#define LSLBIT  BIT(20)
+#define LSSHBITS BITS(5,6)
+#define OFFSET12 BITS(0,11)
+#define SBIT  BIT(20)
+#define DESTReg (BITS (12, 15))
+
+/* they are in unused state, give a corrent value when using */
+#define IS_V5E 0
+#define IS_V5  0
+#define IS_V6  0
+#define LHSReg 0
+
+/* temp define the using the pc reg need implement a flow */
+#define STORE_CHECK_RD_PC	ADD(R(RD), CONST(INSTR_SIZE * 2))
+
+#define OPERAND operand(cpu,instr,bb,NULL)
+#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
+#define BOPERAND boperand(instr)
+
+#define CHECK_RN_PC  (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN))
+#define CHECK_RN_PC_WA  (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN))
+
+#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
+
+int decode_arm_instr(uint32_t instr, int32_t *idx);
+
+enum DECODE_STATUS {
+	DECODE_SUCCESS,
+	DECODE_FAILURE
+};
+
+struct instruction_set_encoding_item {
+        const char *name;
+        int attribute_value;
+        int version;
+        u32 content[21];
+};
+
+typedef struct instruction_set_encoding_item ISEITEM;
+
+#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;}
+#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag)
+
+#define EXECUTE_WB(base_reg)		{if(cpu->dyncom_engine->wb_flag) \
+                                               LET(base_reg, cpu->dyncom_engine->wb_value);}
+inline int get_reg_count(uint32_t instr){
+	int i =  BITS(0,15);
+	int count = 0;
+	while(i){
+		if(i & 1)
+			count ++;
+		i = i >> 1;
+	}
+	return count;
+}
+
+enum ARMVER {
+	INVALID = 0,
+        ARMALL,
+        ARMV4,
+        ARMV4T,
+        ARMV5T,
+        ARMV5TE,
+        ARMV5TEJ,
+        ARMV6,
+	ARM1176JZF_S,
+        ARMVFP2,
+        ARMVFP3
+};
+
+//extern const INSTRACT arm_instruction_action[];
+extern const ISEITEM arm_instruction[];
+
+#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
new file mode 100644
index 000000000..8739b8c14
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -0,0 +1,6559 @@
+/* Copyright (C) 
+* 2012 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+*/
+/**
+* @file arm_dyncom_interpreter.cpp
+* @brief The fast interpreter for arm
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 7849
+* @date 2012-03-15
+*/
+
+#define CITRA_IGNORE_EXIT(x)
+
+#include <algorithm>
+#include <map>
+#include <stdio.h>
+#include <assert.h>
+#include <cstdio>
+#include <vector>
+
+using namespace std;
+
+#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armmmu.h"
+#include "arm_dyncom_thumb.h"
+#include "arm_dyncom_run.h"
+#include "core/arm/skyeye_common/vfp/vfp.h"
+/* shenoubang 2012-6-14 */
+#ifdef __WIN32__
+#include "bank_defs.h"
+#endif
+
+#include "core/mem_map.h"
+#include "core/hle/hle.h"
+
+enum {
+    COND = (1 << 0),
+    NON_BRANCH = (1 << 1),
+    DIRECT_BRANCH = (1 << 2),
+    INDIRECT_BRANCH = (1 << 3),
+    CALL = (1 << 4),
+    RET = (1 << 5),
+    END_OF_PAGE = (1 << 6),
+    THUMB = (1 << 7)
+};
+
+#define USER_MODE_OPT	1
+#define HYBRID_MODE		0 // Enable for JIT mode
+
+#define THRESHOLD			1000
+#define DURATION			500
+//#define PRINT_PROFILE_INFO
+
+#define CHECK_RS 	if(RS == 15) rs += 8
+#define CHECK_RM 	if(RM == 15) rm += 8
+
+//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1))
+#undef BITS
+#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
+#define BIT(s, n) ((s >> (n)) & 1)
+#define RM	BITS(sht_oper, 0, 3)
+#define RS	BITS(sht_oper, 8, 11)
+
+#define glue(x, y)		x ## y
+#define DPO(s)			glue(DataProcessingOperands, s)
+#define ROTATE_RIGHT(n, i, l)	((n << (l - i)) | (n >> i))
+#define ROTATE_LEFT(n, i, l)	((n >> (l - i)) | (n << i))
+#define ROTATE_RIGHT_32(n, i)	ROTATE_RIGHT(n, i, 32)
+#define ROTATE_LEFT_32(n, i)	ROTATE_LEFT(n, i, 32)
+
+//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n))))
+//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1)))
+#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) )
+
+extern void switch_mode(arm_core_t *core, uint32_t mode);
+//extern bool InAPrivilegedMode(arm_core_t *core);
+
+typedef arm_core_t arm_processor;
+typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
+
+/* exclusive memory access */
+static int exclusive_detect(ARMul_State* state, ARMword addr){
+	int i;
+	#if 0
+	for(i = 0; i < 128; i++){
+		if(state->exclusive_tag_array[i] == addr)
+			return 0;
+	}
+	#endif
+	if(state->exclusive_tag == addr)
+		return 0;
+	else
+		return -1;
+}
+
+static void add_exclusive_addr(ARMul_State* state, ARMword addr){
+	int i;
+	#if 0
+	for(i = 0; i < 128; i++){
+		if(state->exclusive_tag_array[i] == 0xffffffff){
+			state->exclusive_tag_array[i] = addr;
+			//DEBUG_LOG(ARM11, "In %s, add  addr 0x%x\n", __func__, addr);
+			return;
+		}
+	}
+	DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
+	#endif
+	state->exclusive_tag = addr;
+	return;
+}
+
+static void remove_exclusive(ARMul_State* state, ARMword addr){
+	#if 0
+	int i;
+	for(i = 0; i < 128; i++){
+		if(state->exclusive_tag_array[i] == addr){
+			state->exclusive_tag_array[i] = 0xffffffff;
+			//DEBUG_LOG(ARM11, "In %s, remove  addr 0x%x\n", __func__, addr);
+			return;
+		}
+	}
+	#endif
+	state->exclusive_tag = 0xFFFFFFFF;
+}
+
+
+unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int immed_8 = BITS(sht_oper, 0, 7);
+	unsigned int rotate_imm = BITS(sht_oper, 8, 11);
+//	DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8);
+//	DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm);
+	unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
+//	DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand);
+	/* set c flag */
+	if (rotate_imm == 0) 
+		cpu->shifter_carry_out = cpu->CFlag;
+	else
+		cpu->shifter_carry_out = BIT(shifter_operand, 31);
+	return shifter_operand;
+}
+
+unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand = rm;
+	cpu->shifter_carry_out = cpu->CFlag;
+	return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	int shift_imm = BITS(sht_oper, 7, 11);
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand;
+	if (shift_imm == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = cpu->CFlag;
+	} else {
+		shifter_operand = rm << shift_imm;
+		cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	int shifter_operand;
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	unsigned int rs = CHECK_READ_REG15(cpu, RS);
+	//if (RM == 15) rm += 8;
+	//if (RS == 15) rs += 8;
+	if (BITS(rs, 0, 7) == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = cpu->CFlag;
+	} else if (BITS(rs, 0, 7) < 32) {
+		shifter_operand = rm << BITS(rs, 0, 7);
+		cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
+	} else if (BITS(rs, 0, 7) == 32) {
+		shifter_operand = 0;
+		cpu->shifter_carry_out = BIT(rm, 0);
+	} else {
+		shifter_operand = 0;
+		cpu->shifter_carry_out = 0;
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	//unsigned int rm = cpu->Reg[RM];
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand;
+	int shift_imm = BITS(sht_oper, 7, 11);
+	if (shift_imm == 0) {
+		shifter_operand = 0;
+		cpu->shifter_carry_out = BIT(rm, 31);
+	} else {
+		shifter_operand = rm >> shift_imm;
+		cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int rs = CHECK_READ_REG15(cpu, RS);
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RS == 15) rs += 8;
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand;
+	if (BITS(rs, 0, 7) == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = cpu->CFlag;
+	} else if (BITS(rs, 0, 7) < 32) {
+		shifter_operand = rm >> BITS(rs, 0, 7);
+		cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
+	} else if (BITS(rs, 0, 7) == 32) {
+		shifter_operand = 0;
+		cpu->shifter_carry_out = BIT(rm, 31);
+	} else {
+		shifter_operand = 0;
+		cpu->shifter_carry_out = 0;
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	//unsigned int rm = cpu->Reg[RM];
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand;
+	int shift_imm = BITS(sht_oper, 7, 11);
+	if (shift_imm == 0) {
+		if (BIT(rm, 31)) {
+			shifter_operand = 0;
+			cpu->shifter_carry_out = BIT(rm, 31);
+		} else {
+			shifter_operand = 0xFFFFFFFF;
+			cpu->shifter_carry_out = BIT(rm, 31);
+		}
+	} else {
+		shifter_operand = static_cast<int>(rm) >> shift_imm;
+		cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	//unsigned int rs = cpu->Reg[RS];
+	unsigned int rs = CHECK_READ_REG15(cpu, RS);
+	//unsigned int rm = cpu->Reg[RM];
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RS == 15) rs += 8;
+	//if (RM == 15) rm += 8;
+	unsigned int shifter_operand;
+	if (BITS(rs, 0, 7) == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = cpu->CFlag;
+	} else if (BITS(rs, 0, 7) < 32) {
+		shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
+		cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
+	} else {
+		if (BIT(rm, 31) == 0) {
+			shifter_operand = 0;
+		} else 
+			shifter_operand = 0xffffffff;
+		cpu->shifter_carry_out = BIT(rm, 31);
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int shifter_operand;
+	//unsigned int rm = cpu->Reg[RM];
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	int shift_imm = BITS(sht_oper, 7, 11);
+	if (shift_imm == 0) {
+		shifter_operand = (cpu->CFlag << 31) | 
+					(rm >> 1);
+		cpu->shifter_carry_out = BIT(rm, 0);
+	} else {
+		shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
+		cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
+	}
+	return shifter_operand;
+}
+
+unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
+{
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int rm = CHECK_READ_REG15(cpu, RM);
+	//if (RM == 15) rm += 8;
+	unsigned int rs = CHECK_READ_REG15(cpu, RS);
+	//if (RS == 15) rs += 8;
+	unsigned int shifter_operand;
+	if (BITS(rs, 0, 7) == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = cpu->CFlag;
+	} else if (BITS(rs, 0, 4) == 0) {
+		shifter_operand = rm;
+		cpu->shifter_carry_out = BIT(rm, 31);
+	} else {
+		shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
+		cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
+	}
+	#if 0
+	if (cpu->icounter >= 20371544) {
+		DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+		DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS);
+		DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]);
+	}
+	#endif
+	return shifter_operand;
+}
+
+//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu);
+typedef struct _MiscImmeData {
+	unsigned int U;
+	unsigned int Rn;
+	unsigned int offset_8;
+} MiscLSData;
+
+typedef struct _MiscRegData {
+	unsigned int U;
+	unsigned int Rn;
+	unsigned int Rm;
+} MiscRegData;
+
+typedef struct _MiscImmePreIdx {
+	unsigned int offset_8;
+	unsigned int U;
+	unsigned int Rn;
+} MiscImmePreIdx;
+
+typedef struct _MiscRegPreIdx {
+	unsigned int U;
+	unsigned int Rn;
+	unsigned int Rm;
+} MiscRegPreIdx;
+
+typedef struct _MiscImmePstIdx {
+	unsigned int offset_8;
+	unsigned int U;
+	unsigned int Rn;
+} MIscImmePstIdx;
+
+typedef struct _MiscRegPstIdx {
+	unsigned int Rn;
+	unsigned int Rm;
+	unsigned int U;
+} MiscRegPstIdx;
+
+typedef struct _LSWordorUnsignedByte {
+} LDnST;
+
+#if USER_MODE_OPT
+static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){
+	switch(size) {
+	case 8:
+        value = Memory::Read8(virt_addr);
+		break;
+	case 16:
+        value = Memory::Read16(virt_addr);
+		break;
+	case 32:
+        value = Memory::Read32(virt_addr);
+		break;
+	}
+	return NO_FAULT;
+}
+
+//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size)
+static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size)
+{
+	switch(size) {
+	case 8:
+        Memory::Write8(virt_addr, value & 0xff);
+		break;
+	case 16:
+		Memory::Write16(virt_addr, value & 0xffff);
+		break;
+	case 32:
+		Memory::Write32(virt_addr, value);
+		break;
+	}
+	return NO_FAULT;
+}
+
+static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){
+	*phys_addr = virt_addr;
+	return NO_FAULT;
+}
+
+#else
+fault_t interpreter_read_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size);
+fault_t interpreter_write_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size);
+fault_t interpreter_fetch(cpu_t *cpu, addr_t virt_addr, uint32_t &value, uint32_t size);
+fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw, tlb_type_t access_type = DATA_TLB);
+#endif
+
+typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw);
+
+typedef struct _ldst_inst {
+	unsigned int inst;
+	get_addr_fp_t get_addr;
+} ldst_inst;
+#define DEBUG_MSG	DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__);		\
+			DEBUG_LOG(ARM11, "inst is %x\n", inst);				\
+			CITRA_IGNORE_EXIT(0)
+
+int CondPassed(arm_processor *cpu, unsigned int cond);
+#define LnSWoUB(s)	glue(LnSWoUB, s)
+#define MLnS(s)		glue(MLnS, s)
+#define LdnStM(s)	glue(LdnStM, s)
+
+#define W_BIT		BIT(inst, 21)
+#define U_BIT		BIT(inst, 23)
+#define I_BIT		BIT(inst, 25)
+#define P_BIT		BIT(inst, 24)
+#define OFFSET_12	BITS(inst, 0, 11)
+fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int addr;
+	fault_t fault;
+	if (U_BIT) {
+		addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
+	} else {
+		addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
+	}
+	//if (Rn == 15) rn += 8;
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	return fault;
+//	return addr;
+}
+
+fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst, 0, 3);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rm == 15) rm += 8;
+	unsigned int addr;
+	if (U_BIT) {
+		addr = rn + rm;
+	} else {
+		addr = rn - rm;
+	}
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	return fault;
+}
+
+fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) addr += 8;
+
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (U_BIT) {
+		cpu->Reg[Rn] += OFFSET_12;
+	} else {
+		cpu->Reg[Rn] -= OFFSET_12;
+	}
+	return fault;
+}
+
+fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int addr;
+	if (U_BIT) {
+		addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
+	} else {
+		addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
+	}
+	#if 0
+	if (Rn == 15) {
+		addr += 8;
+	}
+	#endif
+
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		cpu->Reg[Rn] = addr;
+	}
+	return fault;
+}
+
+fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int addr;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst,  0,  3);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rn == 15) rn += 8;
+	//if (Rm == 15) rm += 8;
+	if (U_BIT) {
+		addr = rn + rm;
+	} else
+		addr = rn - rm;
+	if(BIT(inst, 20)){ /* L BIT */
+	}
+	if(BIT(inst, 6)){ /* Sign Bit */
+	}
+	if(BIT(inst, 5)){ /* Half Bit */
+	}
+
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		cpu->Reg[Rn] = addr;
+	}
+	return fault;
+}
+
+fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst, 0, 3);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rm == 15) rm += 8;
+	unsigned int addr;
+	if (U_BIT) {
+		addr = rn + rm;
+	} else {
+		addr = rn - rm;
+	}
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if(fault)
+		return fault;
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		cpu->Reg[Rn] = addr;
+	}
+	return fault;
+}
+fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int shift = BITS(inst, 5, 6);
+	unsigned int shift_imm = BITS(inst, 7, 11);
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst, 0, 3);
+	unsigned int index;
+	unsigned int addr;
+
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rm == 15) rm += 8;
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	switch (shift) {
+	case 0:
+		//DEBUG_MSG;
+		index = rm << shift_imm;
+		break;
+	case 1:
+//		DEBUG_MSG;
+		if (shift_imm == 0) {
+			index = 0;
+		} else {
+			index = rm >> shift_imm;
+		}
+		break;
+	case 2:
+		DEBUG_MSG;
+		break;
+	case 3:
+		DEBUG_MSG;
+		break;
+	}
+	if (U_BIT) {
+		addr = rn + index;
+	} else
+		addr = rn - index;
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if(fault)
+		return fault;
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		cpu->Reg[Rn] = addr;
+	}
+
+	return fault;
+}
+
+fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int shift = BITS(inst, 5, 6);
+	unsigned int shift_imm = BITS(inst, 7, 11);
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst, 0, 3);
+	unsigned int index;
+	unsigned int addr;
+
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rm == 15) rm += 8;
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	addr = rn;
+	switch (shift) {
+	case 0:
+		//DEBUG_MSG;
+		index = rm << shift_imm;
+		break;
+	case 1:
+//		DEBUG_MSG;
+		if (shift_imm == 0) {
+			index = 0;
+		} else {
+			index = rm >> shift_imm;
+		}
+		break;
+	case 2:
+		DEBUG_MSG;
+		break;
+	case 3:
+		DEBUG_MSG;
+		break;
+	}
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if(fault)
+		return fault;
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		if (U_BIT)
+			cpu->Reg[Rn] += index;
+		else
+			cpu->Reg[Rn] -= index;
+	}
+
+	return fault;
+}
+
+fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst,  0,  3);
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+
+	unsigned int addr = rn;
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		if (U_BIT) {
+			cpu->Reg[Rn] += rm;
+		} else {
+			cpu->Reg[Rn] -= rm;
+		}
+	}
+	return fault;
+}
+
+fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int immedL = BITS(inst, 0, 3);
+	unsigned int immedH = BITS(inst, 8, 11);
+
+	unsigned int Rn     = BITS(inst, 16, 19);
+	unsigned int addr;
+
+	unsigned int offset_8 = (immedH << 4) | immedL;
+	if (U_BIT) {
+		addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
+	} else
+		addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
+	#if 0
+	if (Rn == 15) {
+		addr += 8;
+	}
+	#endif
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	return fault;
+}
+
+fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int addr;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst,  0,  3);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rn == 15) rn += 8;
+	//if (Rm == 15) rm += 8;
+	if (U_BIT) {
+		addr = rn + rm;
+	} else
+		addr = rn - rm;
+	if(BIT(inst, 20)){ /* L BIT */
+	}
+	if(BIT(inst, 6)){ /* Sign Bit */
+	}
+	if(BIT(inst, 5)){ /* Half Bit */
+	}
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	return fault;
+}
+
+fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn     = BITS(inst, 16, 19);
+	unsigned int immedH = BITS(inst,  8, 11);
+	unsigned int immedL = BITS(inst,  0,  3);
+	unsigned int addr;
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+
+//	DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
+	unsigned int offset_8 = (immedH << 4) | immedL;
+	if (U_BIT) {
+		addr = rn + offset_8;
+	} else 
+		addr = rn - offset_8;
+
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		cpu->Reg[Rn] = addr;
+	}
+	return fault;
+}
+
+fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn     = BITS(inst, 16, 19);
+	unsigned int immedH = BITS(inst,  8, 11);
+	unsigned int immedL = BITS(inst,  0,  3);
+	unsigned int addr;
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	addr = rn;
+
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		unsigned int offset_8 = (immedH << 4) | immedL;
+		if (U_BIT) {
+			rn += offset_8;
+		} else {
+			rn -= offset_8;
+		}
+		cpu->Reg[Rn] = rn;
+	}
+
+	return fault;
+}
+fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst,  0,  3);
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+
+	unsigned int addr = rn;
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31))) {
+		if (U_BIT) {
+			cpu->Reg[Rn] += rm;
+		} else {
+			cpu->Reg[Rn] -= rm;
+		}
+	}
+	return fault;
+}
+
+fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int i = BITS(inst, 0, 15);
+	int count = 0;
+	while(i) {
+		if(i & 1) count ++;
+		i = i >> 1;
+	}
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	unsigned int start_addr = rn - count * 4;
+	unsigned int end_addr   = rn - 4;
+
+	fault = check_address_validity(cpu, end_addr,   &phys_addr, rw);
+	virt_addr = end_addr;
+	if (fault) return fault;
+
+	fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+	virt_addr = start_addr;
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+		cpu->Reg[Rn] -= count * 4;
+	}
+
+	return fault;
+}
+
+fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int i = BITS(inst, 0, 15);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	int count = 0;
+	while(i) {
+		if(i & 1) count ++;
+		i = i >> 1;
+	}
+
+	unsigned int start_addr = rn + 4;
+	unsigned int end_addr   = rn + count * 4;
+
+	fault = check_address_validity(cpu, end_addr,   &phys_addr, rw);
+	virt_addr = end_addr;
+	if (fault) return fault;
+
+	fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+	virt_addr = start_addr;
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+		cpu->Reg[Rn] += count * 4;
+	}
+	return fault;
+}
+
+fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int i = BITS(inst, 0, 15);
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	int count = 0;
+	while(i) {
+		if(i & 1) count ++;
+		i = i >> 1;
+	}
+	//if (Rn == 15) rn += 8;
+	unsigned int start_addr = rn;
+	unsigned int end_addr = rn + count * 4 - 4;
+
+	fault = check_address_validity(cpu, end_addr,   &phys_addr, rw);
+	virt_addr = end_addr;
+	if (fault) return fault;
+
+	fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+	virt_addr = start_addr;
+	if (fault) return fault;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+		cpu->Reg[Rn] += count * 4;
+	}
+	return fault;
+}
+
+fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int i = BITS(inst, 0, 15);
+	int count = 0;
+	while(i) {
+		if(i & 1) count ++;
+		i = i >> 1;
+	}
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	unsigned int start_addr = rn - count * 4 + 4;
+	unsigned int end_addr   = rn;
+
+	fault = check_address_validity(cpu, end_addr,   &phys_addr, rw);
+	virt_addr = end_addr;
+	if (fault) return fault;
+
+	fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
+	if (fault) return fault;
+	virt_addr = start_addr;
+
+	if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
+		cpu->Reg[Rn] -= count * 4;
+	}
+	return fault;
+}
+
+fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
+{
+	fault_t fault;
+	unsigned int shift = BITS(inst, 5, 6);
+	unsigned int shift_imm = BITS(inst, 7, 11);
+	unsigned int Rn = BITS(inst, 16, 19);
+	unsigned int Rm = BITS(inst, 0, 3);
+	unsigned int index;
+	unsigned int addr;
+
+	unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
+	//if (Rm == 15) rm += 8;
+	unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
+	//if (Rn == 15) rn += 8;
+	switch (shift) {
+	case 0:
+		//DEBUG_MSG;
+		index = rm << shift_imm;
+		break;
+	case 1:
+//		DEBUG_MSG;
+		if (shift_imm == 0) {
+			index = 0;
+		} else {
+			index = rm >> shift_imm;
+		}
+		break;
+	case 2:
+		if (shift_imm == 0){ /* ASR #32 */
+			if (rm >> 31)
+				index = 0xFFFFFFFF;
+			else
+				index = 0;
+		}
+		else {
+			index = static_cast<int>(rm) >> shift_imm;
+		}
+		break;
+	case 3:
+		DEBUG_MSG;
+		break;
+	}
+	if (U_BIT) {
+		addr = rn + index;
+	} else
+		addr = rn - index;
+	virt_addr = addr;
+	fault = check_address_validity(cpu, addr, &phys_addr, rw);
+	return fault;
+}
+
+#define ISNEG(n)	(n < 0)
+#define ISPOS(n)	(n >= 0)
+
+//enum {
+//	COND            = (1 << 0),
+//	NON_BRANCH      = (1 << 1),
+//	DIRECT_BRANCH   = (1 << 2),
+//	INDIRECT_BRANCH = (1 << 3),
+//	CALL            = (1 << 4),
+//	RET             = (1 << 5),
+//	END_OF_PAGE     = (1 << 6),
+//	THUMB           = (1 << 7)
+//};
+
+typedef struct _arm_inst {
+	unsigned int idx;
+	unsigned int cond;
+	int br;
+	int load_r15;
+	char component[0];
+} arm_inst;
+
+typedef struct _adc_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} adc_inst;
+
+typedef struct _add_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} add_inst;
+
+typedef struct _orr_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} orr_inst;
+
+typedef struct _and_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} and_inst;
+
+typedef struct _eor_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} eor_inst;
+
+typedef struct _bbl_inst {
+	unsigned int L;
+	int signed_immed_24;
+	unsigned int next_addr;
+	unsigned int jmp_addr;
+} bbl_inst;
+
+typedef struct _bx_inst {
+	unsigned int Rm;
+} bx_inst;
+
+typedef struct _blx_inst {
+	union {
+		int32_t signed_immed_24;
+		uint32_t Rm;
+	} val;
+	unsigned int inst;
+} blx_inst;
+
+typedef struct _clz_inst {
+	unsigned int Rm;
+	unsigned int Rd;
+} clz_inst;
+
+typedef struct _cps_inst {
+	unsigned int imod0;
+	unsigned int imod1;
+	unsigned int mmod;
+	unsigned int A, I, F;
+	unsigned int mode;
+} cps_inst;
+
+typedef struct _clrex_inst {
+} clrex_inst;
+
+typedef struct _cpy_inst {
+	unsigned int Rm;
+	unsigned int Rd;
+} cpy_inst;
+
+typedef struct _bic_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} bic_inst;
+
+typedef struct _sub_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} sub_inst;
+
+typedef struct _tst_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} tst_inst;
+
+typedef struct _cmn_inst {
+	unsigned int I;
+	//unsigned int S;
+	unsigned int Rn;
+	//unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} cmn_inst;
+
+typedef struct _teq_inst {
+	unsigned int I;
+	unsigned int Rn;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} teq_inst;
+
+typedef struct _stm_inst {
+	unsigned int inst;
+} stm_inst;
+
+struct bkpt_inst {
+};
+
+struct blx1_inst {
+	unsigned int addr;
+};
+
+struct blx2_inst {
+	unsigned int Rm;
+};
+
+typedef struct _stc_inst {
+} stc_inst;
+
+typedef struct _ldc_inst {
+} ldc_inst;
+
+typedef struct _swi_inst {
+	unsigned int num;
+} swi_inst;
+
+typedef struct _cmp_inst {
+	unsigned int I;
+	unsigned int Rn;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} cmp_inst;
+
+typedef struct _mov_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} mov_inst;
+
+typedef struct _mvn_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} mvn_inst;
+
+typedef struct _rev_inst {
+	unsigned int Rd;
+	unsigned int Rm;
+} rev_inst;
+
+typedef struct _rsb_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} rsb_inst;
+
+typedef struct _rsc_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} rsc_inst;
+
+typedef struct _sbc_inst {
+	unsigned int I;
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int shifter_operand;
+	shtop_fp_t shtop_func;
+} sbc_inst;
+
+typedef struct _mul_inst {
+	unsigned int S;
+	unsigned int Rd;
+	unsigned int Rs;
+	unsigned int Rm;
+} mul_inst;
+
+typedef struct _smul_inst {
+	unsigned int Rd;
+	unsigned int Rs;
+	unsigned int Rm;
+	unsigned int x;
+	unsigned int y;
+} smul_inst;
+
+typedef struct _umull_inst {
+	unsigned int S;
+	unsigned int RdHi;
+	unsigned int RdLo;
+	unsigned int Rs;
+	unsigned int Rm;
+} umull_inst;
+typedef struct _smlad_inst {
+	unsigned int m;
+	unsigned int Rm;
+	unsigned int Rd;
+	unsigned int Ra;
+	unsigned int Rn;
+} smlad_inst;
+
+typedef struct _smla_inst {
+	unsigned int x;
+	unsigned int y;
+	unsigned int Rm;
+	unsigned int Rd;
+	unsigned int Rs;
+	unsigned int Rn;
+} smla_inst;
+
+typedef struct _umlal_inst {
+	unsigned int S;
+	unsigned int Rm;
+	unsigned int Rs;
+	unsigned int RdHi;
+	unsigned int RdLo;
+} umlal_inst;
+
+typedef struct _smlal_inst {
+	unsigned int S;
+	unsigned int Rm;
+	unsigned int Rs;
+	unsigned int RdHi;
+	unsigned int RdLo;
+} smlal_inst;
+
+typedef struct _mla_inst {
+	unsigned int S;
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int Rs;
+	unsigned int Rm;
+} mla_inst;
+
+typedef struct _mrc_inst {
+	unsigned int opcode_1;
+	unsigned int opcode_2;
+	unsigned int cp_num;
+	unsigned int crn;
+	unsigned int crm;
+	unsigned int Rd;
+	unsigned int inst;
+} mrc_inst;
+
+typedef struct _mcr_inst {
+	unsigned int opcode_1;
+	unsigned int opcode_2;
+	unsigned int cp_num;
+	unsigned int crn;
+	unsigned int crm;
+	unsigned int Rd;
+	unsigned int inst;
+} mcr_inst;
+
+typedef struct _mrs_inst {
+	unsigned int R;
+	unsigned int Rd;
+} mrs_inst;
+
+typedef struct _msr_inst {
+	unsigned int field_mask;
+	unsigned int R;
+	unsigned int inst;
+} msr_inst;
+
+typedef struct _pld_inst {
+} pld_inst;
+
+typedef struct _sxtb_inst {
+	unsigned int Rd;
+	unsigned int Rm;
+	unsigned int rotate;
+} sxtb_inst;
+
+typedef struct _sxtab_inst {
+	unsigned int Rd;
+	unsigned int Rn;
+	unsigned int Rm;
+	unsigned rotate;
+} sxtab_inst;
+
+typedef struct _sxtah_inst {
+	unsigned int Rd;
+	unsigned int Rn;
+	unsigned int Rm;
+	unsigned int rotate;
+} sxtah_inst;
+
+typedef struct _sxth_inst {
+	unsigned int Rd;
+	unsigned int Rm;
+	unsigned int rotate;
+} sxth_inst;
+
+typedef struct _uxtab_inst {
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int rotate;
+	unsigned int Rm;
+} uxtab_inst;
+
+typedef struct _uxtah_inst {
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int rotate;
+	unsigned int Rm;
+} uxtah_inst;
+
+typedef struct _uxth_inst {
+	unsigned int Rd;
+	unsigned int Rm;
+	unsigned int rotate;
+} uxth_inst;
+
+typedef struct _cdp_inst {
+	unsigned int opcode_1;
+	unsigned int CRn;
+	unsigned int CRd;
+	unsigned int cp_num;
+	unsigned int opcode_2;
+	unsigned int CRm;
+	uint32 inst;
+}cdp_inst;
+
+typedef struct _uxtb_inst {
+	unsigned int Rd;
+	unsigned int Rm;
+	unsigned int rotate;
+} uxtb_inst;
+
+typedef struct _swp_inst {
+	unsigned int Rn;
+	unsigned int Rd;
+	unsigned int Rm;
+} swp_inst;
+
+typedef struct _b_2_thumb {
+	unsigned int imm;
+}b_2_thumb;
+typedef struct _b_cond_thumb {
+	unsigned int imm;
+	unsigned int cond;
+}b_cond_thumb;
+
+typedef struct _bl_1_thumb {
+	unsigned int imm;
+}bl_1_thumb;
+typedef struct _bl_2_thumb {
+	unsigned int imm;
+}bl_2_thumb;
+typedef struct _blx_1_thumb {
+	unsigned int imm;
+	unsigned int instr;
+}blx_1_thumb;
+
+typedef arm_inst * ARM_INST_PTR;
+
+#define CACHE_BUFFER_SIZE	(64 * 1024 * 2000)
+char inst_buf[CACHE_BUFFER_SIZE];
+int top = 0;
+inline void *AllocBuffer(unsigned int size)
+{
+	int start = top;
+	top += size;
+	if (top > CACHE_BUFFER_SIZE) {
+		DEBUG_LOG(ARM11, "inst_buf is full\n");
+		CITRA_IGNORE_EXIT(-1);
+	}
+	return (void *)&inst_buf[start];
+}
+
+int CondPassed(arm_processor *cpu, unsigned int cond)
+{
+	#define NFLAG		cpu->NFlag
+	#define ZFLAG		cpu->ZFlag
+	#define CFLAG		cpu->CFlag
+	#define VFLAG		cpu->VFlag
+	int temp;
+	switch (cond) {
+	case 0x0:
+		temp = ZFLAG;
+		break;
+	case 0x1:   /* NE */
+		temp = !ZFLAG;
+		break;
+	case 0x6:  /* VS */
+		temp = VFLAG;
+		break;
+	case 0x7:        /* VC */
+		temp = !VFLAG;
+		break;
+	case 0x4:         /* MI */
+		temp = NFLAG;
+		break;
+	case 0x5:        /* PL */
+		temp = !NFLAG;
+		break;
+	case 0x2:       /* CS */
+		temp = CFLAG;
+		break;
+	case 0x3:      /* CC */
+		temp = !CFLAG;
+		break;
+	case 0x8:     /* HI */
+		temp = (CFLAG && !ZFLAG);
+		break;
+	case 0x9:    /* LS */
+		temp = (!CFLAG || ZFLAG);
+		break;
+	case 0xa:   /* GE */
+		temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
+		break;
+	case 0xb:  /* LT */
+		temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
+		break;
+	case 0xc:  /* GT */
+		temp = ((!NFLAG && !VFLAG && !ZFLAG)
+			|| (NFLAG && VFLAG && !ZFLAG));
+		break;
+	case 0xd:  /* LE */
+		temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
+			|| ZFLAG;
+		break;
+	case 0xe: /* AL */
+		temp = 1;
+		break;
+	case 0xf:
+//		DEBUG_LOG(ARM11, "inst is %x\n");
+//		DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter);
+//		CITRA_IGNORE_EXIT(-1);
+		temp = 1;
+		break;
+	}
+	return temp;
+}
+
+enum DECODE_STATUS {
+	DECODE_SUCCESS,
+	DECODE_FAILURE
+};
+
+int decode_arm_instr(uint32_t instr, int32_t *idx);
+
+shtop_fp_t get_shtop(unsigned int inst)
+{
+	if (BIT(inst, 25)) {
+		return DPO(Immediate);
+	} else if (BITS(inst, 4, 11) == 0) {
+		return DPO(Register);
+	} else if (BITS(inst, 4, 6) == 0) {
+		return DPO(LogicalShiftLeftByImmediate);
+	} else if (BITS(inst, 4, 7) == 1) {
+		return DPO(LogicalShiftLeftByRegister);
+	} else if (BITS(inst, 4, 6) == 2) {
+		return DPO(LogicalShiftRightByImmediate);
+	} else if (BITS(inst, 4, 7) == 3) {
+		return DPO(LogicalShiftRightByRegister);
+	} else if (BITS(inst, 4, 6) == 4) {
+		return DPO(ArithmeticShiftRightByImmediate);
+	} else if (BITS(inst, 4, 7) == 5) {
+		return DPO(ArithmeticShiftRightByRegister);
+	} else if (BITS(inst, 4, 6) == 6) {
+		return DPO(RotateRightByImmediate);
+	} else if (BITS(inst, 4, 7) == 7) {
+		return DPO(RotateRightByRegister);
+	}
+	return NULL;
+}
+
+get_addr_fp_t get_calc_addr_op(unsigned int inst)
+{
+	/* 1 */
+	if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LnSWoUB(ImmediateOffset);
+	} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
+//		DEBUG_MSG;
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LnSWoUB(RegisterOffset);
+	} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
+//		DEBUG_MSG;
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LnSWoUB(ScaledRegisterOffset);
+	} else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LnSWoUB(ImmediatePreIndexed);
+	} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
+		return LnSWoUB(RegisterPreIndexed);
+	} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
+		return LnSWoUB(ScaledRegisterPreIndexed);
+	} else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
+		return LnSWoUB(ImmediatePostIndexed);
+	} else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
+//		DEBUG_MSG;
+		return LnSWoUB(RegisterPostIndexed);
+	} else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
+		return LnSWoUB(ScaledRegisterPostIndexed);
+//		DEBUG_MSG;
+	} else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+	/* 2 */
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return MLnS(ImmediateOffset);
+//		DEBUG_MSG;
+	} else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+//		DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
+		return MLnS(RegisterOffset);
+//		DEBUG_MSG;
+	} else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+//		DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
+		return MLnS(ImmediatePreIndexed);
+//		DEBUG_MSG;
+	} else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+		return MLnS(RegisterPreIndexed);
+	} else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+//		DEBUG_MSG;
+		return MLnS(ImmediatePostIndexed);
+	} else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+		//DEBUG_MSG;
+		return MLnS(RegisterPostIndexed);
+	} else if (BITS(inst, 23, 27) == 0x11) {
+	/* 3 */
+//		DEBUG_MSG;
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LdnStM(IncrementAfter);
+	} else if (BITS(inst, 23, 27) == 0x13) {
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LdnStM(IncrementBefore);
+//		DEBUG_MSG;
+	} else if (BITS(inst, 23, 27) == 0x10) {
+//		DEBUG_MSG;
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LdnStM(DecrementAfter);
+	} else if (BITS(inst, 23, 27) == 0x12) {
+//		DEBUG_MSG;
+//		DEBUG_LOG(ARM11, "line is %d", __LINE__);
+		return LdnStM(DecrementBefore);
+	}
+	#if 0
+	DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__);
+	DEBUG_LOG(ARM11, "inst:%x\n", inst);
+	CITRA_IGNORE_EXIT(-1);
+	#endif
+	return NULL;
+}
+
+#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
+
+#define CHECK_RN			(inst_cream->Rn == 15)
+#define CHECK_RM			(inst_cream->Rm == 15)
+#define CHECK_RS			(inst_cream->Rs == 15)
+
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
+	adc_inst *inst_cream = (adc_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
+	add_inst *inst_cream = (add_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
+	and_inst *inst_cream = (and_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) 
+		inst_base->br = INDIRECT_BRANCH;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
+{
+	#define POSBRANCH ((inst & 0x7fffff) << 2)
+	#define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
+
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
+	bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = DIRECT_BRANCH;
+
+	if (BIT(inst, 24))
+		inst_base->br = CALL;
+	if (BITS(inst, 28, 31) <= 0xe)
+		inst_base->br |= COND;
+
+	inst_cream->L 	 = BIT(inst, 24);
+	inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
+	bic_inst *inst_cream = (bic_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (inst_cream->Rd == 15) 
+		inst_base->br = INDIRECT_BRANCH;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
+	blx_inst *inst_cream = (blx_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = INDIRECT_BRANCH;
+
+	inst_cream->inst = inst;
+	if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+		inst_cream->val.Rm = BITS(inst, 0, 3);
+	} else {
+		inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
+		//DEBUG_LOG(ARM11, " blx inst is %x\n", inst);
+		//CITRA_IGNORE_EXIT(-1);
+//		DEBUG_MSG;
+	}
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
+	bx_inst *inst_cream = (bx_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = INDIRECT_BRANCH;
+
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
+	cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->CRm   = BITS(inst,  0,  3);
+	inst_cream->CRd   = BITS(inst, 12, 15);
+	inst_cream->CRn   = BITS(inst, 16, 19);
+	inst_cream->cp_num   = BITS(inst, 8, 11);
+	inst_cream->opcode_2   = BITS(inst, 5, 7);
+	inst_cream->opcode_1   = BITS(inst, 20, 23);
+	inst_cream->inst = inst;
+
+	DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index);
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
+	clz_inst *inst_cream = (clz_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rm   = BITS(inst,  0,  3);
+	inst_cream->Rd   = BITS(inst, 12, 15);
+	if (CHECK_RM) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
+	cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	//inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	//inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
+	cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
+	cps_inst *inst_cream = (cps_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->imod0 = BIT(inst, 18);
+	inst_cream->imod1 = BIT(inst, 19);
+	inst_cream->mmod  = BIT(inst, 17);
+	inst_cream->A	  = BIT(inst, 8);
+	inst_cream->I	  = BIT(inst, 7);
+	inst_cream->F	  = BIT(inst, 6);
+	inst_cream->mode  = BITS(inst, 0, 4);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+	mov_inst *inst_cream = (mov_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
+	eor_inst *inst_cream = (eor_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BIT(inst, 15)) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+	sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	if (CHECK_RM) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+	uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	if (CHECK_RM) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
+	uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rn     = BITS(inst, 16, 19);
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	if (CHECK_RM || CHECK_RN) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	if (I_BIT == 0) {
+		inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+	} else {
+		DEBUG_MSG;
+	}
+	#if 0
+	inst_cream->get_addr = get_calc_addr_op(inst);
+	if(inst == 0x54f13001) {
+		DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
+	}
+	#endif
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	//inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	if (I_BIT == 0) {
+		inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+	} else {
+		DEBUG_MSG;
+	}
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
+	mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->crn      = BITS(inst, 16, 19);
+	inst_cream->crm      = BITS(inst,  0,  3);
+	inst_cream->opcode_1 = BITS(inst, 21, 23);
+	inst_cream->opcode_2 = BITS(inst,  5,  7);
+	inst_cream->Rd       = BITS(inst, 12, 15);
+	inst_cream->cp_num   = BITS(inst,  8, 11);
+	inst_cream->inst     = inst;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
+	mla_inst *inst_cream = (mla_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 12, 15);
+	inst_cream->Rd	 = BITS(inst, 16, 19);
+	inst_cream->Rs	 = BITS(inst,  8, 11);
+	inst_cream->Rm	 = BITS(inst,  0,  3);
+
+	if (CHECK_RM || CHECK_RN || CHECK_RS) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+	mov_inst *inst_cream = (mov_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
+	mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->crn      = BITS(inst, 16, 19);
+	inst_cream->crm      = BITS(inst,  0,  3);
+	inst_cream->opcode_1 = BITS(inst, 21, 23);
+	inst_cream->opcode_2 = BITS(inst,  5,  7);
+	inst_cream->Rd       = BITS(inst, 12, 15);
+	inst_cream->cp_num   = BITS(inst,  8, 11);
+	inst_cream->inst     = inst;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
+	mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->Rd   = BITS(inst, 12, 15);
+	inst_cream->R    = BIT(inst, 22);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
+	msr_inst *inst_cream = (msr_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->field_mask = BITS(inst, 16, 19);
+	inst_cream->R          = BIT(inst, 22);
+	inst_cream->inst       = inst;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
+	mul_inst *inst_cream = (mul_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->Rd	 = BITS(inst, 16, 19);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
+	mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
+	orr_inst *inst_cream = (orr_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_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;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+	rev_inst *inst_cream = (rev_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rm   = BITS(inst,  0,  3);
+	inst_cream->Rd   = BITS(inst, 12, 15);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+	rev_inst *inst_cream = (rev_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rm   = BITS(inst,  0,  3);
+	inst_cream->Rd   = BITS(inst, 12, 15);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
+	rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
+	rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (CHECK_RN)
+		inst_base->load_r15 = 1;
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
+	sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (CHECK_RN)
+		inst_base->load_r15 = 1;
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
+	smla_inst *inst_cream = (smla_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->x	 = BIT(inst, 5);
+	inst_cream->y	 = BIT(inst, 6);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->Rd = BITS(inst, 16, 19);
+	inst_cream->Rn = BITS(inst, 12, 15);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+	smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->m	 = BIT(inst, 4);
+	inst_cream->Rn	 = BITS(inst, 0, 3);
+	inst_cream->Rm	 = BITS(inst, 8, 11);
+	inst_cream->Rd = BITS(inst, 16, 19);
+	inst_cream->Ra = BITS(inst, 12, 15);
+
+	if (CHECK_RM ) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+	umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->RdHi = BITS(inst, 16, 19);
+	inst_cream->RdLo = BITS(inst, 12, 15);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
+	smul_inst *inst_cream = (smul_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd = BITS(inst, 16, 19);
+	inst_cream->Rs = BITS(inst,  8, 11);
+	inst_cream->Rm = BITS(inst,  0,  3);
+
+	inst_cream->x  = BIT(inst, 5);
+	inst_cream->y  = BIT(inst, 6);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+	umull_inst *inst_cream = (umull_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->RdHi = BITS(inst, 16, 19);
+	inst_cream->RdLo = BITS(inst, 12, 15);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+	smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->m	 = BIT(inst, 6);
+	inst_cream->Rm	 = BITS(inst, 8, 11);
+	inst_cream->Rn	 = BITS(inst, 0, 3);
+	inst_cream->Rd = BITS(inst, 16, 19);
+
+	if (CHECK_RM || CHECK_RN) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+	sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	inst_cream->rotate = BITS(inst, 10, 11);
+
+	if (CHECK_RM) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+	uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+
+	if (CHECK_RM) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+	uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	inst_cream->Rn     = BITS(inst, 16, 19);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+//	inst_cream->get_addr = get_calc_addr_op(inst);
+	if (I_BIT == 0) {
+		inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+	} else {
+		DEBUG_MSG;
+	}
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	inst_cream->get_addr = get_calc_addr_op(inst);
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+	ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->inst = inst;
+	if (I_BIT == 0) {
+		inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+	} else {
+		DEBUG_MSG;
+	}
+
+	if (BITS(inst, 12, 15) == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
+	sub_inst *inst_cream = (sub_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
+	swi_inst *inst_cream = (swi_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->num  = BITS(inst, 0, 23);
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+	swp_inst *inst_cream = (swp_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->Rm	 = BITS(inst,  0,  3);
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+	swp_inst *inst_cream = (swp_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->Rm	 = BITS(inst,  0,  3);
+
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
+	sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	inst_cream->Rn     = BITS(inst, 16, 19);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
+	DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__);
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
+	sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
+
+	inst_base->cond = BITS(inst, 28, 31);
+	inst_base->idx   = index;
+	inst_base->br    = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->Rd     = BITS(inst, 12, 15);
+	inst_cream->rotate = BITS(inst, 10, 11);
+	inst_cream->Rm     = BITS(inst,  0,  3);
+	inst_cream->Rn     = BITS(inst, 16, 19);
+
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
+	teq_inst *inst_cream = (teq_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
+	tst_inst *inst_cream = (tst_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->I	 = BIT(inst, 25);
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rn	 = BITS(inst, 16, 19);
+	inst_cream->Rd	 = BITS(inst, 12, 15);
+	inst_cream->shifter_operand = BITS(inst, 0, 11);
+	inst_cream->shtop_func = get_shtop(inst);
+	if (inst_cream->Rd == 15) {
+		inst_base->br = INDIRECT_BRANCH;
+	}
+
+	if (CHECK_RN) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+	umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->RdHi = BITS(inst, 16, 19);
+	inst_cream->RdLo = BITS(inst, 12, 15);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+	umull_inst *inst_cream = (umull_inst *)inst_base->component;
+
+	inst_base->cond  = BITS(inst, 28, 31);
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	inst_base->load_r15 = 0;
+
+	inst_cream->S	 = BIT(inst, 20);
+	inst_cream->Rm	 = BITS(inst, 0, 3);
+	inst_cream->Rs	 = BITS(inst, 8, 11);
+	inst_cream->RdHi = BITS(inst, 16, 19);
+	inst_cream->RdLo = BITS(inst, 12, 15);
+
+	if (CHECK_RM || CHECK_RS) 
+		inst_base->load_r15 = 1;
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
+	b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+
+	inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
+	//DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
+	inst_base->idx = index;
+	inst_base->br	 = DIRECT_BRANCH;
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
+	b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+
+	inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ?	0xFFFFFF00 : 0));
+	inst_cream->cond = ((tinst >> 8) & 0xf);
+	//DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond);
+	inst_base->idx = index;
+	inst_base->br	 = DIRECT_BRANCH;
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
+	bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
+
+	inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
+	//DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
+
+	inst_base->idx	 = index;
+	inst_base->br	 = NON_BRANCH;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
+	bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+
+	inst_cream->imm = (tinst & 0x07FF) << 1;
+	//DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
+	inst_base->idx = index;
+	inst_base->br	 = DIRECT_BRANCH;
+	return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
+{
+	arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
+	blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
+
+	inst_cream->imm = (tinst & 0x07FF) << 1;
+	//DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
+	inst_cream->instr = tinst;
+	inst_base->idx	 = index;
+	inst_base->br	 = DIRECT_BRANCH;
+	return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
+
+
+
+/* Floating point VFPv3 structures and instructions */
+
+#define VFP_INTERPRETER_STRUCT
+#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+#undef VFP_INTERPRETER_STRUCT
+ 
+#define VFP_INTERPRETER_TRANS
+#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+#undef VFP_INTERPRETER_TRANS
+
+
+
+typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
+
+const transop_fp_t arm_instruction_trans[] = {
+	#define VFP_INTERPRETER_TABLE
+	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+	#undef VFP_INTERPRETER_TABLE
+	INTERPRETER_TRANSLATE(srs),
+	INTERPRETER_TRANSLATE(rfe),
+	INTERPRETER_TRANSLATE(bkpt),
+	INTERPRETER_TRANSLATE(blx),
+	INTERPRETER_TRANSLATE(cps),
+	INTERPRETER_TRANSLATE(pld),
+	INTERPRETER_TRANSLATE(setend),
+	INTERPRETER_TRANSLATE(clrex),
+	INTERPRETER_TRANSLATE(rev16),
+	INTERPRETER_TRANSLATE(usad8),
+	INTERPRETER_TRANSLATE(sxtb),
+	INTERPRETER_TRANSLATE(uxtb),
+	INTERPRETER_TRANSLATE(sxth),
+	INTERPRETER_TRANSLATE(sxtb16),
+	INTERPRETER_TRANSLATE(uxth),
+	INTERPRETER_TRANSLATE(uxtb16),
+	INTERPRETER_TRANSLATE(cpy),
+	INTERPRETER_TRANSLATE(uxtab),
+	INTERPRETER_TRANSLATE(ssub8),
+	INTERPRETER_TRANSLATE(shsub8),
+	INTERPRETER_TRANSLATE(ssubaddx),
+	INTERPRETER_TRANSLATE(strex),
+	INTERPRETER_TRANSLATE(strexb),
+	INTERPRETER_TRANSLATE(swp),
+	INTERPRETER_TRANSLATE(swpb),
+	INTERPRETER_TRANSLATE(ssub16),
+	INTERPRETER_TRANSLATE(ssat16),
+	INTERPRETER_TRANSLATE(shsubaddx),
+	INTERPRETER_TRANSLATE(qsubaddx),
+	INTERPRETER_TRANSLATE(shaddsubx),
+	INTERPRETER_TRANSLATE(shadd8),
+	INTERPRETER_TRANSLATE(shadd16),
+	INTERPRETER_TRANSLATE(sel),
+	INTERPRETER_TRANSLATE(saddsubx),
+	INTERPRETER_TRANSLATE(sadd8),
+	INTERPRETER_TRANSLATE(sadd16),
+	INTERPRETER_TRANSLATE(shsub16),
+	INTERPRETER_TRANSLATE(umaal),
+	INTERPRETER_TRANSLATE(uxtab16),
+	INTERPRETER_TRANSLATE(usubaddx),
+	INTERPRETER_TRANSLATE(usub8),
+	INTERPRETER_TRANSLATE(usub16),
+	INTERPRETER_TRANSLATE(usat16),
+	INTERPRETER_TRANSLATE(usada8),
+	INTERPRETER_TRANSLATE(uqsubaddx),
+	INTERPRETER_TRANSLATE(uqsub8),
+	INTERPRETER_TRANSLATE(uqsub16),
+	INTERPRETER_TRANSLATE(uqaddsubx),
+	INTERPRETER_TRANSLATE(uqadd8),
+	INTERPRETER_TRANSLATE(uqadd16),
+	INTERPRETER_TRANSLATE(sxtab),
+	INTERPRETER_TRANSLATE(uhsubaddx),
+	INTERPRETER_TRANSLATE(uhsub8),
+	INTERPRETER_TRANSLATE(uhsub16),
+	INTERPRETER_TRANSLATE(uhaddsubx),
+	INTERPRETER_TRANSLATE(uhadd8),
+	INTERPRETER_TRANSLATE(uhadd16),
+	INTERPRETER_TRANSLATE(uaddsubx),
+	INTERPRETER_TRANSLATE(uadd8),
+	INTERPRETER_TRANSLATE(uadd16),
+	INTERPRETER_TRANSLATE(sxtah),
+	INTERPRETER_TRANSLATE(sxtab16),
+	INTERPRETER_TRANSLATE(qadd8),
+	INTERPRETER_TRANSLATE(bxj),
+	INTERPRETER_TRANSLATE(clz),
+	INTERPRETER_TRANSLATE(uxtah),
+	INTERPRETER_TRANSLATE(bx),
+	INTERPRETER_TRANSLATE(rev),
+	INTERPRETER_TRANSLATE(blx),
+	INTERPRETER_TRANSLATE(revsh),
+	INTERPRETER_TRANSLATE(qadd),
+	INTERPRETER_TRANSLATE(qadd16),
+	INTERPRETER_TRANSLATE(qaddsubx),
+	INTERPRETER_TRANSLATE(ldrex),
+	INTERPRETER_TRANSLATE(qdadd),
+	INTERPRETER_TRANSLATE(qdsub),
+	INTERPRETER_TRANSLATE(qsub),
+	INTERPRETER_TRANSLATE(ldrexb),
+	INTERPRETER_TRANSLATE(qsub8),
+	INTERPRETER_TRANSLATE(qsub16),
+	INTERPRETER_TRANSLATE(smuad),
+	INTERPRETER_TRANSLATE(smmul),
+	INTERPRETER_TRANSLATE(smusd),
+	INTERPRETER_TRANSLATE(smlsd),
+	INTERPRETER_TRANSLATE(smlsld),
+	INTERPRETER_TRANSLATE(smmla),
+	INTERPRETER_TRANSLATE(smmls),
+	INTERPRETER_TRANSLATE(smlald),
+	INTERPRETER_TRANSLATE(smlad),
+	INTERPRETER_TRANSLATE(smlaw),
+	INTERPRETER_TRANSLATE(smulw),
+	INTERPRETER_TRANSLATE(pkhtb),
+	INTERPRETER_TRANSLATE(pkhbt),
+	INTERPRETER_TRANSLATE(smul),
+	INTERPRETER_TRANSLATE(smlalxy),
+	INTERPRETER_TRANSLATE(smla),
+	INTERPRETER_TRANSLATE(mcrr),
+	INTERPRETER_TRANSLATE(mrrc),
+	INTERPRETER_TRANSLATE(cmp),
+	INTERPRETER_TRANSLATE(tst),
+	INTERPRETER_TRANSLATE(teq),
+	INTERPRETER_TRANSLATE(cmn),
+	INTERPRETER_TRANSLATE(smull),
+	INTERPRETER_TRANSLATE(umull),
+	INTERPRETER_TRANSLATE(umlal),
+	INTERPRETER_TRANSLATE(smlal),
+	INTERPRETER_TRANSLATE(mul),
+	INTERPRETER_TRANSLATE(mla),
+	INTERPRETER_TRANSLATE(ssat),
+	INTERPRETER_TRANSLATE(usat),
+	INTERPRETER_TRANSLATE(mrs),
+	INTERPRETER_TRANSLATE(msr),
+	INTERPRETER_TRANSLATE(and),
+	INTERPRETER_TRANSLATE(bic),
+	INTERPRETER_TRANSLATE(ldm),
+	INTERPRETER_TRANSLATE(eor),
+	INTERPRETER_TRANSLATE(add),
+	INTERPRETER_TRANSLATE(rsb),
+	INTERPRETER_TRANSLATE(rsc),
+	INTERPRETER_TRANSLATE(sbc),
+	INTERPRETER_TRANSLATE(adc),
+	INTERPRETER_TRANSLATE(sub),
+	INTERPRETER_TRANSLATE(orr),
+	INTERPRETER_TRANSLATE(mvn),
+	INTERPRETER_TRANSLATE(mov),
+	INTERPRETER_TRANSLATE(stm),
+	INTERPRETER_TRANSLATE(ldm),
+	INTERPRETER_TRANSLATE(ldrsh),
+	INTERPRETER_TRANSLATE(stm),
+	INTERPRETER_TRANSLATE(ldm),
+	INTERPRETER_TRANSLATE(ldrsb),
+	INTERPRETER_TRANSLATE(strd),
+	INTERPRETER_TRANSLATE(ldrh),
+	INTERPRETER_TRANSLATE(strh),
+	INTERPRETER_TRANSLATE(ldrd),
+	INTERPRETER_TRANSLATE(strt),
+	INTERPRETER_TRANSLATE(strbt),
+	INTERPRETER_TRANSLATE(ldrbt),
+	INTERPRETER_TRANSLATE(ldrt),
+	INTERPRETER_TRANSLATE(mrc),
+	INTERPRETER_TRANSLATE(mcr),
+	INTERPRETER_TRANSLATE(msr),
+	INTERPRETER_TRANSLATE(ldrb),
+	INTERPRETER_TRANSLATE(strb),
+	INTERPRETER_TRANSLATE(ldr),
+	INTERPRETER_TRANSLATE(ldrcond),
+	INTERPRETER_TRANSLATE(str),
+	INTERPRETER_TRANSLATE(cdp),
+	INTERPRETER_TRANSLATE(stc),
+	INTERPRETER_TRANSLATE(ldc),
+	INTERPRETER_TRANSLATE(swi),
+	INTERPRETER_TRANSLATE(bbl),
+	/* All the thumb instructions should be placed the end of table */
+	INTERPRETER_TRANSLATE(b_2_thumb), 
+	INTERPRETER_TRANSLATE(b_cond_thumb), 
+	INTERPRETER_TRANSLATE(bl_1_thumb), 
+	INTERPRETER_TRANSLATE(bl_2_thumb),
+	INTERPRETER_TRANSLATE(blx_1_thumb)
+};
+
+typedef map<unsigned int, int> bb_map;
+bb_map CreamCache[65536];
+bb_map ProfileCache[65536];
+
+//#define USE_DUMMY_CACHE
+
+#ifdef USE_DUMMY_CACHE
+unsigned int DummyCache[0x100000];
+#endif
+
+#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536)
+void insert_bb(unsigned int addr, int start)
+{
+#ifdef USE_DUMMY_CACHE
+	DummyCache[addr] = start;
+#else
+//	CreamCache[addr] = start;
+	CreamCache[HASH(addr)][addr] = start;
+#endif
+}
+
+#define TRANS_THRESHOLD                 65000
+int find_bb(unsigned int addr, int &start)
+{
+	int ret = -1;
+#ifdef USE_DUMMY_CACHE
+	start = DummyCache[addr];
+	if (start) {
+		ret = 0;
+	} else
+		ret = -1;
+#else
+	bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr);
+	if (it != CreamCache[HASH(addr)].end()) {
+		start = static_cast<int>(it->second);
+		ret = 0;
+#if HYBRID_MODE
+#if PROFILE
+#else
+		/* increase the bb counter */
+		if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){
+			push_to_compiled(cpu, addr);
+		}
+#endif
+#endif
+	} else {
+		ret = -1;
+	}
+#endif
+	return ret;
+}
+
+
+enum {
+	FETCH_SUCCESS,
+	FETCH_FAILURE
+};
+static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){
+	/* Check if in Thumb mode.  */
+	tdstate ret;
+	ret = thumb_translate (addr, inst, arm_inst, inst_size);
+	if(ret == t_branch){
+		/* FIXME, endian should be judged */
+		uint32 tinstr;
+		if((addr & 0x3) != 0)
+			tinstr = inst >> 16;
+		else
+			tinstr = inst & 0xFFFF;
+
+		//tinstr = inst & 0xFFFF;
+		int inst_index;
+		/* table_length */
+		int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
+
+		switch((tinstr & 0xF800) >> 11){
+		/* we will translate the thumb instruction directly here */
+		/* we will translate the thumb instruction directly here */
+		case 26:
+		case 27:
+			if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
+				uint32 cond = (tinstr & 0x0F00) >> 8;
+				inst_index = table_length - 4;
+				//DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
+				*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+			}
+			else{
+			/* something wrong */
+				DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__);
+			}
+			break;
+		case 28:
+			/* Branch 2, unconditional branch */
+			inst_index = table_length - 5;
+			//DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
+			*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+			break;
+
+		case 8:
+		case 29:
+			/* For BLX 1 thumb instruction*/
+			inst_index = table_length - 1;
+			//DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
+			*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+			break;
+		case 30:
+			/* For BL 1 thumb instruction*/
+			inst_index = table_length - 3;
+			//DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
+			*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+			break;
+		case 31:
+			/* For BL 2 thumb instruction*/
+			inst_index = table_length - 2;
+			//DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
+			*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
+			break;
+		default:
+			ret = t_undefined;
+			break;
+		}
+	}
+	return ret;
+}
+
+#if 0
+int FetchInst(cpu_t *core, unsigned int &inst)
+{
+	//arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
+	arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
+//	fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32);
+	fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32);
+	if (!core->is_user_mode) {
+		if (fault) {
+			cpu->abortSig = true;
+			cpu->Aborted = ARMul_PrefetchAbortV;
+			cpu->AbortAddr = cpu->translate_pc;
+			cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+			cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc;
+			return FETCH_FAILURE;
+		}
+	}
+	return FETCH_SUCCESS;
+}
+#endif
+
+unsigned int *InstLength;
+
+enum {
+	KEEP_GOING,
+	FETCH_EXCEPTION
+};
+
+typedef struct instruction_set_encoding_item ISEITEM;
+
+extern const ISEITEM arm_instruction[];
+
+vector<uint64_t> code_page_set;
+
+void flush_bb(uint32_t addr)
+{
+	bb_map::iterator it;
+	uint32_t start;
+
+	addr  &= 0xfffff000;
+	for (int i = 0; i < 65536; i ++) {
+		for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) {
+			start = static_cast<uint32_t>(it->first);
+			//start = (start >> 12) << 12;
+			start &= 0xfffff000;
+			if (start == addr) {
+				//DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
+				CreamCache[i].erase(it ++);
+			} else
+				++it;
+		}
+	}
+
+	for (int i = 0; i < 65536; i ++) {
+		for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) {
+			start = static_cast<uint32_t>(it->first);
+			//start = (start >> 12) << 12;
+			start &= 0xfffff000;
+			if (start == addr) {
+				//DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
+				ProfileCache[i].erase(it ++);
+			} else
+				++it;
+		}
+	}
+
+	//DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
+}
+
+//static uint32_t get_bank_addr(void *addr)
+//{
+//	uint64_t address = (uint64_t)addr;
+//	uint64_t bank0 = get_dma_addr(BANK0_START);
+//	if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) {
+//		//DEBUG_LOG(ARM11, "1.addr is %llx\n", addr);
+//		return ((uint64_t)addr - bank0) + BANK0_START;
+//	}
+//	return 0;
+//}
+
+/* shenoubang add win32 2012-6-12 */
+//#ifndef __WIN32__
+//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused)
+//{
+//	DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr);
+//	uint64_t addr = (uint64_t)si->si_addr;
+//	addr = (addr >> 12) << 12;
+//	skyeye_backtrace();
+//	#if 0
+//	if (addr == 0) {
+//		return;
+//	}
+//	const vector<uint64_t>::iterator it = find(code_page_set.begin(), 
+//						   code_page_set.end(),
+//						   (uint64_t)addr);
+//	if (it != code_page_set.end()) {
+//		code_page_set.erase(it);
+//	}
+//	mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE);
+//	//DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr);
+//	uint32_t phys_addr = get_bank_addr((void *)addr);
+////	DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr);
+//	flush_bb(phys_addr);
+//	flush_bb(phys_addr + 4096);
+//#if HYBRID_MODE
+//	/* flush the translated BB of dyncom */
+//      	clear_translated_cache(phys_addr); 
+//#endif
+//	#endif
+//}
+//#endif /* shenoubang */
+
+//void protect_code_page(uint32_t addr)
+//{
+//	void *mem_ptr = (void *)get_dma_addr(addr);
+//	mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL);
+//
+//	const vector<uint64_t>::iterator it = find(code_page_set.begin(), 
+//						   code_page_set.end(),
+//						   (uint64_t)mem_ptr);
+//	if (it != code_page_set.end()) {
+//		return;
+//	}
+//	//DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr);
+//	/* shenoubang add win32 2012-6-12 */
+//#ifndef __WIN32__
+//	struct sigaction sa;
+//
+//	memset(&sa, 0, sizeof(sa));
+//	sa.sa_flags = SA_RESTART | SA_SIGINFO;
+//	sa.sa_sigaction = &flush_code_cache;
+//	sigaction(SIGSEGV, &sa, NULL);
+//
+//	//mprotect(mem_ptr, 4096, PROT_READ);
+//
+//	code_page_set.push_back((uint64_t)mem_ptr);
+//#endif /* shenoubang */
+//}
+
+
+
+int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr)
+{
+	/* Decode instruction, get index */
+	/* Allocate memory and init InsCream */
+	/* Go on next, until terminal instruction */
+	/* Save start addr of basicblock in CreamCache */
+	//arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
+	//arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
+	ARM_INST_PTR inst_base = NULL;
+	unsigned int inst, inst_size = 4;
+	int idx;
+	int ret = NON_BRANCH;
+	int thumb = 0;
+	/* instruction size of basic block */
+	int size = 0;
+	/* (R15 - 8) ? */
+	//cpu->translate_pc = cpu->Reg[15];
+	bb_start = top;
+
+	if (cpu->TFlag)
+		thumb = THUMB;
+
+	addr_t phys_addr;
+	addr_t pc_start;
+	fault_t fault = NO_FAULT;
+	//fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB);
+	fault = check_address_validity(cpu, addr, &phys_addr, 1);
+	if(fault != NO_FAULT){
+		cpu->abortSig = true;
+		cpu->Aborted = ARMul_PrefetchAbortV;
+		cpu->AbortAddr = addr;
+		cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+		cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
+		return FETCH_EXCEPTION;
+	}
+	pc_start = phys_addr;
+	//phys_addr = get_dma_addr(phys_addr);
+	while(ret == NON_BRANCH) {
+		/* shenoubang add win32 2012-6-14 */
+#ifdef __WIN32__
+               mem_bank_t* bank;
+               if (bank = bank_ptr(addr)) {
+                       bank->bank_read(32, phys_addr, &inst);
+               }
+               else {
+                       DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr);
+                       return FETCH_FAILURE;
+               }
+#else
+        inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
+#endif
+		//or_tag(core, phys_addr,  TAG_FAST_INTERP);
+
+		/*if (ret == FETCH_FAILURE) {
+			return FETCH_EXCEPTION;
+		}*/
+
+		size ++;
+		/* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */
+		if (cpu->TFlag){
+		//if(cpu->Cpsr & (1 << THUMB_BIT)){
+			uint32_t arm_inst;
+			tdstate state;
+			state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
+			//or_tag(core, phys_addr, TAG_THUMB);
+			//DEBUG_LOG(ARM11, "In thumb state, arm_inst=0x%x, inst_size=0x%x, pc=0x%x\n", arm_inst, inst_size, cpu->translate_pc);
+			/* we have translated the branch instruction of thumb in thumb decoder */
+			if(state == t_branch){
+				goto translated;
+			}
+			inst = arm_inst;
+		}
+
+		ret = decode_arm_instr(inst, &idx);
+		if (ret == DECODE_FAILURE) {
+			DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst);
+			DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
+			CITRA_IGNORE_EXIT(-1);
+		}
+//		DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name);
+		inst_base = arm_instruction_trans[idx](inst, idx);
+//		DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst);
+//		DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]);
+translated:
+		phys_addr += inst_size;
+
+		if ((phys_addr & 0xfff) == 0) {
+			inst_base->br = END_OF_PAGE;
+		}
+		ret = inst_base->br;
+	};
+
+	//DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag);
+	insert_bb(pc_start, bb_start);
+	return KEEP_GOING;
+}
+
+#define LOG_IN_CLR	skyeye_printf_in_color
+
+int cmp(const void *x, const void *y)
+{
+	return *(unsigned long long int*)x - *(unsigned long long int *)y;
+}
+
+void InterpreterInitInstLength(unsigned long long int *ptr, size_t size)
+{
+	int array_size = size / sizeof(void *);
+	unsigned long long int *InstLabel = new unsigned long long int[array_size];
+	memcpy(InstLabel, ptr, size);
+	qsort(InstLabel, array_size, sizeof(void *), cmp);
+	InstLength = new unsigned int[array_size - 4];
+	for (int i = 0; i < array_size - 4; i ++) {
+		for (int j = 0; j < array_size; j ++) {
+			if (ptr[i] == InstLabel[j]) {
+				InstLength[i] = InstLabel[j + 1] - InstLabel[j];
+				break;
+			}
+		}
+	}
+	for (int i = 0; i < array_size - 4; i ++)
+		DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]);
+}
+
+int clz(unsigned int x)
+{
+	int n;
+	if (x == 0) return (32);
+	n = 1;
+	if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
+	if ((x >> 24) == 0) { n = n +  8; x = x <<  8;}
+	if ((x >> 28) == 0) { n = n +  4; x = x <<  4;}
+	if ((x >> 30) == 0) { n = n +  2; x = x <<  2;}
+	n = n - (x >> 31);
+	return n;
+}
+
+unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number);
+
+static bool InAPrivilegedMode(arm_core_t *core)
+{
+	return (core->Mode != USER32MODE);
+}
+
+/* r15 = r15 + 8 */
+void InterpreterMainLoop(ARMul_State* state)
+{
+	#define CRn				inst_cream->crn
+	#define OPCODE_2			inst_cream->opcode_2
+	#define CRm				inst_cream->crm
+	#define CP15_REG(n)			cpu->CP15[CP15(n)]
+	#define RD				cpu->Reg[inst_cream->Rd]
+	#define RN				cpu->Reg[inst_cream->Rn]
+	#define RM				cpu->Reg[inst_cream->Rm]
+	#define RS				cpu->Reg[inst_cream->Rs]
+	#define RDHI				cpu->Reg[inst_cream->RdHi]
+	#define RDLO				cpu->Reg[inst_cream->RdLo]
+	#define LINK_RTN_ADDR			(cpu->Reg[14] = cpu->Reg[15] + 4)
+	#define SET_PC				(cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
+	#define SHIFTER_OPERAND			inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
+
+	#if ENABLE_ICOUNTER
+	#define INC_ICOUNTER			cpu->icounter++;                                                   \
+						if(cpu->Reg[15] > 0xc0000000) 					\
+							cpu->kernel_icounter++;
+						//if (debug_function(core))                                          \
+							if (core->check_int_flag)                                  \
+								goto END
+						//DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15])
+	#else
+	#define INC_ICOUNTER			;                                                   
+	#endif
+
+	#define FETCH_INST			if (inst_base->br != NON_BRANCH)                                   \
+							goto PROFILING;                                             \
+						inst_base = (arm_inst *)&inst_buf[ptr]                             
+#define INC_PC(l)			ptr += sizeof(arm_inst) + l
+
+#ifdef __GNUC__
+#define GOTO_NEXT_INST			goto *InstLabel[inst_base->idx]
+#else
+#define GOTO_NEXT_INST switch(inst_base->idx) { \
+    case 0: goto VMLA_INST; \
+    case 1: goto VMLS_INST; \
+    case 2: goto VNMLA_INST; \
+    case 3: goto VNMLA_INST; \
+    case 4: goto VNMLS_INST; \
+    case 5: goto VNMUL_INST; \
+    case 6: goto VMUL_INST; \
+    case 7: goto VADD_INST; \
+    case 8: goto VSUB_INST; \
+    case 9: goto VDIV_INST; \
+    case 10: goto VMOVI_INST; \
+    case 11: goto VMOVR_INST; \
+    case 12: goto VABS_INST; \
+    case 13: goto VNEG_INST; \
+    case 14: goto VSQRT_INST; \
+    case 15: goto VCMP_INST; \
+    case 16: goto VCMP2_INST; \
+    case 17: goto VCVTBDS_INST; \
+    case 18: goto VCVTBFF_INST; \
+    case 19: goto VCVTBFI_INST; \
+    case 20: goto VMOVBRS_INST; \
+    case 21: goto VMSR_INST; \
+    case 22: goto VMOVBRC_INST; \
+    case 23: goto VMRS_INST; \
+    case 24: goto VMOVBCR_INST; \
+    case 25: goto VMOVBRRSS_INST; \
+    case 26: goto VMOVBRRD_INST; \
+    case 27: goto VSTR_INST; \
+    case 28: goto VPUSH_INST; \
+    case 29: goto VSTM_INST; \
+    case 30: goto VPOP_INST; \
+    case 31: goto VLDR_INST; \
+    case 32: goto VLDM_INST ; \
+    case 33: goto SRS_INST; \
+    case 34: goto RFE_INST; \
+    case 35: goto BKPT_INST; \
+    case 36: goto BLX_INST; \
+    case 37: goto CPS_INST; \
+    case 38: goto PLD_INST; \
+    case 39: goto SETEND_INST; \
+    case 40: goto CLREX_INST; \
+    case 41: goto REV16_INST; \
+    case 42: goto USAD8_INST; \
+    case 43: goto SXTB_INST; \
+    case 44: goto UXTB_INST; \
+    case 45: goto SXTH_INST; \
+    case 46: goto SXTB16_INST; \
+    case 47: goto UXTH_INST; \
+    case 48: goto UXTB16_INST; \
+    case 49: goto CPY_INST; \
+    case 50: goto UXTAB_INST; \
+    case 51: goto SSUB8_INST; \
+    case 52: goto SHSUB8_INST; \
+    case 53: goto SSUBADDX_INST; \
+    case 54: goto STREX_INST; \
+    case 55: goto STREXB_INST; \
+    case 56: goto SWP_INST; \
+    case 57: goto SWPB_INST; \
+    case 58: goto SSUB16_INST; \
+    case 59: goto SSAT16_INST; \
+    case 60: goto SHSUBADDX_INST; \
+    case 61: goto QSUBADDX_INST; \
+    case 62: goto SHADDSUBX_INST; \
+    case 63: goto SHADD8_INST; \
+    case 64: goto SHADD16_INST; \
+    case 65: goto SEL_INST; \
+    case 66: goto SADDSUBX_INST; \
+    case 67: goto SADD8_INST; \
+    case 68: goto SADD16_INST; \
+    case 69: goto SHSUB16_INST; \
+    case 70: goto UMAAL_INST; \
+    case 71: goto UXTAB16_INST; \
+    case 72: goto USUBADDX_INST; \
+    case 73: goto USUB8_INST; \
+    case 74: goto USUB16_INST; \
+    case 75: goto USAT16_INST; \
+    case 76: goto USADA8_INST; \
+    case 77: goto UQSUBADDX_INST; \
+    case 78: goto UQSUB8_INST; \
+    case 79: goto UQSUB16_INST; \
+    case 80: goto UQADDSUBX_INST; \
+    case 81: goto UQADD8_INST; \
+    case 82: goto UQADD16_INST; \
+    case 83: goto SXTAB_INST; \
+    case 84: goto UHSUBADDX_INST; \
+    case 85: goto UHSUB8_INST; \
+    case 86: goto UHSUB16_INST; \
+    case 87: goto UHADDSUBX_INST; \
+    case 88: goto UHADD8_INST; \
+    case 89: goto UHADD16_INST; \
+    case 90: goto UADDSUBX_INST; \
+    case 91: goto UADD8_INST; \
+    case 92: goto UADD16_INST; \
+    case 93: goto SXTAH_INST; \
+    case 94: goto SXTAB16_INST; \
+    case 95: goto QADD8_INST; \
+    case 96: goto BXJ_INST; \
+    case 97: goto CLZ_INST; \
+    case 98: goto UXTAH_INST; \
+    case 99: goto BX_INST; \
+    case 100: goto REV_INST; \
+    case 101: goto BLX_INST; \
+    case 102: goto REVSH_INST; \
+    case 103: goto QADD_INST; \
+    case 104: goto QADD16_INST; \
+    case 105: goto QADDSUBX_INST; \
+    case 106: goto LDREX_INST; \
+    case 107: goto QDADD_INST; \
+    case 108: goto QDSUB_INST; \
+    case 109: goto QSUB_INST; \
+    case 110: goto LDREXB_INST; \
+    case 111: goto QSUB8_INST; \
+    case 112: goto QSUB16_INST; \
+    case 113: goto SMUAD_INST; \
+    case 114: goto SMMUL_INST; \
+    case 115: goto SMUSD_INST; \
+    case 116: goto SMLSD_INST; \
+    case 117: goto SMLSLD_INST; \
+    case 118: goto SMMLA_INST; \
+    case 119: goto SMMLS_INST; \
+    case 120: goto SMLALD_INST; \
+    case 121: goto SMLAD_INST; \
+    case 122: goto SMLAW_INST; \
+    case 123: goto SMULW_INST; \
+    case 124: goto PKHTB_INST; \
+    case 125: goto PKHBT_INST; \
+    case 126: goto SMUL_INST; \
+    case 127: goto SMLAL_INST; \
+    case 128: goto SMLA_INST; \
+    case 129: goto MCRR_INST; \
+    case 130: goto MRRC_INST; \
+    case 131: goto CMP_INST; \
+    case 132: goto TST_INST; \
+    case 133: goto TEQ_INST; \
+    case 134: goto CMN_INST; \
+    case 135: goto SMULL_INST; \
+    case 136: goto UMULL_INST; \
+    case 137: goto UMLAL_INST; \
+    case 138: goto SMLAL_INST; \
+    case 139: goto MUL_INST; \
+    case 140: goto MLA_INST; \
+    case 141: goto SSAT_INST; \
+    case 142: goto USAT_INST; \
+    case 143: goto MRS_INST; \
+    case 144: goto MSR_INST; \
+    case 145: goto AND_INST; \
+    case 146: goto BIC_INST; \
+    case 147: goto LDM_INST; \
+    case 148: goto EOR_INST; \
+    case 149: goto ADD_INST; \
+    case 150: goto RSB_INST; \
+    case 151: goto RSC_INST; \
+    case 152: goto SBC_INST; \
+    case 153: goto ADC_INST; \
+    case 154: goto SUB_INST; \
+    case 155: goto ORR_INST; \
+    case 156: goto MVN_INST; \
+    case 157: goto MOV_INST; \
+    case 158: goto STM_INST; \
+    case 159: goto LDM_INST; \
+    case 160: goto LDRSH_INST; \
+    case 161: goto STM_INST; \
+    case 162: goto LDM_INST; \
+    case 163: goto LDRSB_INST; \
+    case 164: goto STRD_INST; \
+    case 165: goto LDRH_INST; \
+    case 166: goto STRH_INST; \
+    case 167: goto LDRD_INST; \
+    case 168: goto STRT_INST; \
+    case 169: goto STRBT_INST; \
+    case 170: goto LDRBT_INST; \
+    case 171: goto LDRT_INST; \
+    case 172: goto MRC_INST; \
+    case 173: goto MCR_INST; \
+    case 174: goto MSR_INST; \
+    case 175: goto LDRB_INST; \
+    case 176: goto STRB_INST; \
+    case 177: goto LDR_INST; \
+    case 178: goto LDRCOND_INST ; \
+    case 179: goto STR_INST; \
+    case 180: goto CDP_INST; \
+    case 181: goto STC_INST; \
+    case 182: goto LDC_INST; \
+    case 183: goto SWI_INST; \
+    case 184: goto BBL_INST; \
+    case 185: goto B_2_THUMB ; \
+    case 186: goto B_COND_THUMB ; \
+    case 187: goto BL_1_THUMB ; \
+    case 188: goto BL_2_THUMB ; \
+    case 189: goto BLX_1_THUMB ; \
+    case 190: goto DISPATCH; \
+    case 191: goto INIT_INST_LENGTH; \
+    case 192: goto END; \
+    }
+#endif
+
+	#define UPDATE_NFLAG(dst)		(cpu->NFlag = BIT(dst, 31) ? 1 : 0)
+	#define UPDATE_ZFLAG(dst)		(cpu->ZFlag = dst ? 0 : 1)
+//	#define UPDATE_CFLAG(dst, lop, rop)	(cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) ||                        \
+								(ISNEG(lop) && ISPOS(dst)) ||                       \
+								(ISPOS(rop) && ISPOS(dst))))
+	#define UPDATE_CFLAG(dst, lop, rop)	(cpu->CFlag = ((dst < lop) || (dst < rop)))
+	#define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag)	(cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
+	#define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
+	#define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop)	(cpu->CFlag = (lop >= rop))
+	#define UPDATE_CFLAG_WITH_NOT(dst, lop, rop)	(cpu->CFlag = !(dst < lop))
+	#define UPDATE_CFLAG_WITH_SC		cpu->CFlag = cpu->shifter_carry_out
+//	#define UPDATE_CFLAG_WITH_NOT(dst, lop, rop)	cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) ||                        \
+								(ISNEG(lop) && ISPOS(dst)) ||                       \
+								(ISPOS(rop) && ISPOS(dst)))
+	#define UPDATE_VFLAG(dst, lop, rop)	(cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) ||            \
+								((lop >= 0) && (rop) >= 0 && (dst < 0))))
+	#define UPDATE_VFLAG_WITH_NOT(dst, lop, rop)	(cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) ||            \
+								((lop >= 0) && (rop) >= 0 && (dst < 0))))
+	#define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop)	(cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
+
+	#define SAVE_NZCVT			cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
+						(cpu->NFlag << 31)   |                 \
+						(cpu->ZFlag << 30)   |                 \
+						(cpu->CFlag << 29)   |                 \
+						(cpu->VFlag << 28)   |			\
+						(cpu->TFlag << 5)
+	#define LOAD_NZCVT			cpu->NFlag = (cpu->Cpsr >> 31);   \
+						cpu->ZFlag = (cpu->Cpsr >> 30) & 1;   \
+						cpu->CFlag = (cpu->Cpsr >> 29) & 1;   \
+						cpu->VFlag = (cpu->Cpsr >> 28) & 1;	\
+						cpu->TFlag = (cpu->Cpsr >> 5) & 1;
+
+	#define CurrentModeHasSPSR		(cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
+	#define PC				(cpu->Reg[15])
+	#define CHECK_EXT_INT    		if (!cpu->NirqSig) {                       \
+				                	if (!(cpu->Cpsr & 0x80)) {         \
+								goto END;                  \
+							}                                  \
+						}
+
+	
+
+	//arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
+	arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
+
+#if __GNUC__
+    void *InstLabel[] = {
+		#define VFP_INTERPRETER_LABEL
+		#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+		#undef VFP_INTERPRETER_LABEL
+		&&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
+		&&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
+		&&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
+		&&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
+		&&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
+		&&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
+		&&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
+		&&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
+		&&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
+		&&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST,
+		&&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
+		&&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
+		&&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
+		&&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
+		&&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_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
+		};
+#endif
+	arm_inst * inst_base;
+	unsigned int lop, rop, dst;
+	unsigned int addr;
+	unsigned int phys_addr;
+	unsigned int last_pc = 0;
+	fault_t fault;
+	static unsigned int last_physical_base = 0, last_logical_base = 0;
+	int ptr;
+
+	LOAD_NZCVT;
+	DISPATCH:
+	{
+        if (cpu->NumInstrsToExecute == 0)
+            return;
+
+        cpu->NumInstrsToExecute--;
+
+        //NOTICE_LOG(ARM11, "instr!");
+
+		if (!cpu->NirqSig) {
+                	if (!(cpu->Cpsr & 0x80)) {
+				goto END;
+			}
+		}
+
+		if (cpu->TFlag) {
+			cpu->Reg[15] &= 0xfffffffe;
+		} else
+			cpu->Reg[15] &= 0xfffffffc;
+#if PROFILE
+		/* check next instruction address is valid. */
+		last_pc = cpu->Reg[15];
+#endif
+#if USER_MODE_OPT
+		phys_addr = cpu->Reg[15];
+#else
+		{
+			if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
+			       phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
+			else {
+			       /* check next instruction address is valid. */
+			       fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
+			       if (fault) {
+				       cpu->abortSig = true;
+				       cpu->Aborted = ARMul_PrefetchAbortV;
+				       cpu->AbortAddr = cpu->Reg[15];
+				       cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+				       cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
+				       goto END;
+			       }
+			       last_logical_base = cpu->Reg[15] & 0xfffff000;
+			       last_physical_base = phys_addr & 0xfffff000;
+			}
+		}
+#if HYBRID_MODE
+		/* check if the native code of dyncom is available */
+		//fast_map hash_map = core->dyncom_engine->fmap;
+		//void * pfunc = NULL;
+		//PFUNC(phys_addr);
+		//if(pfunc){
+		if(is_translated_entry(core, phys_addr)){
+			int rc = JIT_RETURN_NOERR;
+			//DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
+			SAVE_NZCVT;
+//			resume_timing();
+			rc = cpu_run(core);
+			LOAD_NZCVT;
+			//DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
+			if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
+				/* keep the tflag same with the bit in CPSR */
+				//cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
+				//cpu->TFlag = cpu->Cpsr & (1 << 5);
+				//switch_mode(cpu, cpu->Cpsr & 0x1f);
+				//DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
+			       fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
+			       if (fault) {
+				       cpu->abortSig = true;
+				       cpu->Aborted = ARMul_PrefetchAbortV;
+				       cpu->AbortAddr = cpu->Reg[15];
+				       cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+				       cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
+				       goto END;
+				}
+				last_logical_base = cpu->Reg[15] & 0xfffff000;
+				last_physical_base = phys_addr & 0xfffff000;
+				core->current_page_phys = last_physical_base;
+				core->current_page_effec = last_logical_base;
+				//push_to_compiled(core, phys_addr);
+			}
+			else{
+				if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
+					//DEBUG_LOG(ARM11, "\n\n###############In %s, fsr=0x%x, fault_addr=0x%x, pc=0x%x\n\n", __FUNCTION__, cpu->CP15[CP15(CP15_FAULT_STATUS)], cpu->CP15[CP15(CP15_FAULT_ADDRESS)], cpu->Reg[15]);
+			//core->Reg[15] -= get_instr_size(cpu_dyncom);
+					fill_tlb(cpu);
+					goto END;
+				}
+				if (cpu->syscallSig) {
+					goto END;
+				}
+				if (cpu->abortSig) {
+					cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
+					goto END;
+				}
+				if (!cpu->NirqSig) {
+					if (!(cpu->Cpsr & 0x80)) {
+						goto END;
+					}
+				}
+			
+				/* if regular trap */
+				cpu->Reg[15] += GET_INST_SIZE(cpu);
+				/*uint32_t mode = cpu->Cpsr & 0x1f;
+				if ((mode != cpu->Mode) && (!is_user_mode(core))) {
+					switch_mode(cpu, mode);
+					return 1;
+				}*/
+
+				goto END;
+			}
+			//phys_addr = cpu->Reg[15];
+		}
+		else{
+			if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
+			       phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
+			else {
+			       /* check next instruction address is valid. */
+			       fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
+			       if (fault) {
+				       cpu->abortSig = true;
+				       cpu->Aborted = ARMul_PrefetchAbortV;
+				       cpu->AbortAddr = cpu->Reg[15];
+				       cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
+				       cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
+				       goto END;
+			       }
+			       last_logical_base = cpu->Reg[15] & 0xfffff000;
+			       last_physical_base = phys_addr & 0xfffff000;
+			}
+		}
+#endif /* #if HYBRID_MODE */
+#endif /* #if USER_MODE_OPT */
+		if (true){//if(is_fast_interp_code(core, phys_addr)){
+			if (find_bb(phys_addr, ptr) == -1)
+				if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
+					goto END;
+		}
+		else{
+            if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
+				goto END;
+		}
+#if PROFILE
+		resume_timing();
+#endif
+		inst_base = (arm_inst *)&inst_buf[ptr];
+		GOTO_NEXT_INST;
+	}
+	PROFILING:
+	{
+		goto DISPATCH;
+	}
+	ADC_INST:
+	{
+		INC_ICOUNTER;
+		adc_inst *inst_cream = (adc_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			unsigned int sht_op = SHIFTER_OPERAND;
+			rop = SHIFTER_OPERAND + cpu->CFlag;
+			RD = dst = lop + rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
+				UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(adc_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(adc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	ADD_INST:
+	{
+		INC_ICOUNTER;
+		add_inst *inst_cream = (add_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			if (inst_cream->Rn == 15) {
+				lop += 2 * GET_INST_SIZE(cpu);
+			}
+			rop = SHIFTER_OPERAND;
+			RD = dst = lop + rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr*/
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Cpsr & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG(dst, lop, rop);
+				UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(add_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(add_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	AND_INST:
+	{
+		INC_ICOUNTER;
+		and_inst *inst_cream = (and_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			rop = SHIFTER_OPERAND;
+			RD = dst = lop & rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr*/
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Cpsr & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+				//UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(and_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(and_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	BBL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
+			if (inst_cream->L) {
+				LINK_RTN_ADDR;
+			}
+			SET_PC;
+			INC_PC(sizeof(bbl_inst));
+			goto PROFILING;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(bbl_inst));
+		goto PROFILING;
+	}
+	BIC_INST:
+	{
+		INC_ICOUNTER;
+		bic_inst *inst_cream = (bic_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			if (inst_cream->Rn == 15) {
+				lop += 2 * GET_INST_SIZE(cpu);
+			}
+			rop = SHIFTER_OPERAND;
+//			RD = dst = lop & (rop ^ 0xffffffff);
+			RD = dst = lop & (~rop);
+			if ((inst_cream->S) && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(bic_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(bic_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	BKPT_INST:
+	BLX_INST:
+	{
+		INC_ICOUNTER;
+		blx_inst *inst_cream = (blx_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int inst = inst_cream->inst;
+			if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+				//LINK_RTN_ADDR;
+				cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+				if(cpu->TFlag)
+					cpu->Reg[14] |= 0x1;
+				cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
+				cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
+				//cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe;
+				//cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1;
+			} else {
+				cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
+				cpu->TFlag = 0x1;
+				int signed_int = inst_cream->val.signed_immed_24;
+				signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
+				signed_int = signed_int << 2;
+			//	cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu) 
+				cpu->Reg[15] = cpu->Reg[15] + 8 
+						+ signed_int + (BIT(inst, 24) << 1);
+				//DEBUG_MSG;
+			}
+			INC_PC(sizeof(blx_inst));
+			goto PROFILING;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+//		INC_PC(sizeof(bx_inst));
+		INC_PC(sizeof(blx_inst));
+		goto PROFILING;
+	}
+	BX_INST:
+	{
+		INC_ICOUNTER;
+		bx_inst *inst_cream = (bx_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			if (inst_cream->Rm == 15)
+				DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]);
+			cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
+			cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
+//			cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
+			INC_PC(sizeof(bx_inst));
+			goto PROFILING;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+//		INC_PC(sizeof(bx_inst));
+		INC_PC(sizeof(bx_inst));
+		goto PROFILING;
+	}
+	BXJ_INST:
+	CDP_INST:
+	{
+		INC_ICOUNTER;
+		cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			/* FIXME, check if cp access allowed */
+			#define CP_ACCESS_ALLOW 0
+			if(CP_ACCESS_ALLOW){
+				/* undefined instruction here */
+				return;
+			}
+			ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
+			unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
+			if(cpab != ARMul_DONE){
+				ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num);
+				//CITRA_IGNORE_EXIT(-1);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(cdp_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+
+	CLREX_INST:
+	{
+		INC_ICOUNTER;
+		remove_exclusive(cpu, 0);
+		cpu->exclusive_state = 0;
+
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(clrex_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	CLZ_INST:
+	{
+		INC_ICOUNTER;
+		clz_inst *inst_cream = (clz_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			RD = clz(RM);
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(clz_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	CMN_INST:
+	{
+		INC_ICOUNTER;
+		cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+//			DEBUG_LOG(ARM11, "RN is %x\n", RN);
+			lop = RN;
+			rop = SHIFTER_OPERAND;
+			dst = lop + rop;
+			UPDATE_NFLAG(dst);
+			UPDATE_ZFLAG(dst);
+			UPDATE_CFLAG(dst, lop, rop);
+			UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(cmn_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	CMP_INST:
+	{
+//		DEBUG_LOG(ARM11, "cmp inst\n");
+//		DEBUG_LOG(ARM11, "pc:       %x\n", cpu->Reg[15]);
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+//			DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]);
+			cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
+			lop = RN;
+			if (inst_cream->Rn == 15) {
+				lop += 2 * GET_INST_SIZE(cpu);
+			}
+			rop = SHIFTER_OPERAND;
+			dst = lop - rop;
+
+			UPDATE_NFLAG(dst);
+			UPDATE_ZFLAG(dst);
+//			UPDATE_CFLAG(dst, lop, rop);
+			UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+//			UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+			UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+//			UPDATE_VFLAG_WITH_NOT(dst, lop, rop);
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(cmp_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	CPS_INST:
+	{
+		INC_ICOUNTER;
+		cps_inst *inst_cream = (cps_inst *)inst_base->component;
+		uint32_t aif_val = 0;
+		uint32_t aif_mask = 0;
+		if (InAPrivilegedMode(cpu)) {
+			/* isInAPrivilegedMode */
+			if (inst_cream->imod1) {
+				if (inst_cream->A) {
+					aif_val |= (inst_cream->imod0 << 8);
+					aif_mask |= 1 << 8;
+				}
+				if (inst_cream->I) {
+					aif_val |= (inst_cream->imod0 << 7);
+					aif_mask |= 1 << 7;
+				}
+				if (inst_cream->F) {
+					aif_val |= (inst_cream->imod0 << 6);
+					aif_mask |= 1 << 6;
+				}
+				aif_mask = ~aif_mask;
+				cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
+			}
+			if (inst_cream->mmod) {
+				cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
+				switch_mode(cpu, inst_cream->mode);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(cps_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	CPY_INST:
+	{
+		INC_ICOUNTER;
+		mov_inst *inst_cream = (mov_inst *)inst_base->component;
+//		cpy_inst *inst_cream = (cpy_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			RD = SHIFTER_OPERAND;
+//			RD = RM;
+			if ((inst_cream->Rd == 15)) {
+				INC_PC(sizeof(mov_inst));
+				goto PROFILING;
+			}
+		}
+//		DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]);
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mov_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	EOR_INST:
+	{
+		INC_ICOUNTER;
+		eor_inst *inst_cream = (eor_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			if (inst_cream->Rn == 15) {
+				lop += 2 * GET_INST_SIZE(cpu);
+			}
+			rop = SHIFTER_OPERAND;
+			RD = dst = lop ^ rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr*/
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+//				UPDATE_CFLAG(dst, lop, rop);
+//				UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(eor_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(eor_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDC_INST:
+	{
+		INC_ICOUNTER;
+		/* NOT IMPL */
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDM_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			int i;
+			unsigned int ret;
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) {
+				goto MMU_EXCEPTION;
+			}
+			unsigned int inst = inst_cream->inst;
+			if (BIT(inst, 22) && !BIT(inst, 15)) {
+//				DEBUG_MSG;
+				#if 1
+				/* LDM (2) user */
+				for (i = 0; i < 13; i++) {
+					if(BIT(inst, i)){
+						#if 0
+						fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						#endif
+						fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+						//if (fault) goto MMU_EXCEPTION;
+						cpu->Reg[i] = ret;
+						addr += 4;
+						if ((addr & 0xfff) == 0) {
+							fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						} else {
+							phys_addr += 4;
+						}
+					}
+				}
+				if (BIT(inst, 13)) {
+					#if 0
+					fault = check_address_validity(cpu, addr, &phys_addr, 1);
+					if (fault) {
+						goto MMU_EXCEPTION;
+					}
+					#endif
+					fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+					//if (fault) goto MMU_EXCEPTION;
+					if (cpu->Mode == USER32MODE) 
+						cpu->Reg[13] = ret;
+					else
+						cpu->Reg_usr[0] = ret;
+					addr += 4;
+					if ((addr & 0xfff) == 0) {
+						fault = check_address_validity(cpu, addr, &phys_addr, 1);
+					} else {
+						phys_addr += 4;
+					}
+				}
+				if (BIT(inst, 14)) {
+					#if 0
+					fault = check_address_validity(cpu, addr, &phys_addr, 1);
+					if (fault) {
+						goto MMU_EXCEPTION;
+					}
+					#endif
+					fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+					//if (fault) goto MMU_EXCEPTION;
+					if (cpu->Mode == USER32MODE) 
+						cpu->Reg[14] = ret;
+					else
+						cpu->Reg_usr[1] = ret;
+				}
+				#endif
+			} else if (!BIT(inst, 22)) {
+				for( i = 0; i < 16; i ++ ){
+					if(BIT(inst, i)){
+						//bus_read(32, addr, &ret);
+						#if 0
+						fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						#endif
+						fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+						if (fault) goto MMU_EXCEPTION;
+						/* For armv5t, should enter thumb when bits[0] is non-zero. */
+						if(i == 15){
+							cpu->TFlag = ret & 0x1;
+							ret &= 0xFFFFFFFE;
+							//DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
+						}
+
+						cpu->Reg[i] = ret;
+						addr += 4;
+						if ((addr & 0xfff) == 0) {
+							fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						} else {
+							phys_addr += 4;
+						}
+					}
+				}
+			} else if (BIT(inst, 22) && BIT(inst, 15)) {
+				for( i = 0; i < 15; i ++ ){
+					if(BIT(inst, i)){
+						#if 0
+						fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						#endif
+						fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+						//if (fault) goto MMU_EXCEPTION;
+						cpu->Reg[i] = ret;
+						addr += 4;
+						if ((addr & 0xfff) == 0) {
+							fault = check_address_validity(cpu, addr, &phys_addr, 1);
+						} else {
+							phys_addr += 4;
+						}
+ 					}
+ 				}
+				
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Cpsr & 0x1f);
+					LOAD_NZCVT;
+				}
+				#if 0
+				fault = check_address_validity(cpu, addr, &phys_addr, 1);
+				if (fault) {
+					goto MMU_EXCEPTION;
+				}
+				#endif
+				fault = interpreter_read_memory(addr, phys_addr, ret, 32);
+				if (fault) {
+					goto MMU_EXCEPTION;
+				}
+				cpu->Reg[15] = ret;
+				#if 0
+				addr += 4;
+				phys_addr += 4;
+				#endif
+ 			}
+			if (BIT(inst, 15)) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SXTH_INST:
+	{
+		INC_ICOUNTER;
+		sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+			if (BIT(operand2, 15)) {
+				operand2 |= 0xffff0000;
+			} else {
+				operand2 &= 0xffff;
+			}
+			RD = operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(sxth_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDR_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		//if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			//bus_read(32, addr, &value);
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+				cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			else {
+				value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
+				cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			}
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				/* For armv5t, should enter thumb when bits[0] is non-zero. */
+				cpu->TFlag = value & 0x1;
+				cpu->Reg[15] &= 0xFFFFFFFE;
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		//}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRCOND_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if (CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			//bus_read(32, addr, &value);
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+				cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			else {
+                                value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
+                                cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+                        }
+
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				/* For armv5t, should enter thumb when bits[0] is non-zero. */
+				cpu->TFlag = value & 0x1;
+				cpu->Reg[15] &= 0xFFFFFFFE;
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UXTH_INST:
+	{
+		INC_ICOUNTER;
+		uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 
+						& 0xffff;
+			RD = operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(uxth_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UXTAH_INST:
+	{
+		INC_ICOUNTER;
+		uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 
+						& 0xffff;
+			RD = RN + operand2;
+			if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
+				DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
+				CITRA_IGNORE_EXIT(-1);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(uxtah_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRB_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+			//bus_read(8, addr, &value);
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRBT_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRD_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			/* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			uint32_t rear_phys_addr;
+			 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
+			if(fault){
+				ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
+				CITRA_IGNORE_EXIT(-1);
+				goto MMU_EXCEPTION;
+			}
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
+			/* No dispatch since this operation should not modify R15 */
+		}
+		cpu->Reg[15] += 4;
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+
+	LDREX_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+			fault = check_address_validity(cpu, addr, &phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+
+			add_exclusive_addr(cpu, phys_addr);
+			cpu->exclusive_state = 1;
+
+			//bus_read(32, addr, &value);
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDREXB_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+			fault = check_address_validity(cpu, addr, &phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+			
+			add_exclusive_addr(cpu, phys_addr);
+			cpu->exclusive_state = 1;
+
+			//bus_read(8, addr, &value);
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRH_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = 0;
+			fault = interpreter_read_memory(addr, phys_addr, value, 16);
+//			fault = interpreter_read_memory(addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			//if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) {
+			//	value = 0xffffffff;
+			//}
+			//bus_read(16, addr, &value);
+//			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff;
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRSB_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+//			DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr);
+			fault = interpreter_read_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+			//bus_read(8, addr, &value);
+			if (BIT(value, 7)) {
+				value |= 0xffffff00;
+			}
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRSH_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 16);
+			if (fault) goto MMU_EXCEPTION;
+			//bus_read(16, addr, &value);
+			if (BIT(value, 15)) {
+				value |= 0xffff0000;
+			}
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	LDRT_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+
+			if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
+				cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+			else
+				cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
+
+			if (BITS(inst_cream->inst, 12, 15) == 15) {
+				INC_PC(sizeof(ldst_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MCR_INST:
+	{
+		INC_ICOUNTER;
+		/* NOT IMPL */
+		mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int inst = inst_cream->inst;
+			if (inst_cream->Rd == 15) {
+				DEBUG_MSG;
+			} else {
+				if (inst_cream->cp_num == 15) {
+					if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
+						//LET(RD, CONST(0x0007b000));
+						//LET(RD, CONST(0x410FB760));
+						//LET(CP15_MAIN_ID, R(RD));
+						CP15_REG(CP15_MAIN_ID) = RD;
+					} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
+						//LET(RD, R(CP15_CONTROL));
+						CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
+					} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
+						//LET(RD, R(CP15_CONTROL));
+						CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
+					} else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(CP15_CONTROL, R(RD));
+						CP15_REG(CP15_CONTROL) = RD;
+					} else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD));
+						CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
+					} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD));
+						CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
+					} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
+						//LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD));
+						CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
+					} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
+						//LET(CP15_TRANSLATION_BASE_CONTROL, R(RD));
+						CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
+					} else if(CRn == MMU_CACHE_OPS){
+						//SKYEYE_WARNING("cache operation have not implemented.\n");
+					} else if(CRn == MMU_TLB_OPS){
+						switch (CRm) {
+						case 5: /* ITLB */
+							switch(OPCODE_2){
+							case 0: /* invalidate all */
+								//invalidate_all_tlb(state);
+								DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n");
+								//remove_tlb(INSN_TLB);
+								//erase_all(core, INSN_TLB);
+								break;
+							case 1: /* invalidate by MVA */
+								//invalidate_by_mva(state, value);
+								//DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n");
+								//remove_tlb_by_mva(RD, INSN_TLB);
+								//erase_by_mva(core, RD, INSN_TLB);
+								break;
+							case 2: /* invalidate by asid */
+								//invalidate_by_asid(state, value);
+								//DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n");
+								//erase_by_asid(core, RD, INSN_TLB);
+								break;
+							default:
+								break;
+							}
+
+							break;
+						case 6: /* DTLB */
+							switch(OPCODE_2){
+							case 0: /* invalidate all */
+								//invalidate_all_tlb(state);
+								//remove_tlb(DATA_TLB);
+								//erase_all(core, DATA_TLB);
+								DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n");
+								break;
+							case 1: /* invalidate by MVA */
+								//invalidate_by_mva(state, value);
+								//remove_tlb_by_mva(RD, DATA_TLB);
+								//erase_by_mva(core, RD, DATA_TLB);
+								//DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n");
+								break;
+							case 2: /* invalidate by asid */
+								//invalidate_by_asid(state, value);
+								//remove_tlb_by_asid(RD, DATA_TLB);
+								//erase_by_asid(core, RD, DATA_TLB);
+								//DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n");
+								break;
+							default:
+								break;
+							}
+							break;
+						case 7: /* UNIFILED TLB */
+							switch(OPCODE_2){
+							case 0: /* invalidate all */
+								//invalidate_all_tlb(state);
+								//erase_all(core, INSN_TLB);
+								//erase_all(core, DATA_TLB);
+								//remove_tlb(DATA_TLB);
+								//remove_tlb(INSN_TLB);
+								//DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n");
+								break;
+							case 1: /* invalidate by MVA */
+								//invalidate_by_mva(state, value);
+								//erase_by_mva(core, RD, DATA_TLB);
+								//erase_by_mva(core, RD, INSN_TLB);
+								DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n");
+								break;
+							case 2: /* invalidate by asid */
+								//invalidate_by_asid(state, value);
+								//erase_by_asid(core, RD, DATA_TLB);
+								//erase_by_asid(core, RD, INSN_TLB);
+								DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n");
+								break;
+							default:
+								break;
+							}
+							break;
+						default:
+							break;
+						}
+					} else if(CRn == MMU_PID){
+						if(OPCODE_2 == 0)
+							CP15_REG(CP15_PID) = RD;
+						else if(OPCODE_2 == 1)
+							CP15_REG(CP15_CONTEXT_ID) = RD;
+						else if(OPCODE_2 == 3){
+							CP15_REG(CP15_THREAD_URO) = RD;
+						}
+						else{
+							printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn);
+						}
+
+					} else {
+						DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
+					}
+				}
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mcr_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MCRR_INST:
+	MLA_INST:
+	{
+		INC_ICOUNTER;
+		mla_inst *inst_cream = (mla_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			uint64_t rm = RM;
+			uint64_t rs = RS;
+			uint64_t rn = RN;
+			if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
+				DEBUG_LOG(ARM11, "in __line__\n", __LINE__);
+				CITRA_IGNORE_EXIT(-1);
+			}
+//			RD = dst = RM * RS + RN;
+			RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
+			if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(mla_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mla_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MOV_INST:
+	{
+//		DEBUG_LOG(ARM11, "mov inst\n");
+//		DEBUG_LOG(ARM11, "pc:       %x\n", cpu->Reg[15]);
+//		debug_function(cpu);
+//		cpu->icount ++;
+		INC_ICOUNTER;
+		mov_inst *inst_cream = (mov_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			RD = dst = SHIFTER_OPERAND;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(mov_inst));
+				goto PROFILING;
+			}
+//				return;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mov_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MRC_INST:
+	{
+		INC_ICOUNTER;
+		/* NOT IMPL */
+		mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int inst = inst_cream->inst;
+			if (inst_cream->Rd == 15) {
+				DEBUG_MSG;
+			}
+			if (inst_cream->inst == 0xeef04a10) {
+				/* undefined instruction fmrx */
+				RD = 0x20000000;
+				CITRA_IGNORE_EXIT(-1);
+				goto END;
+			} else {
+				if (inst_cream->cp_num == 15) {
+					if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
+						//LET(RD, CONST(0x0007b000));
+						//LET(RD, CONST(0x410FB760));
+						//LET(RD, R(CP15_MAIN_ID));
+						RD = cpu->CP15[CP15(CP15_MAIN_ID)];
+					} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(RD, R(CP15_CONTROL));
+						RD = cpu->CP15[CP15(CP15_CONTROL)];
+					} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
+						//LET(RD, R(CP15_CONTROL));
+						RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
+					} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
+						//LET(RD, R(CP15_CONTROL));
+						RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
+					} else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL));
+						RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
+					} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0));
+						RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
+					} else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(RD, R(CP15_FAULT_STATUS));
+						RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
+					} else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
+						//LET(RD, R(CP15_FAULT_ADDRESS));
+						RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
+					} else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
+						//LET(RD, R(CP15_CACHE_TYPE));
+						RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
+					} else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
+						//LET(RD, R(CP15_INSTR_FAULT_STATUS));
+						RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
+					} else if (CRn == 13) {
+						if(OPCODE_2 == 0)
+							RD = CP15_REG(CP15_PID);
+						else if(OPCODE_2 == 1)
+							RD = CP15_REG(CP15_CONTEXT_ID);
+						else if(OPCODE_2 == 3){
+							RD = Memory::KERNEL_MEMORY_VADDR;
+						}
+						else{
+							printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn);
+						}
+					}
+					else {
+						DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
+					}
+				}
+				//DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mrc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MRRC_INST:
+	MRS_INST:
+	{
+		INC_ICOUNTER;
+		mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			if (inst_cream->R) {
+				RD = cpu->Spsr_copy;
+			} else {
+				SAVE_NZCVT;
+				RD = cpu->Cpsr;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mrs_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MSR_INST:
+	{
+		INC_ICOUNTER;
+		msr_inst *inst_cream = (msr_inst *)inst_base->component;
+		const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
+		unsigned int inst = inst_cream->inst;
+		unsigned int operand;
+
+		if (BIT(inst, 25)) {
+			int rot_imm = BITS(inst, 8, 11) * 2;
+			//operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm));
+			operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
+		} else {
+			//operand = R(RM);
+			operand = cpu->Reg[BITS(inst, 0, 3)];
+		}
+		uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
+					| (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
+		uint32_t mask;
+		if (!inst_cream->R) {
+			if (InAPrivilegedMode(cpu)) {
+				if ((operand & StateMask) != 0) {
+					/* UNPREDICTABLE */
+					DEBUG_MSG;
+				} else
+					mask = byte_mask & (UserMask | PrivMask);
+			} else {
+				mask = byte_mask & UserMask;
+			}
+			//LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
+			SAVE_NZCVT;
+
+			cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
+			switch_mode(cpu, cpu->Cpsr & 0x1f);
+			LOAD_NZCVT;
+		} else {
+			if (CurrentModeHasSPSR) {
+				mask = byte_mask & (UserMask | PrivMask | StateMask);
+				//LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
+				cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(msr_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MUL_INST:
+	{
+		INC_ICOUNTER;
+		mul_inst *inst_cream = (mul_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+//			RD = dst = SHIFTER_OPERAND;
+			uint64_t rm = RM;
+			uint64_t rs = RS;
+			RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
+			if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(mul_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mul_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	MVN_INST:
+	{
+		INC_ICOUNTER;
+		mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+//			RD = dst = (SHIFTER_OPERAND ^ 0xffffffff);
+			RD = dst = ~SHIFTER_OPERAND;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(mvn_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(mvn_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	ORR_INST:
+	{
+		INC_ICOUNTER;
+		orr_inst *inst_cream = (orr_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			rop = SHIFTER_OPERAND;
+//			DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]);
+			RD = dst = lop | rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr*/
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_WITH_SC;
+//				UPDATE_CFLAG(dst, lop, rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(orr_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(orr_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	PKHBT_INST:
+	PKHTB_INST:
+	PLD_INST:
+	{
+		INC_ICOUNTER;
+		/* NOT IMPL */
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(stc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	QADD_INST:
+	QADD16_INST:
+	QADD8_INST:
+	QADDSUBX_INST:
+	QDADD_INST:
+	QDSUB_INST:
+	QSUB_INST:
+	QSUB16_INST:
+	QSUB8_INST:
+	QSUBADDX_INST:
+	REV_INST:
+	{
+		INC_ICOUNTER;
+		rev_inst *inst_cream = (rev_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			RD = ((RM & 0xff) << 24) |
+				(((RM >> 8) & 0xff) << 16) |
+				(((RM >> 16) & 0xff) << 8) |
+				((RM >> 24) & 0xff);
+			if (inst_cream->Rm == 15) {
+				DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
+				CITRA_IGNORE_EXIT(-1);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(rev_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	REV16_INST:
+	{
+		INC_ICOUNTER;
+		rev_inst *inst_cream = (rev_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			RD = (BITS(RM, 0, 7) << 8) | 
+				BITS(RM, 8, 15) |
+				(BITS(RM, 16, 23) << 24) |
+				(BITS(RM, 24, 31) << 16);
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(rev_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	REVSH_INST:
+	RFE_INST:
+	RSB_INST:
+	{
+		INC_ICOUNTER;
+		rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			rop = RN;
+			lop = SHIFTER_OPERAND;
+			if (inst_cream->Rn == 15) {
+				rop += 2 * GET_INST_SIZE(cpu);;
+			}
+			RD = dst = lop - rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+				UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+//				UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+				UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(rsb_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(rsb_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	RSC_INST:
+	{
+		INC_ICOUNTER;
+		rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			//lop = RN + !cpu->CFlag;
+			//rop = SHIFTER_OPERAND;
+			//RD = dst = rop - lop;
+			lop = RN;
+			rop = SHIFTER_OPERAND;
+			RD = dst = rop - lop - !cpu->CFlag;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+//				UPDATE_CFLAG(dst, lop, rop);
+//				UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
+				UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
+//				cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
+				UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(rsc_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(rsc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SADD16_INST:
+	SADD8_INST:
+	SADDSUBX_INST:
+	SBC_INST:
+	{
+		INC_ICOUNTER;
+		sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = SHIFTER_OPERAND + !cpu->CFlag;
+			rop = RN;
+			RD = dst = rop - lop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+//				UPDATE_CFLAG(dst, lop, rop);
+				//UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
+				//rop = rop - !cpu->CFlag;
+				if(rop >= !cpu->CFlag)
+					UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
+				else
+					UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
+//				cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
+				UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(sbc_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(sbc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SEL_INST:
+	SETEND_INST:
+	SHADD16_INST:
+	SHADD8_INST:
+	SHADDSUBX_INST:
+	SHSUB16_INST:
+	SHSUB8_INST:
+	SHSUBADDX_INST:
+	SMLA_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			smla_inst *inst_cream = (smla_inst *)inst_base->component;
+			int32_t operand1, operand2;
+			if (inst_cream->x == 0)
+				operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+			else
+				operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+
+			if (inst_cream->y == 0)
+				operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+			else
+				operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+			RD = operand1 * operand2 + RN;
+			//FIXME: UPDATE Q FLAGS
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(smla_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SMLAD_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+			long long int rm = cpu->Reg[inst_cream->Rm];
+			long long int rn = cpu->Reg[inst_cream->Rn];
+			long long int ra = cpu->Reg[inst_cream->Ra];
+			/* see SMUAD */
+			if(inst_cream->Ra == 15)
+				CITRA_IGNORE_EXIT(-1);
+			int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
+			
+			int half_rn, half_operand2;
+			half_rn = rn & 0xFFFF;
+			half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+
+			half_operand2 = operand2 & 0xFFFF;
+			half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+		
+			long long int product1 = half_rn * half_operand2;
+
+			half_rn = (rn & 0xFFFF0000) >> 16;
+			half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+
+			half_operand2 = (operand2 & 0xFFFF0000) >> 16;
+			half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+		
+			long long int product2 = half_rn * half_operand2;
+
+			long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
+			long long int result = product1 + product2 + signed_ra;
+			cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
+			/* FIXME , should check Signed overflow */
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(umlal_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+
+	SMLAL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+			long long int rm = RM;
+			long long int rs = RS;
+			if (BIT(rm, 31)) {
+				rm |= 0xffffffff00000000LL;
+			}
+			if (BIT(rs, 31)) {
+				rs |= 0xffffffff00000000LL;
+			}
+			long long int rst = rm * rs;
+			long long int rdhi32 = RDHI;
+			long long int hilo = (rdhi32 << 32) + RDLO;
+			rst += hilo;
+			RDLO = BITS(rst,  0, 31);
+			RDHI = BITS(rst, 32, 63);
+			if (inst_cream->S) {
+				cpu->NFlag = BIT(RDHI, 31);
+				cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(umlal_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SMLALXY_INST:
+	SMLALD_INST:
+	SMLAW_INST:
+	SMLSD_INST:
+	SMLSLD_INST:
+	SMMLA_INST:
+	SMMLS_INST:
+	SMMUL_INST:
+	SMUAD_INST:
+	SMUL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			smul_inst *inst_cream = (smul_inst *)inst_base->component;
+			uint32_t operand1, operand2;
+			if (inst_cream->x == 0)
+				operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+			else
+				operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+
+			if (inst_cream->y == 0)
+				operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+			else
+				operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+			RD = operand1 * operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(smul_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SMULL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			umull_inst *inst_cream = (umull_inst *)inst_base->component;
+//			DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
+			int64_t rm = RM;
+			int64_t rs = RS;
+			if (BIT(rm, 31)) {
+				rm |= 0xffffffff00000000LL;
+			}
+			if (BIT(rs, 31)) {
+				rs |= 0xffffffff00000000LL;
+			}
+			int64_t rst = rm * rs;
+			RDHI = BITS(rst, 32, 63);
+			RDLO = BITS(rst,  0, 31);
+
+
+			if (inst_cream->S) {
+				cpu->NFlag = BIT(RDHI, 31);
+				cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(umull_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SMULW_INST:
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+//			DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
+			int64_t rm = RM;
+			int64_t rn = RN;
+			if (inst_cream->m)
+				rm = BITS(rm,16 , 31);
+			else
+				rm = BITS(rm,0 , 15);
+			int64_t rst = rm * rn;
+			RD = BITS(rst,  16, 47);
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(smlad_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+
+	SMUSD_INST:
+	SRS_INST:
+	SSAT_INST:
+	SSAT16_INST:
+	SSUB16_INST:
+	SSUB8_INST:
+	SSUBADDX_INST:
+	STC_INST:
+	{
+		INC_ICOUNTER;
+		/* NOT IMPL */
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(stc_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STM_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		unsigned int inst = inst_cream->inst;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			int i;
+			unsigned int Rn = BITS(inst, 16, 19);
+			unsigned int old_RN = cpu->Reg[Rn];
+
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			if (BIT(inst_cream->inst, 22) == 1) {
+//				DEBUG_MSG;
+				#if 1
+				for (i = 0; i < 13; i++) {
+					if(BIT(inst_cream->inst, i)){
+						fault = check_address_validity(cpu, addr, &phys_addr, 0);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+					}
+				}
+				if (BIT(inst_cream->inst, 13)) {
+					if (cpu->Mode == USER32MODE) {
+						fault = check_address_validity(cpu, addr, &phys_addr, 0);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+					} else {
+						fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+					}
+				}
+				if (BIT(inst_cream->inst, 14)) {
+					if (cpu->Mode == USER32MODE) {
+						fault = check_address_validity(cpu, addr, &phys_addr, 0);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+					} else {
+						fault = check_address_validity(cpu, addr, &phys_addr, 0);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+					}
+				}
+				if (BIT(inst_cream->inst, 15)) {
+					fault = check_address_validity(cpu, addr, &phys_addr, 0);
+					if (fault) {
+						goto MMU_EXCEPTION;
+					}
+					fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
+					if (fault) goto MMU_EXCEPTION;
+				}
+				#endif
+			} else {
+				for( i = 0; i < 15; i ++ ){
+					if(BIT(inst_cream->inst, i)){
+						//arch_write_memory(cpu, bb, Addr, R(i), 32);
+						//bus_write(32, addr, cpu->Reg[i]);
+						fault = check_address_validity(cpu, addr, &phys_addr, 0);
+						if (fault) {
+							goto MMU_EXCEPTION;
+						}
+						if(i == Rn)
+							fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
+						else
+							fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
+						if (fault) goto MMU_EXCEPTION;
+						addr += 4;
+						phys_addr += 4;
+						//Addr = ADD(Addr, CONST(4));
+					}
+				}
+
+				/* check pc reg*/
+				if(BIT(inst_cream->inst, i)){
+					//arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32);
+					//bus_write(32, addr, cpu->Reg[i] + 8);
+					fault = check_address_validity(cpu, addr, &phys_addr, 0);
+					if (fault) {
+						goto MMU_EXCEPTION;
+					}
+					fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
+					if (fault) goto MMU_EXCEPTION;
+				}
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SXTB_INST:
+	{
+		INC_ICOUNTER;
+		sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			if (inst_cream->Rm == 15) {
+				DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
+				CITRA_IGNORE_EXIT(-1);
+			}
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+			if (BIT(operand2, 7)) {
+				operand2 |= 0xffffff00;
+			} else
+				operand2 &= 0xff;
+			RD = operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(sxtb_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STR_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+			//bus_write(32, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UXTB_INST:
+	{
+		INC_ICOUNTER;
+		uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 
+						& 0xff;
+			RD = operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(uxtb_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UXTAB_INST:
+	{
+		INC_ICOUNTER;
+		uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 
+						& 0xff;
+			RD = RN + operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(uxtab_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STRB_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+			//bus_write(8, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STRBT_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+			//bus_write(8, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		//if (BITS(inst_cream->inst, 12, 15) == 15)
+		//	goto PROFILING;
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STRD_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			uint32_t rear_phys_addr;
+			fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
+                        if (fault){
+				ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
+				CITRA_IGNORE_EXIT(-1);
+				goto MMU_EXCEPTION;
+			}
+
+			//fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0);
+			//if (fault) goto MMU_EXCEPTION;
+
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+			//bus_write(32, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
+			//bus_write(32, addr, value);
+			fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STREX_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
+			fault = check_address_validity(cpu, addr, &phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+
+			int dest_reg = BITS(inst_cream->inst, 12, 15);
+			if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
+				remove_exclusive(cpu, phys_addr);
+				cpu->Reg[dest_reg] = 0;
+				cpu->exclusive_state = 0;
+				
+				//			bus_write(32, addr, value);
+				fault = interpreter_write_memory(addr, phys_addr, value, 32);
+				if (fault) goto MMU_EXCEPTION;
+			}
+			else{
+				/* Failed to write due to mutex access */
+				cpu->Reg[dest_reg] = 1;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STREXB_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
+			fault = check_address_validity(cpu, addr, &phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			//bus_write(8, addr, value);
+			int dest_reg = BITS(inst_cream->inst, 12, 15);
+			if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
+				remove_exclusive(cpu, phys_addr);
+				cpu->Reg[dest_reg] = 0;
+				cpu->exclusive_state = 0;
+				fault = interpreter_write_memory(addr, phys_addr, value, 8);
+				if (fault) goto MMU_EXCEPTION;
+
+			}
+			else{
+				cpu->Reg[dest_reg] = 1;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STRH_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
+			//bus_write(16, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 16);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		//if (BITS(inst_cream->inst, 12, 15) == 15)
+		//	goto PROFILING;
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	STRT_INST:
+	{
+		INC_ICOUNTER;
+		ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
+			//bus_write(16, addr, value);
+			fault = interpreter_write_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(ldst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SUB_INST:
+	{
+		INC_ICOUNTER;
+		sub_inst *inst_cream = (sub_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			lop = RN;
+			if (inst_cream->Rn == 15) {
+				lop += 8;
+			}
+			rop = SHIFTER_OPERAND;
+			RD = dst = lop - rop;
+			if (inst_cream->S && (inst_cream->Rd == 15)) {
+				/* cpsr = spsr */
+				if (CurrentModeHasSPSR) {
+					cpu->Cpsr = cpu->Spsr_copy;
+					switch_mode(cpu, cpu->Spsr_copy & 0x1f);
+					LOAD_NZCVT;
+				}
+			} else if (inst_cream->S) {
+				UPDATE_NFLAG(dst);
+				UPDATE_ZFLAG(dst);
+//				UPDATE_CFLAG(dst, lop, rop);
+				UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
+	//			UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
+				UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
+			}
+			if (inst_cream->Rd == 15) {
+				INC_PC(sizeof(sub_inst));
+				goto PROFILING;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(sub_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SWI_INST:
+	{
+		INC_ICOUNTER;
+		swi_inst *inst_cream = (swi_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode
+				//arm_dyncom_SWI(cpu, inst_cream->num);
+				HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
+			} else {
+				cpu->syscallSig = 1;
+				goto END;
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(swi_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SWP_INST:
+	{
+		INC_ICOUNTER;
+		swp_inst *inst_cream = (swp_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = RN;
+			fault = check_address_validity(cpu, addr, &phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 32);
+			if (fault) goto MMU_EXCEPTION;
+			fault = interpreter_write_memory(addr, phys_addr, RM, 32);
+			if (fault) goto MMU_EXCEPTION;
+
+			/* ROR(data, 8*UInt(address<1:0>)); */
+			assert((phys_addr & 0x3) == 0);
+			RD = value;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(swp_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SWPB_INST:
+	{
+		INC_ICOUNTER;
+		swp_inst *inst_cream = (swp_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			addr = RN;
+			fault = check_address_validity(cpu, addr, &phys_addr, 1);
+			if (fault) goto MMU_EXCEPTION;
+			unsigned int value;
+			fault = interpreter_read_memory(addr, phys_addr, value, 8);
+			if (fault) goto MMU_EXCEPTION;
+			fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
+			if (fault) goto MMU_EXCEPTION;
+
+			/* FIXME */
+			#if 0
+			if Shared(address) then
+			/* ARMv6 */
+			physical_address = TLB(address)
+			ClearExclusiveByAddress(physical_address,processor_id,1)
+			/* See Summary of operation on page A2-49 */
+			#endif
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(swp_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SXTAB_INST:
+	{
+		INC_ICOUNTER;
+		sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			/* R15 should be check */
+			if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
+				CITRA_IGNORE_EXIT(-1);
+			}
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) 
+						& 0xff;
+			/* sign extend for byte */
+			operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
+			RD = RN + operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(uxtab_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SXTAB16_INST:
+	SXTAH_INST:
+	{
+		INC_ICOUNTER;
+		sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			/* R15 should be check */
+			if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
+				CITRA_IGNORE_EXIT(-1);
+			}
+			unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
+			/* sign extend for half */
+			operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2;
+			RD = RN + operand2;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(sxtah_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	SXTB16_INST:
+	TEQ_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			teq_inst *inst_cream = (teq_inst *)inst_base->component;
+			lop = RN;
+			if (inst_cream->Rn == 15)
+				lop += GET_INST_SIZE(cpu) * 2;
+
+			rop = SHIFTER_OPERAND;
+			dst = lop ^ rop;
+
+			UPDATE_NFLAG(dst);
+			UPDATE_ZFLAG(dst);
+			UPDATE_CFLAG_WITH_SC;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(teq_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	TST_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			tst_inst *inst_cream = (tst_inst *)inst_base->component;
+			lop = RN;
+			if (inst_cream->Rn == 15)
+				lop += GET_INST_SIZE(cpu) * 2;
+			rop = SHIFTER_OPERAND;
+			dst = lop & rop;
+
+			UPDATE_NFLAG(dst);
+			UPDATE_ZFLAG(dst);
+			UPDATE_CFLAG_WITH_SC;
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(tst_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UADD16_INST:
+	UADD8_INST:
+	UADDSUBX_INST:
+	UHADD16_INST:
+	UHADD8_INST:
+	UHADDSUBX_INST:
+	UHSUB16_INST:
+	UHSUB8_INST:
+	UHSUBADDX_INST:
+	UMAAL_INST:
+	UMLAL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+			unsigned long long int rm = RM;
+			unsigned long long int rs = RS;
+			unsigned long long int rst = rm * rs;
+			unsigned long long int add = ((unsigned long long) RDHI)<<32;
+			add += RDLO;
+			//DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add);
+			rst += add;
+			RDLO = BITS(rst,  0, 31);
+			RDHI = BITS(rst, 32, 63);
+			
+			if (inst_cream->S)
+			{
+				cpu->NFlag = BIT(RDHI, 31);
+				cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(umlal_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	UMULL_INST:
+	{
+		INC_ICOUNTER;
+		if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+			umull_inst *inst_cream = (umull_inst *)inst_base->component;
+			unsigned long long int rm = RM;
+			unsigned long long int rs = RS;
+			unsigned long long int rst = rm * rs;
+//			DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
+			RDHI = BITS(rst, 32, 63);
+			RDLO = BITS(rst,  0, 31);
+
+			if (inst_cream->S) {
+				cpu->NFlag = BIT(RDHI, 31);
+				cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+			}
+		}
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(umull_inst));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+	}
+	B_2_THUMB:
+	{
+		INC_ICOUNTER;
+		b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+		cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+		//DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
+		INC_PC(sizeof(b_2_thumb));
+		goto PROFILING;
+	}
+	B_COND_THUMB:
+	{
+		INC_ICOUNTER;
+		b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+		if(CondPassed(cpu, inst_cream->cond))
+			cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+		else
+			cpu->Reg[15] += 2;
+		//DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]);
+		INC_PC(sizeof(b_cond_thumb));
+		goto PROFILING;
+	}
+	BL_1_THUMB:
+	{
+		INC_ICOUNTER;
+		bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
+		cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
+		//cpu->Reg[15] += 2;
+		//DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
+
+		cpu->Reg[15] += GET_INST_SIZE(cpu);
+		INC_PC(sizeof(bl_1_thumb));
+		FETCH_INST;
+		GOTO_NEXT_INST;
+
+	}
+	BL_2_THUMB:
+	{
+		INC_ICOUNTER;
+		bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+		int tmp = ((cpu->Reg[15] + 2) | 1);
+		cpu->Reg[15] =
+			(cpu->Reg[14] + inst_cream->imm);
+		cpu->Reg[14] = tmp;
+		//DEBUG_LOG(ARM11, " BL_2_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
+		INC_PC(sizeof(bl_2_thumb));
+		goto PROFILING;
+	}
+	BLX_1_THUMB:
+	{	
+		/* BLX 1 for armv5t and above */
+		INC_ICOUNTER;
+		uint32 tmp = cpu->Reg[15];
+		blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
+		cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
+		//DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, instr=0x%x\n", inst_cream->imm, cpu->Reg[14], inst_cream->instr);
+		cpu->Reg[14] = ((tmp + 2) | 1);
+		//(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
+		/* switch to arm state from thumb state */
+		cpu->TFlag = 0;
+		//DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, r15=0x%x, \n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
+		INC_PC(sizeof(blx_1_thumb));
+		goto PROFILING;
+	}
+
+	UQADD16_INST:
+	UQADD8_INST:
+	UQADDSUBX_INST:
+	UQSUB16_INST:
+	UQSUB8_INST:
+	UQSUBADDX_INST:
+	USAD8_INST:
+	USADA8_INST:
+	USAT_INST:
+	USAT16_INST:
+	USUB16_INST:
+	USUB8_INST:
+	USUBADDX_INST:
+	UXTAB16_INST:
+	UXTB16_INST:
+	#define VFP_INTERPRETER_IMPL
+	#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+	#undef VFP_INTERPRETER_IMPL
+	MMU_EXCEPTION:
+	{
+		SAVE_NZCVT;
+		cpu->abortSig = true;
+		cpu->Aborted = ARMul_DataAbortV;
+		cpu->AbortAddr = addr;
+		cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
+		cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
+		return;
+	}
+	END:
+	{
+		SAVE_NZCVT;
+		return;
+	}
+	INIT_INST_LENGTH:
+	{
+#if 0
+	DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
+	for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
+		DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
+	DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
+#endif
+#ifdef __GNUC__
+	InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
+#endif
+#if 0
+	for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
+		DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
+	DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
+	DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
+	DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
+#endif
+	return;
+	}
+}
+
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
new file mode 100644
index 000000000..d73f8f65f
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h
@@ -0,0 +1,7 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+void InterpreterMainLoop(ARMul_State* state);
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp
new file mode 100644
index 000000000..a2026cbf3
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_run.cpp
@@ -0,0 +1,120 @@
+/* Copyright (C)
+* 2011 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+/**
+* @file arm_dyncom_run.cpp
+* @brief The dyncom run implementation for arm
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 78.77
+* @date 2011-11-20
+*/
+
+#include <assert.h>
+
+#include "core/arm/skyeye_common/armdefs.h"
+
+void switch_mode(arm_core_t *core, uint32_t mode)
+{
+    uint32_t tmp1, tmp2;
+    if (core->Mode == mode) {
+        //Mode not changed.
+        //printf("mode not changed\n");
+        return;
+    }
+    //printf("%d --->>> %d\n", core->Mode, mode);
+    //printf("In %s, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
+    if (mode != USERBANK) {
+        switch (core->Mode) {
+        case USER32MODE:
+            core->Reg_usr[0] = core->Reg[13];
+            core->Reg_usr[1] = core->Reg[14];
+            break;
+        case IRQ32MODE:
+            core->Reg_irq[0] = core->Reg[13];
+            core->Reg_irq[1] = core->Reg[14];
+            core->Spsr[IRQBANK] = core->Spsr_copy;
+            break;
+        case SVC32MODE:
+            core->Reg_svc[0] = core->Reg[13];
+            core->Reg_svc[1] = core->Reg[14];
+            core->Spsr[SVCBANK] = core->Spsr_copy;
+            break;
+        case ABORT32MODE:
+            core->Reg_abort[0] = core->Reg[13];
+            core->Reg_abort[1] = core->Reg[14];
+            core->Spsr[ABORTBANK] = core->Spsr_copy;
+            break;
+        case UNDEF32MODE:
+            core->Reg_undef[0] = core->Reg[13];
+            core->Reg_undef[1] = core->Reg[14];
+            core->Spsr[UNDEFBANK] = core->Spsr_copy;
+            break;
+        case FIQ32MODE:
+            core->Reg_firq[0] = core->Reg[13];
+            core->Reg_firq[1] = core->Reg[14];
+            core->Spsr[FIQBANK] = core->Spsr_copy;
+            break;
+
+        }
+
+        switch (mode) {
+        case USER32MODE:
+            core->Reg[13] = core->Reg_usr[0];
+            core->Reg[14] = core->Reg_usr[1];
+            core->Bank = USERBANK;
+            break;
+        case IRQ32MODE:
+            core->Reg[13] = core->Reg_irq[0];
+            core->Reg[14] = core->Reg_irq[1];
+            core->Spsr_copy = core->Spsr[IRQBANK];
+            core->Bank = IRQBANK;
+            break;
+        case SVC32MODE:
+            core->Reg[13] = core->Reg_svc[0];
+            core->Reg[14] = core->Reg_svc[1];
+            core->Spsr_copy = core->Spsr[SVCBANK];
+            core->Bank = SVCBANK;
+            break;
+        case ABORT32MODE:
+            core->Reg[13] = core->Reg_abort[0];
+            core->Reg[14] = core->Reg_abort[1];
+            core->Spsr_copy = core->Spsr[ABORTBANK];
+            core->Bank = ABORTBANK;
+            break;
+        case UNDEF32MODE:
+            core->Reg[13] = core->Reg_undef[0];
+            core->Reg[14] = core->Reg_undef[1];
+            core->Spsr_copy = core->Spsr[UNDEFBANK];
+            core->Bank = UNDEFBANK;
+            break;
+        case FIQ32MODE:
+            core->Reg[13] = core->Reg_firq[0];
+            core->Reg[14] = core->Reg_firq[1];
+            core->Spsr_copy = core->Spsr[FIQBANK];
+            core->Bank = FIQBANK;
+            break;
+
+        }
+        core->Mode = mode;
+        //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
+        //printf("\n--------------------------------------\n");
+    }
+    else {
+        printf("user mode\n");
+        exit(-2);
+    }
+}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
new file mode 100644
index 000000000..aeabeac16
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -0,0 +1,55 @@
+/* Copyright (C)
+* 2011 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#ifndef __ARM_DYNCOM_RUN__
+#define __ARM_DYNCOM_RUN__
+
+#include "core/arm/skyeye_common/skyeye_types.h"
+
+void switch_mode(arm_core_t *core, uint32_t mode);
+
+/* FIXME, we temporarily think thumb instruction is always 16 bit */
+static inline uint32 GET_INST_SIZE(arm_core_t* core){
+	return core->TFlag? 2 : 4;
+}
+
+/**
+* @brief Read R15 and forced R15 to wold align, used address calculation
+*
+* @param core
+* @param Rn
+*
+* @return 
+*/
+static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
+	return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+}
+
+/**
+* @brief Read R15, used to data processing with pc
+*
+* @param core
+* @param Rn
+*
+* @return 
+*/
+static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){
+	return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+}
+
+#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
new file mode 100644
index 000000000..e10f2f9ee
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -0,0 +1,521 @@
+/* Copyright (C) 
+* 2011 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+*/
+/**
+* @file arm_dyncom_thumb.c
+* @brief The thumb dynamic interpreter
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 78.77
+* @date 2011-11-07
+*/
+
+/* We can provide simple Thumb simulation by decoding the Thumb
+instruction into its corresponding ARM instruction, and using the
+existing ARM simulator.  */
+
+#include "core/arm/skyeye_common/skyeye_defs.h"
+
+#ifndef MODET			/* required for the Thumb instruction support */
+#if 1
+#error "MODET needs to be defined for the Thumb world to work"
+#else
+#define MODET (1)
+#endif
+#endif
+
+#include "core/arm/skyeye_common/armos.h"
+#include "core/arm/dyncom/arm_dyncom_thumb.h"
+
+/* Decode a 16bit Thumb instruction.  The instruction is in the low
+   16-bits of the tinstr field, with the following Thumb instruction
+   held in the high 16-bits.  Passing in two Thumb instructions allows
+   easier simulation of the special dual BL instruction.  */
+
+tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size)
+{
+    tdstate valid = t_uninitialized;
+	ARMword next_instr;
+	ARMword tinstr;
+	tinstr = instr;
+	/* The endian should be judge here */
+	#if 0
+	if (state->bigendSig) {
+		next_instr = tinstr & 0xFFFF;
+		tinstr >>= 16;
+	}
+	else {
+		next_instr = tinstr >> 16;
+		tinstr &= 0xFFFF;
+	}
+	#endif
+	if((addr & 0x3) != 0)
+		tinstr = instr >> 16;
+	else
+		tinstr &= 0xFFFF;
+
+	//printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc);
+#if 1				/* debugging to catch non updates */
+	*ainstr = 0xDEADC0DE;
+#endif
+
+	switch ((tinstr & 0xF800) >> 11) {
+	case 0:		/* LSL */
+	case 1:		/* LSR */
+	case 2:		/* ASR */
+		/* Format 1 */
+		*ainstr = 0xE1B00000	/* base opcode */
+			| ((tinstr & 0x1800) >> (11 - 5))	/* shift type */
+			|((tinstr & 0x07C0) << (7 - 6))	/* imm5 */
+			|((tinstr & 0x0038) >> 3)	/* Rs */
+			|((tinstr & 0x0007) << 12);	/* Rd */
+		break;
+	case 3:		/* ADD/SUB */
+		/* Format 2 */
+		{
+			ARMword subset[4] = {
+				0xE0900000,	/* ADDS Rd,Rs,Rn    */
+				0xE0500000,	/* SUBS Rd,Rs,Rn    */
+				0xE2900000,	/* ADDS Rd,Rs,#imm3 */
+				0xE2500000	/* SUBS Rd,Rs,#imm3 */
+			};
+			/* It is quicker indexing into a table, than performing switch
+			   or conditionals: */
+			*ainstr = subset[(tinstr & 0x0600) >> 9]	/* base opcode */
+				|((tinstr & 0x01C0) >> 6)	/* Rn or imm3 */
+				|((tinstr & 0x0038) << (16 - 3))	/* Rs */
+				|((tinstr & 0x0007) << (12 - 0));	/* Rd */
+		}
+		break;
+	case 4:		/* MOV */
+	case 5:		/* CMP */
+	case 6:		/* ADD */
+	case 7:		/* SUB */
+		/* Format 3 */
+		{
+			ARMword subset[4] = {
+				0xE3B00000,	/* MOVS Rd,#imm8    */
+				0xE3500000,	/* CMP  Rd,#imm8    */
+				0xE2900000,	/* ADDS Rd,Rd,#imm8 */
+				0xE2500000,	/* SUBS Rd,Rd,#imm8 */
+			};
+			*ainstr = subset[(tinstr & 0x1800) >> 11]	/* base opcode */
+				|((tinstr & 0x00FF) >> 0)	/* imm8 */
+				|((tinstr & 0x0700) << (16 - 8))	/* Rn */
+				|((tinstr & 0x0700) << (12 - 8));	/* Rd */
+		}
+		break;
+	case 8:		/* Arithmetic and high register transfers */
+		/* TODO: Since the subsets for both Format 4 and Format 5
+		   instructions are made up of different ARM encodings, we could
+		   save the following conditional, and just have one large
+		   subset. */
+		if ((tinstr & (1 << 10)) == 0) {
+			typedef enum
+			{ t_norm, t_shift, t_neg, t_mul }otype_t;
+
+			/* Format 4 */
+			struct
+			{
+				ARMword opcode;
+				otype_t otype;
+			}
+			subset[16] = {
+				{
+				0xE0100000, t_norm},	/* ANDS Rd,Rd,Rs     */
+				{
+				0xE0300000, t_norm},	/* EORS Rd,Rd,Rs     */
+				{
+				0xE1B00010, t_shift},	/* MOVS Rd,Rd,LSL Rs */
+				{
+				0xE1B00030, t_shift},	/* MOVS Rd,Rd,LSR Rs */
+				{
+				0xE1B00050, t_shift},	/* MOVS Rd,Rd,ASR Rs */
+				{
+				0xE0B00000, t_norm},	/* ADCS Rd,Rd,Rs     */
+				{
+				0xE0D00000, t_norm},	/* SBCS Rd,Rd,Rs     */
+				{
+				0xE1B00070, t_shift},	/* MOVS Rd,Rd,ROR Rs */
+				{
+				0xE1100000, t_norm},	/* TST  Rd,Rs        */
+				{
+				0xE2700000, t_neg},	/* RSBS Rd,Rs,#0     */
+				{
+				0xE1500000, t_norm},	/* CMP  Rd,Rs        */
+				{
+				0xE1700000, t_norm},	/* CMN  Rd,Rs        */
+				{
+				0xE1900000, t_norm},	/* ORRS Rd,Rd,Rs     */
+				{
+				0xE0100090, t_mul},	/* MULS Rd,Rd,Rs     */
+				{
+				0xE1D00000, t_norm},	/* BICS Rd,Rd,Rs     */
+				{
+				0xE1F00000, t_norm}	/* MVNS Rd,Rs        */
+			};
+			*ainstr = subset[(tinstr & 0x03C0) >> 6].opcode;	/* base */
+			switch (subset[(tinstr & 0x03C0) >> 6].otype) {
+			case t_norm:
+				*ainstr |= ((tinstr & 0x0007) << 16)	/* Rn */
+					|((tinstr & 0x0007) << 12)	/* Rd */
+					|((tinstr & 0x0038) >> 3);	/* Rs */
+				break;
+			case t_shift:
+				*ainstr |= ((tinstr & 0x0007) << 12)	/* Rd */
+					|((tinstr & 0x0007) >> 0)	/* Rm */
+					|((tinstr & 0x0038) << (8 - 3));	/* Rs */
+				break;
+			case t_neg:
+				*ainstr |= ((tinstr & 0x0007) << 12)	/* Rd */
+					|((tinstr & 0x0038) << (16 - 3));	/* Rn */
+				break;
+			case t_mul:
+				*ainstr |= ((tinstr & 0x0007) << 16)	/* Rd */
+					|((tinstr & 0x0007) << 8)	/* Rs */
+					|((tinstr & 0x0038) >> 3);	/* Rm */
+				break;
+			}
+		}
+		else {
+			/* Format 5 */
+			ARMword Rd = ((tinstr & 0x0007) >> 0);
+			ARMword Rs = ((tinstr & 0x0038) >> 3);
+			if (tinstr & (1 << 7))
+				Rd += 8;
+			if (tinstr & (1 << 6))
+				Rs += 8;
+			switch ((tinstr & 0x03C0) >> 6) {
+			case 0x1:	/* ADD Rd,Rd,Hs */
+			case 0x2:	/* ADD Hd,Hd,Rs */
+			case 0x3:	/* ADD Hd,Hd,Hs */
+				*ainstr = 0xE0800000	/* base */
+					| (Rd << 16)	/* Rn */
+					|(Rd << 12)	/* Rd */
+					|(Rs << 0);	/* Rm */
+				break;
+			case 0x5:	/* CMP Rd,Hs */
+			case 0x6:	/* CMP Hd,Rs */
+			case 0x7:	/* CMP Hd,Hs */
+				*ainstr = 0xE1500000	/* base */
+					| (Rd << 16)	/* Rn */
+					|(Rd << 12)	/* Rd */
+					|(Rs << 0);	/* Rm */
+				break;
+			case 0x9:	/* MOV Rd,Hs */
+			case 0xA:	/* MOV Hd,Rs */
+			case 0xB:	/* MOV Hd,Hs */
+				*ainstr = 0xE1A00000	/* base */
+					| (Rd << 16)	/* Rn */
+					|(Rd << 12)	/* Rd */
+					|(Rs << 0);	/* Rm */
+				break;
+			case 0xC:	/* BX Rs */
+			case 0xD:	/* BX Hs */
+				*ainstr = 0xE12FFF10	/* base */
+					| ((tinstr & 0x0078) >> 3);	/* Rd */
+				break;
+			case 0x0:	/* UNDEFINED */
+			case 0x4:	/* UNDEFINED */
+			case 0x8:	/* UNDEFINED */
+				valid = t_undefined;
+				break;
+			case 0xE:	/* BLX */
+			case 0xF:	/* BLX */
+				
+				//if (state->is_v5) {
+				if(1){
+					//valid = t_branch;
+					#if 1
+					*ainstr = 0xE1200030	/* base */
+						|(Rs << 0);	/* Rm */
+					#endif
+				} else {
+					valid = t_undefined;
+				}
+				break;
+			}
+		}
+		break;
+	case 9:		/* LDR Rd,[PC,#imm8] */
+		/* Format 6 */
+		*ainstr = 0xE59F0000	/* base */
+			| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
+			|((tinstr & 0x00FF) << (2 - 0));	/* off8 */
+		break;
+	case 10:
+	case 11:
+		/* TODO: Format 7 and Format 8 perform the same ARM encoding, so
+		   the following could be merged into a single subset, saving on
+		   the following boolean: */
+		if ((tinstr & (1 << 9)) == 0) {
+			/* Format 7 */
+			ARMword subset[4] = {
+				0xE7800000,	/* STR  Rd,[Rb,Ro] */
+				0xE7C00000,	/* STRB Rd,[Rb,Ro] */
+				0xE7900000,	/* LDR  Rd,[Rb,Ro] */
+				0xE7D00000	/* LDRB Rd,[Rb,Ro] */
+			};
+			*ainstr = subset[(tinstr & 0x0C00) >> 10]	/* base */
+				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
+				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
+				|((tinstr & 0x01C0) >> 6);	/* Ro */
+		}
+		else {
+			/* Format 8 */
+			ARMword subset[4] = {
+				0xE18000B0,	/* STRH  Rd,[Rb,Ro] */
+				0xE19000D0,	/* LDRSB Rd,[Rb,Ro] */
+				0xE19000B0,	/* LDRH  Rd,[Rb,Ro] */
+				0xE19000F0	/* LDRSH Rd,[Rb,Ro] */
+			};
+			*ainstr = subset[(tinstr & 0x0C00) >> 10]	/* base */
+				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
+				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
+				|((tinstr & 0x01C0) >> 6);	/* Ro */
+		}
+		break;
+	case 12:		/* STR Rd,[Rb,#imm5] */
+	case 13:		/* LDR Rd,[Rb,#imm5] */
+	case 14:		/* STRB Rd,[Rb,#imm5] */
+	case 15:		/* LDRB Rd,[Rb,#imm5] */
+		/* Format 9 */
+		{
+			ARMword subset[4] = {
+				0xE5800000,	/* STR  Rd,[Rb,#imm5] */
+				0xE5900000,	/* LDR  Rd,[Rb,#imm5] */
+				0xE5C00000,	/* STRB Rd,[Rb,#imm5] */
+				0xE5D00000	/* LDRB Rd,[Rb,#imm5] */
+			};
+			/* The offset range defends on whether we are transferring a
+			   byte or word value: */
+			*ainstr = subset[(tinstr & 0x1800) >> 11]	/* base */
+				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
+				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
+				|((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2)));	/* off5 */
+		}
+		break;
+	case 16:		/* STRH Rd,[Rb,#imm5] */
+	case 17:		/* LDRH Rd,[Rb,#imm5] */
+		/* Format 10 */
+		*ainstr = ((tinstr & (1 << 11))	/* base */
+			   ? 0xE1D000B0	/* LDRH */
+			   : 0xE1C000B0)	/* STRH */
+			|((tinstr & 0x0007) << (12 - 0))	/* Rd */
+			|((tinstr & 0x0038) << (16 - 3))	/* Rb */
+			|((tinstr & 0x01C0) >> (6 - 1))	/* off5, low nibble */
+			|((tinstr & 0x0600) >> (9 - 8));	/* off5, high nibble */
+		break;
+	case 18:		/* STR Rd,[SP,#imm8] */
+	case 19:		/* LDR Rd,[SP,#imm8] */
+		/* Format 11 */
+		*ainstr = ((tinstr & (1 << 11))	/* base */
+			   ? 0xE59D0000	/* LDR */
+			   : 0xE58D0000)	/* STR */
+			|((tinstr & 0x0700) << (12 - 8))	/* Rd */
+			|((tinstr & 0x00FF) << 2);	/* off8 */
+		break;
+	case 20:		/* ADD Rd,PC,#imm8 */
+	case 21:		/* ADD Rd,SP,#imm8 */
+		/* Format 12 */
+		if ((tinstr & (1 << 11)) == 0) {
+			/* NOTE: The PC value used here should by word aligned */
+			/* We encode shift-left-by-2 in the rotate immediate field,
+			   so no shift of off8 is needed.  */
+			*ainstr = 0xE28F0F00	/* base */
+				| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
+				|(tinstr & 0x00FF);	/* off8 */
+		}
+		else {
+			/* We encode shift-left-by-2 in the rotate immediate field,
+			   so no shift of off8 is needed.  */
+			*ainstr = 0xE28D0F00	/* base */
+				| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
+				|(tinstr & 0x00FF);	/* off8 */
+		}
+		break;
+	case 22:
+	case 23:
+		if ((tinstr & 0x0F00) == 0x0000) {
+			/* Format 13 */
+			/* NOTE: The instruction contains a shift left of 2
+			   equivalent (implemented as ROR #30): */
+			*ainstr = ((tinstr & (1 << 7))	/* base */
+				   ? 0xE24DDF00	/* SUB */
+				   : 0xE28DDF00)	/* ADD */
+				|(tinstr & 0x007F);	/* off7 */
+		}
+		else if ((tinstr & 0x0F00) == 0x0e00)
+			*ainstr = 0xEF000000 | SWI_Breakpoint;
+		else {
+			/* Format 14 */
+			ARMword subset[4] = {
+				0xE92D0000,	/* STMDB sp!,{rlist}    */
+				0xE92D4000,	/* STMDB sp!,{rlist,lr} */
+				0xE8BD0000,	/* LDMIA sp!,{rlist}    */
+				0xE8BD8000	/* LDMIA sp!,{rlist,pc} */
+			};
+			*ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)]	/* base */
+				|(tinstr & 0x00FF);	/* mask8 */
+		}
+		break;
+	case 24:		/* STMIA */
+	case 25:		/* LDMIA */
+		/* Format 15 */
+		*ainstr = ((tinstr & (1 << 11))	/* base */
+			   ? 0xE8B00000	/* LDMIA */
+			   : 0xE8A00000)	/* STMIA */
+			|((tinstr & 0x0700) << (16 - 8))	/* Rb */
+			|(tinstr & 0x00FF);	/* mask8 */
+		break;
+	case 26:		/* Bcc */
+	case 27:		/* Bcc/SWI */
+		if ((tinstr & 0x0F00) == 0x0F00) {
+			#if 0
+			if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
+					state->AbortAddr == pc) {
+				*ainstr = ARMul_ABORTWORD;
+				break;
+			}
+			#endif
+			/* Format 17 : SWI */
+			*ainstr = 0xEF000000;
+			/* Breakpoint must be handled specially.  */
+			if ((tinstr & 0x00FF) == 0x18)
+				*ainstr |= ((tinstr & 0x00FF) << 16);
+			/* New breakpoint value.  See gdb/arm-tdep.c  */
+			else if ((tinstr & 0x00FF) == 0xFE)
+				*ainstr |= SWI_Breakpoint;
+			else
+				*ainstr |= (tinstr & 0x00FF);
+		}
+		else if ((tinstr & 0x0F00) != 0x0E00) {
+			/* Format 16 */
+			#if 0
+			int doit = FALSE;
+			/* TODO: Since we are doing a switch here, we could just add
+			   the SWI and undefined instruction checks into this
+			   switch to same on a couple of conditionals: */
+			switch ((tinstr & 0x0F00) >> 8) {
+			case EQ:
+				doit = ZFLAG;
+				break;
+			case NE:
+				doit = !ZFLAG;
+				break;
+			case VS:
+				doit = VFLAG;
+				break;
+			case VC:
+				doit = !VFLAG;
+				break;
+			case MI:
+				doit = NFLAG;
+				break;
+			case PL:
+				doit = !NFLAG;
+				break;
+			case CS:
+				doit = CFLAG;
+				break;
+			case CC:
+				doit = !CFLAG;
+				break;
+			case HI:
+				doit = (CFLAG && !ZFLAG);
+				break;
+			case LS:
+				doit = (!CFLAG || ZFLAG);
+				break;
+			case GE:
+				doit = ((!NFLAG && !VFLAG)
+					|| (NFLAG && VFLAG));
+				break;
+			case LT:
+				doit = ((NFLAG && !VFLAG)
+					|| (!NFLAG && VFLAG));
+				break;
+			case GT:
+				doit = ((!NFLAG && !VFLAG && !ZFLAG)
+					|| (NFLAG && VFLAG && !ZFLAG));
+				break;
+			case LE:
+				doit = ((NFLAG && !VFLAG)
+					|| (!NFLAG && VFLAG)) || ZFLAG;
+				break;
+			}
+			if (doit) {
+				state->Reg[15] = (pc + 4
+						  + (((tinstr & 0x7F) << 1)
+						     | ((tinstr & (1 << 7)) ?
+							0xFFFFFF00 : 0)));
+				FLUSHPIPE;
+			}
+			#endif
+			valid = t_branch;
+		}
+		else		/* UNDEFINED : cc=1110(AL) uses different format */
+			valid = t_undefined;
+		break;
+	case 28:		/* B */
+		/* Format 18 */
+		#if 0
+		state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
+					    | ((tinstr & (1 << 10)) ?
+					       0xFFFFF800 : 0)));
+		#endif
+		//FLUSHPIPE;
+		valid = t_branch;
+		break;
+	case 29:
+		if(tinstr & 0x1)
+			valid = t_undefined;
+		else{
+			/* BLX 1 for armv5t and above */
+			//printf("In %s, After  BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
+			valid = t_branch;
+		}
+		break;
+	case 30:		/* BL instruction 1 */
+		/* Format 19 */
+		/* There is no single ARM instruction equivalent for this Thumb
+		   instruction. To keep the simulation simple (from the user
+		   perspective) we check if the following instruction is the
+		   second half of this BL, and if it is we simulate it
+		   immediately.  */
+		valid = t_branch;
+		break;
+	case 31:		/* BL instruction 2 */
+		/* Format 19 */
+		/* There is no single ARM instruction equivalent for this
+		   instruction. Also, it should only ever be matched with the
+		   fmt19 "BL instruction 1" instruction. However, we do allow
+		   the simulation of it on its own, with undefined results if
+		   r14 is not suitably initialised.  */
+		{
+			#if 0
+			ARMword tmp = (pc + 2);
+			state->Reg[15] =
+				(state->Reg[14] + ((tinstr & 0x07FF) << 1));
+			state->Reg[14] = (tmp | 1);
+			#endif
+			valid = t_branch;
+		}
+		break;
+	}
+	*inst_size = 2;
+	return valid;
+}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
new file mode 100644
index 000000000..5541de9d1
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -0,0 +1,51 @@
+/* Copyright (C)
+* 2011 - Michael.Kang blackfin.kang@gmail.com
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+/**
+* @file arm_dyncom_thumb.h
+* @brief The thumb dyncom
+* @author Michael.Kang blackfin.kang@gmail.com
+* @version 78.77
+* @date 2011-11-07
+*/
+
+#ifndef __ARM_DYNCOM_THUMB_H__
+#define __ARM_DYNCOM_THUMB_H__
+
+#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/skyeye_types.h"
+
+enum tdstate {
+    t_undefined,    // Undefined Thumb instruction
+    t_decoded,      // Instruction decoded to ARM equivalent
+    t_branch,       // Thumb branch (already processed)
+    t_uninitialized,
+};
+
+tdstate
+thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size);
+static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){
+    uint32 tinstr;
+    if ((pc & 0x3) != 0)
+        tinstr = instr >> 16;
+    else
+        tinstr = instr & 0xFFFF;
+    return tinstr;
+}
+
+#endif
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 64760500c..49ae01a0c 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -10,7 +10,7 @@
 #include "core/arm/skyeye_common/armdefs.h"
 #include "core/arm/skyeye_common/armemu.h"
 
-class ARM_Interpreter : virtual public ARM_Interface {
+class ARM_Interpreter final : virtual public ARM_Interface {
 public:
 
     ARM_Interpreter();
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 3d3545c65..2568b93ef 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -15,18 +15,11 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
-//#include <util.h>
-
-#include <string>
-#include "core/arm/interpreter/armdefs.h"
-#include "core/arm/interpreter/armemu.h"
-#include "core/hle/coprocessor.h"
+#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armemu.h"
 #include "core/arm/disassembler/arm_disasm.h"
+#include "core/mem_map.h"
 
-//#include "ansidecl.h"
-//#include "skyeye.h"
-//extern int skyeye_instr_debug;
-/* Definitions for the support routines.  */
 
 static ARMword ModeToBank (ARMword);
 static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
@@ -751,7 +744,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
     int cpopc = BITS(21, 23) & 0x7;
 
     if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
-	ARMword result = HLE::CallMRC(instr);
+	ARMword result = Memory::KERNEL_MEMORY_VADDR;
 
 	if (result != -1) {
 		return result;
diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h
index 0ca62780b..4dac1a8bf 100644
--- a/src/core/arm/skyeye_common/arm_regformat.h
+++ b/src/core/arm/skyeye_common/arm_regformat.h
@@ -99,5 +99,7 @@ enum arm_regno{
     MAX_REG_NUM,
 };
 
-#define VFP_OFFSET(x) (x - VFP_BASE)
+#define CP15(idx)       (idx - CP15_BASE)
+#define VFP_OFFSET(x)   (x - VFP_BASE)
+
 #endif
diff --git a/src/core/arm/skyeye_common/armcpu.h b/src/core/arm/skyeye_common/armcpu.h
index 6b5ea8566..3a029f0e7 100644
--- a/src/core/arm/skyeye_common/armcpu.h
+++ b/src/core/arm/skyeye_common/armcpu.h
@@ -20,16 +20,13 @@
 
 #ifndef __ARM_CPU_H__
 #define __ARM_CPU_H__
-//#include <skyeye_thread.h>
-//#include <skyeye_obj.h>
-//#include <skyeye_mach.h>
-//#include <skyeye_exec.h>
 
 #include <stddef.h>
 #include <stdio.h>
 
 #include "common/thread.h"
 
+#include "core/arm/skyeye_common/armdefs.h"
 
 typedef struct ARM_CPU_State_s {
     ARMul_State * core;
diff --git a/src/core/arm/skyeye_common/armos.h b/src/core/arm/skyeye_common/armos.h
index 4b58801ad..ffdadcd1c 100644
--- a/src/core/arm/skyeye_common/armos.h
+++ b/src/core/arm/skyeye_common/armos.h
@@ -15,14 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
-//#include "bank_defs.h"
-//#include "dyncom/defines.h"
-
-//typedef struct mmap_area{
-//	mem_bank_t bank;
-//	void *mmap_addr;
-//	struct mmap_area *next;
-//}mmap_area_t;
+#include <stdint.h>
 
 #if FAST_MEMORY
 /* in user mode, mmap_base will be on initial brk,
diff --git a/src/core/arm/skyeye_common/skyeye_defs.h b/src/core/arm/skyeye_common/skyeye_defs.h
index b6713ebad..d4088383f 100644
--- a/src/core/arm/skyeye_common/skyeye_defs.h
+++ b/src/core/arm/skyeye_common/skyeye_defs.h
@@ -108,4 +108,6 @@ typedef struct generic_arch_s
 	align_t alignment;
 } generic_arch_t;
 
-#endif
\ No newline at end of file
+typedef u32 addr_t;
+
+#endif
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
new file mode 100644
index 000000000..e7f022f19
--- /dev/null
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -0,0 +1,55 @@
+/*
+        skyeye_types.h - some data types definition for skyeye debugger
+        Copyright (C) 2003 Skyeye Develop Group
+        for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>
+
+        This program is free software; you can redistribute it and/or modify
+        it under the terms of the GNU General Public License as published by
+        the Free Software Foundation; either version 2 of the License, or
+        (at your option) any later version.
+
+        This program is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+        GNU General Public License for more details.
+
+        You should have received a copy of the GNU General Public License
+        along with this program; if not, write to the Free Software
+        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+/*
+ * 12/16/2006   Michael.Kang  <blackfin.kang@gmail.com>
+ */
+
+#ifndef __SKYEYE_TYPES_H
+#define __SKYEYE_TYPES_H
+
+#include <stdint.h>
+
+/*default machine word length */
+
+#ifndef __BEOS__
+/* To avoid the type conflict with the qemu */
+#ifndef QEMU
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+
+typedef int8_t sint8;
+typedef int16_t sint16;
+typedef int32_t sint32;
+typedef int64_t sint64;
+#endif
+
+typedef uint32_t address_t;
+typedef uint32_t uinteger_t;
+typedef int32_t integer_t;
+
+typedef uint32_t physical_address_t;
+typedef uint32_t generic_address_t; 
+
+#endif
+
+#endif
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index a57047911..45208fb13 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -3709,7 +3709,7 @@ VFPLABEL_INST:
 		{
 			fault = check_address_validity(cpu, addr, &phys_addr, 0);
 			if (fault) goto MMU_EXCEPTION;
-			fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
+			fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
 			if (fault) goto MMU_EXCEPTION;
 			DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]);
 		}
@@ -3719,13 +3719,13 @@ VFPLABEL_INST:
 			if (fault) goto MMU_EXCEPTION;
 
 			/* Check endianness */
-			fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32);
+			fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32);
 			if (fault) goto MMU_EXCEPTION;
 
 			fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
 			if (fault) goto MMU_EXCEPTION;
 
-			fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32);
+			fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32);
 			if (fault) goto MMU_EXCEPTION;
 			DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]);
 		}
@@ -3926,7 +3926,7 @@ VFPLABEL_INST:
 			{
 				fault = check_address_validity(cpu, addr, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+				fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
 				addr += 4;
@@ -3936,12 +3936,12 @@ VFPLABEL_INST:
 				/* Careful of endianness, little by default */
 				fault = check_address_validity(cpu, addr, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
+				fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
 				if (fault) goto MMU_EXCEPTION;
 
 				fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+				fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
 				addr += 8;
@@ -4048,7 +4048,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 	{
 		if (single)
 		{
-			//fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+			//fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 			#if 0
 			phys_addr = get_phys_addr(cpu, bb, Addr, 0);
 			bb = cpu->dyncom_engine->bb;
@@ -4166,7 +4166,7 @@ VFPLABEL_INST: /* encoding 1 */
 				fault = check_address_validity(cpu, addr, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+				fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
 				addr += 4;
@@ -4177,13 +4177,13 @@ VFPLABEL_INST: /* encoding 1 */
 				fault = check_address_validity(cpu, addr, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
+				fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
 				if (fault) goto MMU_EXCEPTION;
 
 				fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+				fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
 				addr += 8;
@@ -4304,7 +4304,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 		if (single)
 		{
 			
-			//fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+			//fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 			/* if R(i) is R15? */
 			#if 0
 			phys_addr = get_phys_addr(cpu, bb, Addr, 0);
@@ -4321,7 +4321,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 		else
 		{
 		
-			//fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
+			//fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
 			#if 0
 			phys_addr = get_phys_addr(cpu, bb, Addr, 0);
 			bb = cpu->dyncom_engine->bb;
@@ -4332,7 +4332,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 			bb = cpu->dyncom_engine->bb;
 			//if (fault) goto MMU_EXCEPTION;
 
-			//fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+			//fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
 			#if 0
 			phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
 			bb = cpu->dyncom_engine->bb;
@@ -4431,7 +4431,7 @@ VFPLABEL_INST:
 				fault = check_address_validity(cpu, addr, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_read_memory(core, addr, phys_addr, value1, 32);
+				fault = interpreter_read_memory(addr, phys_addr, value1, 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr);
 				cpu->ExtReg[inst_cream->d+i] = value1;
@@ -4443,13 +4443,13 @@ VFPLABEL_INST:
 				fault = check_address_validity(cpu, addr, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_read_memory(core, addr, phys_addr, value1, 32);
+				fault = interpreter_read_memory(addr, phys_addr, value1, 32);
 				if (fault) goto MMU_EXCEPTION;
 
 				fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
 
-				fault = interpreter_read_memory(core, addr + 4, phys_addr, value2, 32);
+				fault = interpreter_read_memory(addr + 4, phys_addr, value2, 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr);
 				cpu->ExtReg[(inst_cream->d+i)*2] = value1;
@@ -4682,7 +4682,7 @@ VFPLABEL_INST:
 		{
 			fault = check_address_validity(cpu, addr, &phys_addr, 1);
 			if (fault) goto MMU_EXCEPTION;
-			fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
+			fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
 			if (fault) goto MMU_EXCEPTION;
 			DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr);
 		}
@@ -4691,12 +4691,12 @@ VFPLABEL_INST:
 			unsigned int word1, word2;
 			fault = check_address_validity(cpu, addr, &phys_addr, 1);
 			if (fault) goto MMU_EXCEPTION;
-			fault = interpreter_read_memory(core, addr, phys_addr, word1, 32);
+			fault = interpreter_read_memory(addr, phys_addr, word1, 32);
 			if (fault) goto MMU_EXCEPTION;
 
 			fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
 			if (fault) goto MMU_EXCEPTION;
-			fault = interpreter_read_memory(core, addr + 4, phys_addr, word2, 32);
+			fault = interpreter_read_memory(addr + 4, phys_addr, word2, 32);
 			if (fault) goto MMU_EXCEPTION;
 			/* Check endianness */
 			cpu->ExtReg[inst_cream->d*2] = word1;
@@ -4923,7 +4923,7 @@ VFPLABEL_INST:
 			{
 				fault = check_address_validity(cpu, addr, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+				fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr);
 				addr += 4;
@@ -4933,12 +4933,12 @@ VFPLABEL_INST:
 				/* Careful of endianness, little by default */
 				fault = check_address_validity(cpu, addr, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
+				fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
 				if (fault) goto MMU_EXCEPTION;
 
 				fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
 				if (fault) goto MMU_EXCEPTION;
-				fault = interpreter_read_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+				fault = interpreter_read_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
 				if (fault) goto MMU_EXCEPTION;
 				DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr);
 				addr += 8;
@@ -5058,7 +5058,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 		if (single)
 		{
 			
-			//fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
+			//fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
 			/* if R(i) is R15? */
 			#if 0
 			phys_addr = get_phys_addr(cpu, bb, Addr, 1);
@@ -5095,7 +5095,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
 			val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
 			LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
 
-			//fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+			//fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
 			//DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
 			//addr += 8;
 			Addr = ADD(Addr, CONST(8));
diff --git a/src/core/hle/coprocessor.h b/src/core/hle/coprocessor.h
deleted file mode 100644
index b08d6f3ee..000000000
--- a/src/core/hle/coprocessor.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.  
-
-#pragma once
-
-#include "common/common_types.h"
-
-namespace HLE {
-
-/// Coprocessor operations
-enum CoprocessorOperation {
-    DATA_SYNCHRONIZATION_BARRIER    = 0xE0,
-    CALL_GET_THREAD_COMMAND_BUFFER  = 0xE1,
-};
-
-/// Call an MRC (move to ARM register from coprocessor) instruction in HLE
-s32 CallMRC(u32 instruction);
-
-} // namespace