summaryrefslogtreecommitdiff
path: root/src/core/arm/dyncom
diff options
context:
space:
mode:
authorGravatar bunnei2014-10-25 14:35:31 -0400
committerGravatar bunnei2014-10-25 14:35:31 -0400
commit4615c73d15f6f27c5e275c57dcafcb56355b9c2d (patch)
treee11104887d1a680e3aa33bddc4ad3ca764ead696 /src/core/arm/dyncom
parentMerge pull request #149 from linkmauve/open-file-directly-fix (diff)
parentARM: Removed unnecessary and unused SkyEye MMU code. (diff)
downloadyuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.tar.gz
yuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.tar.xz
yuzu-4615c73d15f6f27c5e275c57dcafcb56355b9c2d.zip
Merge pull request #112 from bunnei/skyeye-dyncom-interpreter
SkyEye dyncom interpreter
Diffstat (limited to 'src/core/arm/dyncom')
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp163
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h90
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp402
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h155
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp6563
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h7
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.cpp120
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h55
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp521
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h51
10 files changed, 8127 insertions, 0 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
new file mode 100644
index 000000000..669b612fc
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -0,0 +1,163 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "core/arm/skyeye_common/armcpu.h"
6#include "core/arm/skyeye_common/armemu.h"
7#include "core/arm/skyeye_common/vfp/vfp.h"
8
9#include "core/arm/dyncom/arm_dyncom.h"
10#include "core/arm/dyncom/arm_dyncom_interpreter.h"
11
12const static cpu_config_t s_arm11_cpu_info = {
13 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
14};
15
16ARM_DynCom::ARM_DynCom() : ticks(0) {
17 state = std::unique_ptr<ARMul_State>(new ARMul_State);
18
19 ARMul_EmulateInit();
20 memset(state.get(), 0, sizeof(ARMul_State));
21
22 ARMul_NewState((ARMul_State*)state.get());
23
24 state->abort_model = 0;
25 state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
26 state->bigendSig = LOW;
27
28 ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
29 state->lateabtSig = LOW;
30
31 // Reset the core to initial state
32 ARMul_CoProInit(state.get());
33 ARMul_Reset(state.get());
34 state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
35 state->Emulate = 3;
36
37 state->pc = state->Reg[15] = 0x00000000;
38 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
39 state->servaddr = 0xFFFF0000;
40 state->NirqSig = HIGH;
41
42 VFPInit(state.get()); // Initialize the VFP
43
44 ARMul_EmulateInit();
45}
46
47ARM_DynCom::~ARM_DynCom() {
48}
49
50/**
51 * Set the Program Counter to an address
52 * @param addr Address to set PC to
53 */
54void ARM_DynCom::SetPC(u32 pc) {
55 state->pc = state->Reg[15] = pc;
56}
57
58/*
59 * Get the current Program Counter
60 * @return Returns current PC
61 */
62u32 ARM_DynCom::GetPC() const {
63 return state->pc;
64}
65
66/**
67 * Get an ARM register
68 * @param index Register index (0-15)
69 * @return Returns the value in the register
70 */
71u32 ARM_DynCom::GetReg(int index) const {
72 return state->Reg[index];
73}
74
75/**
76 * Set an ARM register
77 * @param index Register index (0-15)
78 * @param value Value to set register to
79 */
80void ARM_DynCom::SetReg(int index, u32 value) {
81 state->Reg[index] = value;
82}
83
84/**
85 * Get the current CPSR register
86 * @return Returns the value of the CPSR register
87 */
88u32 ARM_DynCom::GetCPSR() const {
89 return state->Cpsr;
90}
91
92/**
93 * Set the current CPSR register
94 * @param cpsr Value to set CPSR to
95 */
96void ARM_DynCom::SetCPSR(u32 cpsr) {
97 state->Cpsr = cpsr;
98}
99
100/**
101 * Returns the number of clock ticks since the last reset
102 * @return Returns number of clock ticks
103 */
104u64 ARM_DynCom::GetTicks() const {
105 return ticks;
106}
107
108/**
109 * Executes the given number of instructions
110 * @param num_instructions Number of instructions to executes
111 */
112void ARM_DynCom::ExecuteInstructions(int num_instructions) {
113 ticks += num_instructions;
114 state->NumInstrsToExecute = num_instructions;
115 InterpreterMainLoop(state.get());
116}
117
118/**
119 * Saves the current CPU context
120 * @param ctx Thread context to save
121 * @todo Do we need to save Reg[15] and NextInstr?
122 */
123void ARM_DynCom::SaveContext(ThreadContext& ctx) {
124 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
125 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
126
127 ctx.sp = state->Reg[13];
128 ctx.lr = state->Reg[14];
129 ctx.pc = state->pc;
130 ctx.cpsr = state->Cpsr;
131
132 ctx.fpscr = state->VFP[1];
133 ctx.fpexc = state->VFP[2];
134
135 ctx.reg_15 = state->Reg[15];
136 ctx.mode = state->NextInstr;
137}
138
139/**
140 * Loads a CPU context
141 * @param ctx Thread context to load
142 * @param Do we need to load Reg[15] and NextInstr?
143 */
144void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
145 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
146 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
147
148 state->Reg[13] = ctx.sp;
149 state->Reg[14] = ctx.lr;
150 state->pc = ctx.pc;
151 state->Cpsr = ctx.cpsr;
152
153 state->VFP[1] = ctx.fpscr;
154 state->VFP[2] = ctx.fpexc;
155
156 state->Reg[15] = ctx.reg_15;
157 state->NextInstr = ctx.mode;
158}
159
160/// Prepare core for thread reschedule (if needed to correctly handle state)
161void ARM_DynCom::PrepareReschedule() {
162 state->NumInstrsToExecute = 0;
163}
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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8
9#include "common/common_types.h"
10
11#include "core/arm/arm_interface.h"
12#include "core/arm/skyeye_common/armdefs.h"
13
14class ARM_DynCom final : virtual public ARM_Interface {
15public:
16
17 ARM_DynCom();
18 ~ARM_DynCom();
19
20 /**
21 * Set the Program Counter to an address
22 * @param addr Address to set PC to
23 */
24 void SetPC(u32 pc);
25
26 /*
27 * Get the current Program Counter
28 * @return Returns current PC
29 */
30 u32 GetPC() const;
31
32 /**
33 * Get an ARM register
34 * @param index Register index (0-15)
35 * @return Returns the value in the register
36 */
37 u32 GetReg(int index) const;
38
39 /**
40 * Set an ARM register
41 * @param index Register index (0-15)
42 * @param value Value to set register to
43 */
44 void SetReg(int index, u32 value);
45
46 /**
47 * Get the current CPSR register
48 * @return Returns the value of the CPSR register
49 */
50 u32 GetCPSR() const;
51
52 /**
53 * Set the current CPSR register
54 * @param cpsr Value to set CPSR to
55 */
56 void SetCPSR(u32 cpsr);
57
58 /**
59 * Returns the number of clock ticks since the last reset
60 * @return Returns number of clock ticks
61 */
62 u64 GetTicks() const;
63
64 /**
65 * Saves the current CPU context
66 * @param ctx Thread context to save
67 */
68 void SaveContext(ThreadContext& ctx);
69
70 /**
71 * Loads a CPU context
72 * @param ctx Thread context to load
73 */
74 void LoadContext(const ThreadContext& ctx);
75
76 /// Prepare core for thread reschedule (if needed to correctly handle state)
77 void PrepareReschedule();
78
79 /**
80 * Executes the given number of instructions
81 * @param num_instructions Number of instructions to executes
82 */
83 void ExecuteInstructions(int num_instructions);
84
85private:
86
87 std::unique_ptr<ARMul_State> state;
88 u64 ticks;
89
90};
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 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_dec.cpp
20* @brief Some common utility for arm decoder
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25
26#include "core/arm/skyeye_common/arm_regformat.h"
27#include "core/arm/skyeye_common/armdefs.h"
28#include "core/arm/dyncom/arm_dyncom_dec.h"
29
30const ISEITEM arm_instruction[] = {
31 #define VFP_DECODE
32 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
33 #undef VFP_DECODE
34 {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005},
35 {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a},
36 {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007},
37 {"blx" , 1 , 3 , 25, 31, 0x0000007d},
38 {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000},
39 {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f},
40 {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000},
41 {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f},
42 {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb},
43 {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001},
44 {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007},
45 {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007},
46 {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007},
47 {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007},
48 {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007},
49 {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007},
50 {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000},
51 {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007},
52 {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f},
53 {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f},
54 {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005},
55 {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009},
56 {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009},
57 {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009},
58 {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009},
59 {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007},
60 {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003},
61 {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005},
62 {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005},
63 {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003},
64 {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009},
65 {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001},
66 {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b},
67 {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003},
68 {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009},
69 {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001},
70 {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007},
71 {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009},
72 {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007},
73 {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005},
74 {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f},
75 {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007},
76 {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003},
77 {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001},
78 {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005},
79 {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f},
80 {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007},
81 {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003},
82 {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009},
83 {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001},
84 {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007},
85 {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005},
86 {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f},
87 {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007},
88 {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003},
89 {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009},
90 {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001},
91 {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003},
92 {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009},
93 {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001},
94 {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007},
95 {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007},
96 {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009},
97 {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002},
98 {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001},
99 {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007},
100 {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001},
101 {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003},
102 {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003},
103 {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b},
104 {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005},
105 {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001},
106 {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003},
107 {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009},
108 {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005},
109 {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005},
110 {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005},
111 {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009},
112 {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f},
113 {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007},
114 {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
115 {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
116 {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001},
117 {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001},
118 {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001},
119 {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001},
120 {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001},
121 {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001},
122 {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001},
123 {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000},
124 {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002},
125 {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005},
126 {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001},
127 {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000},
128 {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000},
129// {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
130 {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000},
131 {"mcrr" , 1 , 6 , 20, 27, 0x000000c4},
132 {"mrrc" , 1 , 6 , 20, 27, 0x000000c5},
133 {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015},
134 {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011},
135 {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013},
136 {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017},
137 {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009},
138 {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009},
139 {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009},
140 {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009},
141 {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009},
142 {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009},
143 {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001},
144 {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001},
145 {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000},
146 {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000},
147 {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000},
148 {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e},
149 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000},
150 {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001},
151 {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004},
152 {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003},
153 {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007},
154 {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006},
155 {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005},
156 {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002},
157 {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c},
158 {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f},
159 {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d},
160 {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004},
161 {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001},
162 {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f},
163 {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000},
164 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001},
165 {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d},
166 {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f},
167 {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b},
168 {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b},
169 {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d},
170 {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002},
171 {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006},
172 {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007},
173 {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003},
174 {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001},
175 {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001},
176 {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002},
177 {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001},
178 {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000},
179 {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
180 {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
181 {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000},
182 {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000},
183 {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000},
184 {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001},
185 {"swi" , 1 , 0 , 24, 27, 0x0000000f},
186 {"bbl" , 1 , 0 , 25, 27, 0x00000005},
187};
188
189const ISEITEM arm_exclusion_code[] = {
190 #define VFP_DECODE_EXCLUSION
191 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
192 #undef VFP_DECODE_EXCLUSION
193 {"srs" , 0 , 6 , 0},
194 {"rfe" , 0 , 6 , 0},
195 {"bkpt" , 0 , 3 , 0},
196 {"blx" , 0 , 3 , 0},
197 {"cps" , 0 , 6 , 0},
198 {"pld" , 0 , 4 , 0},
199 {"setend" , 0 , 6 , 0},
200 {"clrex" , 0 , 6 , 0},
201 {"rev16" , 0 , 6 , 0},
202 {"usad8" , 0 , 6 , 0},
203 {"sxtb" , 0 , 6 , 0},
204 {"uxtb" , 0 , 6 , 0},
205 {"sxth" , 0 , 6 , 0},
206 {"sxtb16" , 0 , 6 , 0},
207 {"uxth" , 0 , 6 , 0},
208 {"uxtb16" , 0 , 6 , 0},
209 {"cpy" , 0 , 6 , 0},
210 {"uxtab" , 0 , 6 , 0},
211 {"ssub8" , 0 , 6 , 0},
212 {"shsub8" , 0 , 6 , 0},
213 {"ssubaddx" , 0 , 6 , 0},
214 {"strex" , 0 , 6 , 0},
215 {"strexb" , 0 , 7 , 0},
216 {"swp" , 0 , 0 , 0},
217 {"swpb" , 0 , 0 , 0},
218 {"ssub16" , 0 , 6 , 0},
219 {"ssat16" , 0 , 6 , 0},
220 {"shsubaddx" , 0 , 6 , 0},
221 {"qsubaddx" , 0 , 6 , 0},
222 {"shaddsubx" , 0 , 6 , 0},
223 {"shadd8" , 0 , 6 , 0},
224 {"shadd16" , 0 , 6 , 0},
225 {"sel" , 0 , 6 , 0},
226 {"saddsubx" , 0 , 6 , 0},
227 {"sadd8" , 0 , 6 , 0},
228 {"sadd16" , 0 , 6 , 0},
229 {"shsub16" , 0 , 6 , 0},
230 {"umaal" , 0 , 6 , 0},
231 {"uxtab16" , 0 , 6 , 0},
232 {"usubaddx" , 0 , 6 , 0},
233 {"usub8" , 0 , 6 , 0},
234 {"usub16" , 0 , 6 , 0},
235 {"usat16" , 0 , 6 , 0},
236 {"usada8" , 0 , 6 , 0},
237 {"uqsubaddx" , 0 , 6 , 0},
238 {"uqsub8" , 0 , 6 , 0},
239 {"uqsub16" , 0 , 6 , 0},
240 {"uqaddsubx" , 0 , 6 , 0},
241 {"uqadd8" , 0 , 6 , 0},
242 {"uqadd16" , 0 , 6 , 0},
243 {"sxtab" , 0 , 6 , 0},
244 {"uhsubaddx" , 0 , 6 , 0},
245 {"uhsub8" , 0 , 6 , 0},
246 {"uhsub16" , 0 , 6 , 0},
247 {"uhaddsubx" , 0 , 6 , 0},
248 {"uhadd8" , 0 , 6 , 0},
249 {"uhadd16" , 0 , 6 , 0},
250 {"uaddsubx" , 0 , 6 , 0},
251 {"uadd8" , 0 , 6 , 0},
252 {"uadd16" , 0 , 6 , 0},
253 {"sxtah" , 0 , 6 , 0},
254 {"sxtab16" , 0 , 6 , 0},
255 {"qadd8" , 0 , 6 , 0},
256 {"bxj" , 0 , 5 , 0},
257 {"clz" , 0 , 3 , 0},
258 {"uxtah" , 0 , 6 , 0},
259 {"bx" , 0 , 2 , 0},
260 {"rev" , 0 , 6 , 0},
261 {"blx" , 0 , 3 , 0},
262 {"revsh" , 0 , 6 , 0},
263 {"qadd" , 0 , 4 , 0},
264 {"qadd16" , 0 , 6 , 0},
265 {"qaddsubx" , 0 , 6 , 0},
266 {"ldrex" , 0 , 0 , 0},
267 {"qdadd" , 0 , 4 , 0},
268 {"qdsub" , 0 , 4 , 0},
269 {"qsub" , 0 , 4 , 0},
270 {"ldrexb" , 0 , 7 , 0},
271 {"qsub8" , 0 , 6 , 0},
272 {"qsub16" , 0 , 6 , 0},
273 {"smuad" , 0 , 6 , 0},
274 {"smmul" , 0 , 6 , 0},
275 {"smusd" , 0 , 6 , 0},
276 {"smlsd" , 0 , 6 , 0},
277 {"smlsld" , 0 , 6 , 0},
278 {"smmla" , 0 , 6 , 0},
279 {"smmls" , 0 , 6 , 0},
280 {"smlald" , 0 , 6 , 0},
281 {"smlad" , 0 , 6 , 0},
282 {"smlaw" , 0 , 4 , 0},
283 {"smulw" , 0 , 4 , 0},
284 {"pkhtb" , 0 , 6 , 0},
285 {"pkhbt" , 0 , 6 , 0},
286 {"smul" , 0 , 4 , 0},
287 {"smlal" , 0 , 4 , 0},
288 {"smla" , 0 , 4 , 0},
289 {"mcrr" , 0 , 6 , 0},
290 {"mrrc" , 0 , 6 , 0},
291 {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
292 {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
293 {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
294 {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
295 {"smull" , 0 , 0 , 0},
296 {"umull" , 0 , 0 , 0},
297 {"umlal" , 0 , 0 , 0},
298 {"smlal" , 0 , 0 , 0},
299 {"mul" , 0 , 0 , 0},
300 {"mla" , 0 , 0 , 0},
301 {"ssat" , 0 , 6 , 0},
302 {"usat" , 0 , 6 , 0},
303 {"mrs" , 0 , 0 , 0},
304 {"msr" , 0 , 0 , 0},
305 {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
306 {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
307 {"ldm" , 0 , 0 , 0},
308 {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
309 {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
310 {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
311 {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
312 {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
313 {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
314 {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
315 {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
316 {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
317 {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
318 {"stm" , 0 , 0 , 0},
319 {"ldm" , 0 , 0 , 0},
320 {"ldrsh" , 0 , 2 , 0},
321 {"stm" , 0 , 0 , 0},
322 {"ldm" , 0 , 0 , 0},
323 {"ldrsb" , 0 , 2 , 0},
324 {"strd" , 0 , 4 , 0},
325 {"ldrh" , 0 , 0 , 0},
326 {"strh" , 0 , 0 , 0},
327 {"ldrd" , 0 , 4 , 0},
328 {"strt" , 0 , 0 , 0},
329 {"strbt" , 0 , 0 , 0},
330 {"ldrbt" , 0 , 0 , 0},
331 {"ldrt" , 0 , 0 , 0},
332 {"mrc" , 0 , 6 , 0},
333 {"mcr" , 0 , 0 , 0},
334 {"msr" , 0 , 0 , 0},
335 {"ldrb" , 0 , 0 , 0},
336 {"strb" , 0 , 0 , 0},
337 {"ldr" , 0 , 0 , 0},
338 {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e},
339 {"str" , 0 , 0 , 0},
340 {"cdp" , 0 , 0 , 0},
341 {"stc" , 0 , 0 , 0},
342 {"ldc" , 0 , 0 , 0},
343 {"swi" , 0 , 0 , 0},
344 {"bbl" , 0 , 0 , 0},
345 {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */
346 {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */
347 {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */
348 {"invalid", 0, INVALID, 0}
349};
350
351int decode_arm_instr(uint32_t instr, int32_t *idx)
352{
353 int n = 0;
354 int base = 0;
355 int ret = DECODE_FAILURE;
356 int i = 0;
357 int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM);
358 for (i = 0; i < instr_slots; i++)
359 {
360// ret = DECODE_SUCCESS;
361 n = arm_instruction[i].attribute_value;
362 base = 0;
363 while (n) {
364 if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
365 /* clrex */
366 if (instr != arm_instruction[i].content[base + 2]) {
367 break;
368 }
369 } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
370 break;
371 }
372 base += 3;
373 n --;
374 }
375 //All conditions is satisfied.
376 if (n == 0)
377 ret = DECODE_SUCCESS;
378
379 if (ret == DECODE_SUCCESS) {
380 n = arm_exclusion_code[i].attribute_value;
381 if (n != 0) {
382 base = 0;
383 while (n) {
384 if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
385 break; }
386 base += 3;
387 n --;
388 }
389 //All conditions is satisfied.
390 if (n == 0)
391 ret = DECODE_FAILURE;
392 }
393 }
394
395 if (ret == DECODE_SUCCESS) {
396 *idx = i;
397 return ret;
398 }
399 }
400 return ret;
401}
402
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 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19/**
20* @file arm_dyncom_dec.h
21* @brief Some common utility for arm instruction decoder
22* @author Michael.Kang blackfin.kang@gmail.com
23* @version 7849
24* @date 2012-03-15
25*/
26
27#ifndef __ARM_DYNCOM_DEC__
28#define __ARM_DYNCOM_DEC__
29
30#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
31#define BIT(n) ((instr >> (n)) & 1)
32#define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0);
33#define ptr_N cpu->ptr_N
34#define ptr_Z cpu->ptr_Z
35#define ptr_C cpu->ptr_C
36#define ptr_V cpu->ptr_V
37#define ptr_I cpu->ptr_I
38#define ptr_T cpu->ptr_T
39#define ptr_CPSR cpu->ptr_gpr[16]
40
41/* for MUL instructions */
42/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
43#define RDHi ((instr >> 16) & 0xF)
44/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
45#define RDLo ((instr >> 12) & 0xF)
46/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
47#define MUL_RD ((instr >> 16) & 0xF)
48/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
49#define MUL_RN ((instr >> 12) & 0xF)
50/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */
51#define RS ((instr >> 8) & 0xF)
52
53/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
54#define RD ((instr >> 12) & 0xF)
55/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
56#define RN ((instr >> 16) & 0xF)
57/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
58#define RM (instr & 0xF)
59#define BIT(n) ((instr >> (n)) & 1)
60#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
61
62/* CP15 registers */
63#define OPCODE_1 BITS(21, 23)
64#define CRn BITS(16, 19)
65#define CRm BITS(0, 3)
66#define OPCODE_2 BITS(5, 7)
67
68/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */
69#define I BIT(25)
70/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */
71#define S BIT(20)
72
73#define SHIFT BITS(5,6)
74#define SHIFT_IMM BITS(7,11)
75#define IMMH BITS(8,11)
76#define IMML BITS(0,3)
77
78#define LSPBIT BIT(24)
79#define LSUBIT BIT(23)
80#define LSBBIT BIT(22)
81#define LSWBIT BIT(21)
82#define LSLBIT BIT(20)
83#define LSSHBITS BITS(5,6)
84#define OFFSET12 BITS(0,11)
85#define SBIT BIT(20)
86#define DESTReg (BITS (12, 15))
87
88/* they are in unused state, give a corrent value when using */
89#define IS_V5E 0
90#define IS_V5 0
91#define IS_V6 0
92#define LHSReg 0
93
94/* temp define the using the pc reg need implement a flow */
95#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2))
96
97#define OPERAND operand(cpu,instr,bb,NULL)
98#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
99#define BOPERAND boperand(instr)
100
101#define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN))
102#define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN))
103
104#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
105
106int decode_arm_instr(uint32_t instr, int32_t *idx);
107
108enum DECODE_STATUS {
109 DECODE_SUCCESS,
110 DECODE_FAILURE
111};
112
113struct instruction_set_encoding_item {
114 const char *name;
115 int attribute_value;
116 int version;
117 u32 content[21];
118};
119
120typedef struct instruction_set_encoding_item ISEITEM;
121
122#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;}
123#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag)
124
125#define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \
126 LET(base_reg, cpu->dyncom_engine->wb_value);}
127inline int get_reg_count(uint32_t instr){
128 int i = BITS(0,15);
129 int count = 0;
130 while(i){
131 if(i & 1)
132 count ++;
133 i = i >> 1;
134 }
135 return count;
136}
137
138enum ARMVER {
139 INVALID = 0,
140 ARMALL,
141 ARMV4,
142 ARMV4T,
143 ARMV5T,
144 ARMV5TE,
145 ARMV5TEJ,
146 ARMV6,
147 ARM1176JZF_S,
148 ARMVFP2,
149 ARMVFP3
150};
151
152//extern const INSTRACT arm_instruction_action[];
153extern const ISEITEM arm_instruction[];
154
155#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..fe1501b59
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -0,0 +1,6563 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_interpreter.cpp
20* @brief The fast interpreter for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25
26#define CITRA_IGNORE_EXIT(x)
27
28#include <algorithm>
29#include <map>
30#include <stdio.h>
31#include <assert.h>
32#include <cstdio>
33#include <vector>
34
35using namespace std;
36
37#include "core/arm/skyeye_common/armdefs.h"
38#include "core/arm/skyeye_common/armmmu.h"
39#include "arm_dyncom_thumb.h"
40#include "arm_dyncom_run.h"
41#include "core/arm/skyeye_common/vfp/vfp.h"
42/* shenoubang 2012-6-14 */
43#ifdef __WIN32__
44#include "bank_defs.h"
45#endif
46
47#include "core/mem_map.h"
48#include "core/hle/hle.h"
49
50enum {
51 COND = (1 << 0),
52 NON_BRANCH = (1 << 1),
53 DIRECT_BRANCH = (1 << 2),
54 INDIRECT_BRANCH = (1 << 3),
55 CALL = (1 << 4),
56 RET = (1 << 5),
57 END_OF_PAGE = (1 << 6),
58 THUMB = (1 << 7)
59};
60
61#define USER_MODE_OPT 1
62#define HYBRID_MODE 0 // Enable for JIT mode
63
64#define THRESHOLD 1000
65#define DURATION 500
66//#define PRINT_PROFILE_INFO
67
68#define CHECK_RS if(RS == 15) rs += 8
69#define CHECK_RM if(RM == 15) rm += 8
70
71//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1))
72#undef BITS
73#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
74#define BIT(s, n) ((s >> (n)) & 1)
75#define RM BITS(sht_oper, 0, 3)
76#define RS BITS(sht_oper, 8, 11)
77
78#define glue(x, y) x ## y
79#define DPO(s) glue(DataProcessingOperands, s)
80#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
81#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
82#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
83#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
84
85//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n))))
86//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1)))
87#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) )
88
89extern void switch_mode(arm_core_t *core, uint32_t mode);
90//extern bool InAPrivilegedMode(arm_core_t *core);
91
92typedef arm_core_t arm_processor;
93typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
94
95/* exclusive memory access */
96static int exclusive_detect(ARMul_State* state, ARMword addr){
97 int i;
98 #if 0
99 for(i = 0; i < 128; i++){
100 if(state->exclusive_tag_array[i] == addr)
101 return 0;
102 }
103 #endif
104 if(state->exclusive_tag == addr)
105 return 0;
106 else
107 return -1;
108}
109
110static void add_exclusive_addr(ARMul_State* state, ARMword addr){
111 int i;
112 #if 0
113 for(i = 0; i < 128; i++){
114 if(state->exclusive_tag_array[i] == 0xffffffff){
115 state->exclusive_tag_array[i] = addr;
116 //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr);
117 return;
118 }
119 }
120 DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
121 #endif
122 state->exclusive_tag = addr;
123 return;
124}
125
126static void remove_exclusive(ARMul_State* state, ARMword addr){
127 #if 0
128 int i;
129 for(i = 0; i < 128; i++){
130 if(state->exclusive_tag_array[i] == addr){
131 state->exclusive_tag_array[i] = 0xffffffff;
132 //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr);
133 return;
134 }
135 }
136 #endif
137 state->exclusive_tag = 0xFFFFFFFF;
138}
139
140
141unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper)
142{
143// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
144 unsigned int immed_8 = BITS(sht_oper, 0, 7);
145 unsigned int rotate_imm = BITS(sht_oper, 8, 11);
146// DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8);
147// DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm);
148 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
149// DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand);
150 /* set c flag */
151 if (rotate_imm == 0)
152 cpu->shifter_carry_out = cpu->CFlag;
153 else
154 cpu->shifter_carry_out = BIT(shifter_operand, 31);
155 return shifter_operand;
156}
157
158unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper)
159{
160// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
161 unsigned int rm = CHECK_READ_REG15(cpu, RM);
162 //if (RM == 15) rm += 8;
163 unsigned int shifter_operand = rm;
164 cpu->shifter_carry_out = cpu->CFlag;
165 return shifter_operand;
166}
167
168unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper)
169{
170// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
171 int shift_imm = BITS(sht_oper, 7, 11);
172 unsigned int rm = CHECK_READ_REG15(cpu, RM);
173 //if (RM == 15) rm += 8;
174 unsigned int shifter_operand;
175 if (shift_imm == 0) {
176 shifter_operand = rm;
177 cpu->shifter_carry_out = cpu->CFlag;
178 } else {
179 shifter_operand = rm << shift_imm;
180 cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
181 }
182 return shifter_operand;
183}
184
185unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper)
186{
187// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
188 int shifter_operand;
189 unsigned int rm = CHECK_READ_REG15(cpu, RM);
190 unsigned int rs = CHECK_READ_REG15(cpu, RS);
191 //if (RM == 15) rm += 8;
192 //if (RS == 15) rs += 8;
193 if (BITS(rs, 0, 7) == 0) {
194 shifter_operand = rm;
195 cpu->shifter_carry_out = cpu->CFlag;
196 } else if (BITS(rs, 0, 7) < 32) {
197 shifter_operand = rm << BITS(rs, 0, 7);
198 cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
199 } else if (BITS(rs, 0, 7) == 32) {
200 shifter_operand = 0;
201 cpu->shifter_carry_out = BIT(rm, 0);
202 } else {
203 shifter_operand = 0;
204 cpu->shifter_carry_out = 0;
205 }
206 return shifter_operand;
207}
208
209unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
210{
211// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
212 //unsigned int rm = cpu->Reg[RM];
213 unsigned int rm = CHECK_READ_REG15(cpu, RM);
214 //if (RM == 15) rm += 8;
215 unsigned int shifter_operand;
216 int shift_imm = BITS(sht_oper, 7, 11);
217 if (shift_imm == 0) {
218 shifter_operand = 0;
219 cpu->shifter_carry_out = BIT(rm, 31);
220 } else {
221 shifter_operand = rm >> shift_imm;
222 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
223 }
224 return shifter_operand;
225}
226
227unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
228{
229// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
230 unsigned int rs = CHECK_READ_REG15(cpu, RS);
231 unsigned int rm = CHECK_READ_REG15(cpu, RM);
232 //if (RS == 15) rs += 8;
233 //if (RM == 15) rm += 8;
234 unsigned int shifter_operand;
235 if (BITS(rs, 0, 7) == 0) {
236 shifter_operand = rm;
237 cpu->shifter_carry_out = cpu->CFlag;
238 } else if (BITS(rs, 0, 7) < 32) {
239 shifter_operand = rm >> BITS(rs, 0, 7);
240 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
241 } else if (BITS(rs, 0, 7) == 32) {
242 shifter_operand = 0;
243 cpu->shifter_carry_out = BIT(rm, 31);
244 } else {
245 shifter_operand = 0;
246 cpu->shifter_carry_out = 0;
247 }
248 return shifter_operand;
249}
250
251unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
252{
253// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
254 //unsigned int rm = cpu->Reg[RM];
255 unsigned int rm = CHECK_READ_REG15(cpu, RM);
256 //if (RM == 15) rm += 8;
257 unsigned int shifter_operand;
258 int shift_imm = BITS(sht_oper, 7, 11);
259 if (shift_imm == 0) {
260 if (BIT(rm, 31)) {
261 shifter_operand = 0;
262 cpu->shifter_carry_out = BIT(rm, 31);
263 } else {
264 shifter_operand = 0xFFFFFFFF;
265 cpu->shifter_carry_out = BIT(rm, 31);
266 }
267 } else {
268 shifter_operand = static_cast<int>(rm) >> shift_imm;
269 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
270 }
271 return shifter_operand;
272}
273
274unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
275{
276// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
277 //unsigned int rs = cpu->Reg[RS];
278 unsigned int rs = CHECK_READ_REG15(cpu, RS);
279 //unsigned int rm = cpu->Reg[RM];
280 unsigned int rm = CHECK_READ_REG15(cpu, RM);
281 //if (RS == 15) rs += 8;
282 //if (RM == 15) rm += 8;
283 unsigned int shifter_operand;
284 if (BITS(rs, 0, 7) == 0) {
285 shifter_operand = rm;
286 cpu->shifter_carry_out = cpu->CFlag;
287 } else if (BITS(rs, 0, 7) < 32) {
288 shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
289 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
290 } else {
291 if (BIT(rm, 31) == 0) {
292 shifter_operand = 0;
293 } else
294 shifter_operand = 0xffffffff;
295 cpu->shifter_carry_out = BIT(rm, 31);
296 }
297 return shifter_operand;
298}
299
300unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
301{
302// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
303 unsigned int shifter_operand;
304 //unsigned int rm = cpu->Reg[RM];
305 unsigned int rm = CHECK_READ_REG15(cpu, RM);
306 //if (RM == 15) rm += 8;
307 int shift_imm = BITS(sht_oper, 7, 11);
308 if (shift_imm == 0) {
309 shifter_operand = (cpu->CFlag << 31) |
310 (rm >> 1);
311 cpu->shifter_carry_out = BIT(rm, 0);
312 } else {
313 shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
314 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
315 }
316 return shifter_operand;
317}
318
319unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
320{
321// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
322 unsigned int rm = CHECK_READ_REG15(cpu, RM);
323 //if (RM == 15) rm += 8;
324 unsigned int rs = CHECK_READ_REG15(cpu, RS);
325 //if (RS == 15) rs += 8;
326 unsigned int shifter_operand;
327 if (BITS(rs, 0, 7) == 0) {
328 shifter_operand = rm;
329 cpu->shifter_carry_out = cpu->CFlag;
330 } else if (BITS(rs, 0, 4) == 0) {
331 shifter_operand = rm;
332 cpu->shifter_carry_out = BIT(rm, 31);
333 } else {
334 shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
335 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
336 }
337 #if 0
338 if (cpu->icounter >= 20371544) {
339 DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
340 DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS);
341 DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]);
342 }
343 #endif
344 return shifter_operand;
345}
346
347//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu);
348typedef struct _MiscImmeData {
349 unsigned int U;
350 unsigned int Rn;
351 unsigned int offset_8;
352} MiscLSData;
353
354typedef struct _MiscRegData {
355 unsigned int U;
356 unsigned int Rn;
357 unsigned int Rm;
358} MiscRegData;
359
360typedef struct _MiscImmePreIdx {
361 unsigned int offset_8;
362 unsigned int U;
363 unsigned int Rn;
364} MiscImmePreIdx;
365
366typedef struct _MiscRegPreIdx {
367 unsigned int U;
368 unsigned int Rn;
369 unsigned int Rm;
370} MiscRegPreIdx;
371
372typedef struct _MiscImmePstIdx {
373 unsigned int offset_8;
374 unsigned int U;
375 unsigned int Rn;
376} MIscImmePstIdx;
377
378typedef struct _MiscRegPstIdx {
379 unsigned int Rn;
380 unsigned int Rm;
381 unsigned int U;
382} MiscRegPstIdx;
383
384typedef struct _LSWordorUnsignedByte {
385} LDnST;
386
387#if USER_MODE_OPT
388static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){
389 switch(size) {
390 case 8:
391 value = Memory::Read8(virt_addr);
392 break;
393 case 16:
394 value = Memory::Read16(virt_addr);
395 break;
396 case 32:
397 value = Memory::Read32(virt_addr);
398 break;
399 }
400 return NO_FAULT;
401}
402
403//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size)
404static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size)
405{
406 switch(size) {
407 case 8:
408 Memory::Write8(virt_addr, value & 0xff);
409 break;
410 case 16:
411 Memory::Write16(virt_addr, value & 0xffff);
412 break;
413 case 32:
414 Memory::Write32(virt_addr, value);
415 break;
416 }
417 return NO_FAULT;
418}
419
420static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){
421 *phys_addr = virt_addr;
422 return NO_FAULT;
423}
424
425#else
426fault_t interpreter_read_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size);
427fault_t interpreter_write_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size);
428fault_t interpreter_fetch(cpu_t *cpu, addr_t virt_addr, uint32_t &value, uint32_t size);
429fault_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);
430#endif
431
432typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw);
433
434typedef struct _ldst_inst {
435 unsigned int inst;
436 get_addr_fp_t get_addr;
437} ldst_inst;
438#define DEBUG_MSG DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__); \
439 DEBUG_LOG(ARM11, "inst is %x\n", inst); \
440 CITRA_IGNORE_EXIT(0)
441
442int CondPassed(arm_processor *cpu, unsigned int cond);
443#define LnSWoUB(s) glue(LnSWoUB, s)
444#define MLnS(s) glue(MLnS, s)
445#define LdnStM(s) glue(LdnStM, s)
446
447#define W_BIT BIT(inst, 21)
448#define U_BIT BIT(inst, 23)
449#define I_BIT BIT(inst, 25)
450#define P_BIT BIT(inst, 24)
451#define OFFSET_12 BITS(inst, 0, 11)
452fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
453{
454 unsigned int Rn = BITS(inst, 16, 19);
455 unsigned int addr;
456 fault_t fault;
457 if (U_BIT) {
458 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
459 } else {
460 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
461 }
462 //if (Rn == 15) rn += 8;
463 virt_addr = addr;
464 fault = check_address_validity(cpu, addr, &phys_addr, rw);
465 return fault;
466// return addr;
467}
468
469fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
470{
471 fault_t fault;
472 unsigned int Rn = BITS(inst, 16, 19);
473 unsigned int Rm = BITS(inst, 0, 3);
474 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
475 //if (Rn == 15) rn += 8;
476 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
477 //if (Rm == 15) rm += 8;
478 unsigned int addr;
479 if (U_BIT) {
480 addr = rn + rm;
481 } else {
482 addr = rn - rm;
483 }
484 virt_addr = addr;
485 fault = check_address_validity(cpu, addr, &phys_addr, rw);
486 return fault;
487}
488
489fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
490{
491 fault_t fault;
492 unsigned int Rn = BITS(inst, 16, 19);
493 unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
494 //if (Rn == 15) addr += 8;
495
496 virt_addr = addr;
497 fault = check_address_validity(cpu, addr, &phys_addr, rw);
498 if (fault) return fault;
499
500 if (U_BIT) {
501 cpu->Reg[Rn] += OFFSET_12;
502 } else {
503 cpu->Reg[Rn] -= OFFSET_12;
504 }
505 return fault;
506}
507
508fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
509{
510 fault_t fault;
511 unsigned int Rn = BITS(inst, 16, 19);
512 unsigned int addr;
513 if (U_BIT) {
514 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
515 } else {
516 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
517 }
518 #if 0
519 if (Rn == 15) {
520 addr += 8;
521 }
522 #endif
523
524 virt_addr = addr;
525 fault = check_address_validity(cpu, addr, &phys_addr, rw);
526 if (fault) return fault;
527
528 if (CondPassed(cpu, BITS(inst, 28, 31))) {
529 cpu->Reg[Rn] = addr;
530 }
531 return fault;
532}
533
534fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
535{
536 fault_t fault;
537 unsigned int addr;
538 unsigned int Rn = BITS(inst, 16, 19);
539 unsigned int Rm = BITS(inst, 0, 3);
540 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
541 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
542 //if (Rn == 15) rn += 8;
543 //if (Rm == 15) rm += 8;
544 if (U_BIT) {
545 addr = rn + rm;
546 } else
547 addr = rn - rm;
548 if(BIT(inst, 20)){ /* L BIT */
549 }
550 if(BIT(inst, 6)){ /* Sign Bit */
551 }
552 if(BIT(inst, 5)){ /* Half Bit */
553 }
554
555 virt_addr = addr;
556 fault = check_address_validity(cpu, addr, &phys_addr, rw);
557 if (fault) return fault;
558
559 if (CondPassed(cpu, BITS(inst, 28, 31))) {
560 cpu->Reg[Rn] = addr;
561 }
562 return fault;
563}
564
565fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
566{
567 fault_t fault;
568 unsigned int Rn = BITS(inst, 16, 19);
569 unsigned int Rm = BITS(inst, 0, 3);
570 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
571 //if (Rn == 15) rn += 8;
572 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
573 //if (Rm == 15) rm += 8;
574 unsigned int addr;
575 if (U_BIT) {
576 addr = rn + rm;
577 } else {
578 addr = rn - rm;
579 }
580 virt_addr = addr;
581 fault = check_address_validity(cpu, addr, &phys_addr, rw);
582 if(fault)
583 return fault;
584 if (CondPassed(cpu, BITS(inst, 28, 31))) {
585 cpu->Reg[Rn] = addr;
586 }
587 return fault;
588}
589fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
590{
591 fault_t fault;
592 unsigned int shift = BITS(inst, 5, 6);
593 unsigned int shift_imm = BITS(inst, 7, 11);
594 unsigned int Rn = BITS(inst, 16, 19);
595 unsigned int Rm = BITS(inst, 0, 3);
596 unsigned int index;
597 unsigned int addr;
598
599 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
600 //if (Rm == 15) rm += 8;
601 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
602 //if (Rn == 15) rn += 8;
603 switch (shift) {
604 case 0:
605 //DEBUG_MSG;
606 index = rm << shift_imm;
607 break;
608 case 1:
609// DEBUG_MSG;
610 if (shift_imm == 0) {
611 index = 0;
612 } else {
613 index = rm >> shift_imm;
614 }
615 break;
616 case 2:
617 DEBUG_MSG;
618 break;
619 case 3:
620 DEBUG_MSG;
621 break;
622 }
623 if (U_BIT) {
624 addr = rn + index;
625 } else
626 addr = rn - index;
627 virt_addr = addr;
628 fault = check_address_validity(cpu, addr, &phys_addr, rw);
629 if(fault)
630 return fault;
631 if (CondPassed(cpu, BITS(inst, 28, 31))) {
632 cpu->Reg[Rn] = addr;
633 }
634
635 return fault;
636}
637
638fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
639{
640 fault_t fault;
641 unsigned int shift = BITS(inst, 5, 6);
642 unsigned int shift_imm = BITS(inst, 7, 11);
643 unsigned int Rn = BITS(inst, 16, 19);
644 unsigned int Rm = BITS(inst, 0, 3);
645 unsigned int index;
646 unsigned int addr;
647
648 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
649 //if (Rm == 15) rm += 8;
650 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
651 //if (Rn == 15) rn += 8;
652 addr = rn;
653 switch (shift) {
654 case 0:
655 //DEBUG_MSG;
656 index = rm << shift_imm;
657 break;
658 case 1:
659// DEBUG_MSG;
660 if (shift_imm == 0) {
661 index = 0;
662 } else {
663 index = rm >> shift_imm;
664 }
665 break;
666 case 2:
667 DEBUG_MSG;
668 break;
669 case 3:
670 DEBUG_MSG;
671 break;
672 }
673 virt_addr = addr;
674 fault = check_address_validity(cpu, addr, &phys_addr, rw);
675 if(fault)
676 return fault;
677 if (CondPassed(cpu, BITS(inst, 28, 31))) {
678 if (U_BIT)
679 cpu->Reg[Rn] += index;
680 else
681 cpu->Reg[Rn] -= index;
682 }
683
684 return fault;
685}
686
687fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
688{
689 fault_t fault;
690 unsigned int Rn = BITS(inst, 16, 19);
691 unsigned int Rm = BITS(inst, 0, 3);
692 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
693 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
694
695 unsigned int addr = rn;
696 virt_addr = addr;
697 fault = check_address_validity(cpu, addr, &phys_addr, rw);
698 if (fault) return fault;
699
700 if (CondPassed(cpu, BITS(inst, 28, 31))) {
701 if (U_BIT) {
702 cpu->Reg[Rn] += rm;
703 } else {
704 cpu->Reg[Rn] -= rm;
705 }
706 }
707 return fault;
708}
709
710fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
711{
712 fault_t fault;
713 unsigned int immedL = BITS(inst, 0, 3);
714 unsigned int immedH = BITS(inst, 8, 11);
715
716 unsigned int Rn = BITS(inst, 16, 19);
717 unsigned int addr;
718
719 unsigned int offset_8 = (immedH << 4) | immedL;
720 if (U_BIT) {
721 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
722 } else
723 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
724 #if 0
725 if (Rn == 15) {
726 addr += 8;
727 }
728 #endif
729 virt_addr = addr;
730 fault = check_address_validity(cpu, addr, &phys_addr, rw);
731 return fault;
732}
733
734fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
735{
736 fault_t fault;
737 unsigned int addr;
738 unsigned int Rn = BITS(inst, 16, 19);
739 unsigned int Rm = BITS(inst, 0, 3);
740 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
741 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
742 //if (Rn == 15) rn += 8;
743 //if (Rm == 15) rm += 8;
744 if (U_BIT) {
745 addr = rn + rm;
746 } else
747 addr = rn - rm;
748 if(BIT(inst, 20)){ /* L BIT */
749 }
750 if(BIT(inst, 6)){ /* Sign Bit */
751 }
752 if(BIT(inst, 5)){ /* Half Bit */
753 }
754 virt_addr = addr;
755 fault = check_address_validity(cpu, addr, &phys_addr, rw);
756 return fault;
757}
758
759fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
760{
761 fault_t fault;
762 unsigned int Rn = BITS(inst, 16, 19);
763 unsigned int immedH = BITS(inst, 8, 11);
764 unsigned int immedL = BITS(inst, 0, 3);
765 unsigned int addr;
766 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
767 //if (Rn == 15) rn += 8;
768
769// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
770 unsigned int offset_8 = (immedH << 4) | immedL;
771 if (U_BIT) {
772 addr = rn + offset_8;
773 } else
774 addr = rn - offset_8;
775
776 virt_addr = addr;
777 fault = check_address_validity(cpu, addr, &phys_addr, rw);
778 if (fault) return fault;
779
780 if (CondPassed(cpu, BITS(inst, 28, 31))) {
781 cpu->Reg[Rn] = addr;
782 }
783 return fault;
784}
785
786fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
787{
788 fault_t fault;
789 unsigned int Rn = BITS(inst, 16, 19);
790 unsigned int immedH = BITS(inst, 8, 11);
791 unsigned int immedL = BITS(inst, 0, 3);
792 unsigned int addr;
793 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
794 addr = rn;
795
796 virt_addr = addr;
797 fault = check_address_validity(cpu, addr, &phys_addr, rw);
798 if (fault) return fault;
799
800 if (CondPassed(cpu, BITS(inst, 28, 31))) {
801 unsigned int offset_8 = (immedH << 4) | immedL;
802 if (U_BIT) {
803 rn += offset_8;
804 } else {
805 rn -= offset_8;
806 }
807 cpu->Reg[Rn] = rn;
808 }
809
810 return fault;
811}
812fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
813{
814 fault_t fault;
815 unsigned int Rn = BITS(inst, 16, 19);
816 unsigned int Rm = BITS(inst, 0, 3);
817 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
818 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
819
820 unsigned int addr = rn;
821 virt_addr = addr;
822 fault = check_address_validity(cpu, addr, &phys_addr, rw);
823 if (fault) return fault;
824
825 if (CondPassed(cpu, BITS(inst, 28, 31))) {
826 if (U_BIT) {
827 cpu->Reg[Rn] += rm;
828 } else {
829 cpu->Reg[Rn] -= rm;
830 }
831 }
832 return fault;
833}
834
835fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
836{
837 fault_t fault;
838 unsigned int Rn = BITS(inst, 16, 19);
839 unsigned int i = BITS(inst, 0, 15);
840 int count = 0;
841 while(i) {
842 if(i & 1) count ++;
843 i = i >> 1;
844 }
845 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
846 //if (Rn == 15) rn += 8;
847 unsigned int start_addr = rn - count * 4;
848 unsigned int end_addr = rn - 4;
849
850 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
851 virt_addr = end_addr;
852 if (fault) return fault;
853
854 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
855 virt_addr = start_addr;
856 if (fault) return fault;
857
858 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
859 cpu->Reg[Rn] -= count * 4;
860 }
861
862 return fault;
863}
864
865fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
866{
867 fault_t fault;
868 unsigned int Rn = BITS(inst, 16, 19);
869 unsigned int i = BITS(inst, 0, 15);
870 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
871 //if (Rn == 15) rn += 8;
872 int count = 0;
873 while(i) {
874 if(i & 1) count ++;
875 i = i >> 1;
876 }
877
878 unsigned int start_addr = rn + 4;
879 unsigned int end_addr = rn + count * 4;
880
881 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
882 virt_addr = end_addr;
883 if (fault) return fault;
884
885 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
886 virt_addr = start_addr;
887 if (fault) return fault;
888
889 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
890 cpu->Reg[Rn] += count * 4;
891 }
892 return fault;
893}
894
895fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
896{
897 fault_t fault;
898 unsigned int Rn = BITS(inst, 16, 19);
899 unsigned int i = BITS(inst, 0, 15);
900 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
901 int count = 0;
902 while(i) {
903 if(i & 1) count ++;
904 i = i >> 1;
905 }
906 //if (Rn == 15) rn += 8;
907 unsigned int start_addr = rn;
908 unsigned int end_addr = rn + count * 4 - 4;
909
910 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
911 virt_addr = end_addr;
912 if (fault) return fault;
913
914 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
915 virt_addr = start_addr;
916 if (fault) return fault;
917
918 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
919 cpu->Reg[Rn] += count * 4;
920 }
921 return fault;
922}
923
924fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
925{
926 fault_t fault;
927 unsigned int Rn = BITS(inst, 16, 19);
928 unsigned int i = BITS(inst, 0, 15);
929 int count = 0;
930 while(i) {
931 if(i & 1) count ++;
932 i = i >> 1;
933 }
934 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
935 //if (Rn == 15) rn += 8;
936 unsigned int start_addr = rn - count * 4 + 4;
937 unsigned int end_addr = rn;
938
939 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
940 virt_addr = end_addr;
941 if (fault) return fault;
942
943 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
944 if (fault) return fault;
945 virt_addr = start_addr;
946
947 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
948 cpu->Reg[Rn] -= count * 4;
949 }
950 return fault;
951}
952
953fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
954{
955 fault_t fault;
956 unsigned int shift = BITS(inst, 5, 6);
957 unsigned int shift_imm = BITS(inst, 7, 11);
958 unsigned int Rn = BITS(inst, 16, 19);
959 unsigned int Rm = BITS(inst, 0, 3);
960 unsigned int index;
961 unsigned int addr;
962
963 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
964 //if (Rm == 15) rm += 8;
965 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
966 //if (Rn == 15) rn += 8;
967 switch (shift) {
968 case 0:
969 //DEBUG_MSG;
970 index = rm << shift_imm;
971 break;
972 case 1:
973// DEBUG_MSG;
974 if (shift_imm == 0) {
975 index = 0;
976 } else {
977 index = rm >> shift_imm;
978 }
979 break;
980 case 2:
981 if (shift_imm == 0){ /* ASR #32 */
982 if (rm >> 31)
983 index = 0xFFFFFFFF;
984 else
985 index = 0;
986 }
987 else {
988 index = static_cast<int>(rm) >> shift_imm;
989 }
990 break;
991 case 3:
992 DEBUG_MSG;
993 break;
994 }
995 if (U_BIT) {
996 addr = rn + index;
997 } else
998 addr = rn - index;
999 virt_addr = addr;
1000 fault = check_address_validity(cpu, addr, &phys_addr, rw);
1001 return fault;
1002}
1003
1004#define ISNEG(n) (n < 0)
1005#define ISPOS(n) (n >= 0)
1006
1007//enum {
1008// COND = (1 << 0),
1009// NON_BRANCH = (1 << 1),
1010// DIRECT_BRANCH = (1 << 2),
1011// INDIRECT_BRANCH = (1 << 3),
1012// CALL = (1 << 4),
1013// RET = (1 << 5),
1014// END_OF_PAGE = (1 << 6),
1015// THUMB = (1 << 7)
1016//};
1017
1018typedef struct _arm_inst {
1019 unsigned int idx;
1020 unsigned int cond;
1021 int br;
1022 int load_r15;
1023 char component[0];
1024} arm_inst;
1025
1026typedef struct _adc_inst {
1027 unsigned int I;
1028 unsigned int S;
1029 unsigned int Rn;
1030 unsigned int Rd;
1031 unsigned int shifter_operand;
1032 shtop_fp_t shtop_func;
1033} adc_inst;
1034
1035typedef struct _add_inst {
1036 unsigned int I;
1037 unsigned int S;
1038 unsigned int Rn;
1039 unsigned int Rd;
1040 unsigned int shifter_operand;
1041 shtop_fp_t shtop_func;
1042} add_inst;
1043
1044typedef struct _orr_inst {
1045 unsigned int I;
1046 unsigned int S;
1047 unsigned int Rn;
1048 unsigned int Rd;
1049 unsigned int shifter_operand;
1050 shtop_fp_t shtop_func;
1051} orr_inst;
1052
1053typedef struct _and_inst {
1054 unsigned int I;
1055 unsigned int S;
1056 unsigned int Rn;
1057 unsigned int Rd;
1058 unsigned int shifter_operand;
1059 shtop_fp_t shtop_func;
1060} and_inst;
1061
1062typedef struct _eor_inst {
1063 unsigned int I;
1064 unsigned int S;
1065 unsigned int Rn;
1066 unsigned int Rd;
1067 unsigned int shifter_operand;
1068 shtop_fp_t shtop_func;
1069} eor_inst;
1070
1071typedef struct _bbl_inst {
1072 unsigned int L;
1073 int signed_immed_24;
1074 unsigned int next_addr;
1075 unsigned int jmp_addr;
1076} bbl_inst;
1077
1078typedef struct _bx_inst {
1079 unsigned int Rm;
1080} bx_inst;
1081
1082typedef struct _blx_inst {
1083 union {
1084 int32_t signed_immed_24;
1085 uint32_t Rm;
1086 } val;
1087 unsigned int inst;
1088} blx_inst;
1089
1090typedef struct _clz_inst {
1091 unsigned int Rm;
1092 unsigned int Rd;
1093} clz_inst;
1094
1095typedef struct _cps_inst {
1096 unsigned int imod0;
1097 unsigned int imod1;
1098 unsigned int mmod;
1099 unsigned int A, I, F;
1100 unsigned int mode;
1101} cps_inst;
1102
1103typedef struct _clrex_inst {
1104} clrex_inst;
1105
1106typedef struct _cpy_inst {
1107 unsigned int Rm;
1108 unsigned int Rd;
1109} cpy_inst;
1110
1111typedef struct _bic_inst {
1112 unsigned int I;
1113 unsigned int S;
1114 unsigned int Rn;
1115 unsigned int Rd;
1116 unsigned int shifter_operand;
1117 shtop_fp_t shtop_func;
1118} bic_inst;
1119
1120typedef struct _sub_inst {
1121 unsigned int I;
1122 unsigned int S;
1123 unsigned int Rn;
1124 unsigned int Rd;
1125 unsigned int shifter_operand;
1126 shtop_fp_t shtop_func;
1127} sub_inst;
1128
1129typedef struct _tst_inst {
1130 unsigned int I;
1131 unsigned int S;
1132 unsigned int Rn;
1133 unsigned int Rd;
1134 unsigned int shifter_operand;
1135 shtop_fp_t shtop_func;
1136} tst_inst;
1137
1138typedef struct _cmn_inst {
1139 unsigned int I;
1140 //unsigned int S;
1141 unsigned int Rn;
1142 //unsigned int Rd;
1143 unsigned int shifter_operand;
1144 shtop_fp_t shtop_func;
1145} cmn_inst;
1146
1147typedef struct _teq_inst {
1148 unsigned int I;
1149 unsigned int Rn;
1150 unsigned int shifter_operand;
1151 shtop_fp_t shtop_func;
1152} teq_inst;
1153
1154typedef struct _stm_inst {
1155 unsigned int inst;
1156} stm_inst;
1157
1158struct bkpt_inst {
1159};
1160
1161struct blx1_inst {
1162 unsigned int addr;
1163};
1164
1165struct blx2_inst {
1166 unsigned int Rm;
1167};
1168
1169typedef struct _stc_inst {
1170} stc_inst;
1171
1172typedef struct _ldc_inst {
1173} ldc_inst;
1174
1175typedef struct _swi_inst {
1176 unsigned int num;
1177} swi_inst;
1178
1179typedef struct _cmp_inst {
1180 unsigned int I;
1181 unsigned int Rn;
1182 unsigned int shifter_operand;
1183 shtop_fp_t shtop_func;
1184} cmp_inst;
1185
1186typedef struct _mov_inst {
1187 unsigned int I;
1188 unsigned int S;
1189 unsigned int Rd;
1190 unsigned int shifter_operand;
1191 shtop_fp_t shtop_func;
1192} mov_inst;
1193
1194typedef struct _mvn_inst {
1195 unsigned int I;
1196 unsigned int S;
1197 unsigned int Rd;
1198 unsigned int shifter_operand;
1199 shtop_fp_t shtop_func;
1200} mvn_inst;
1201
1202typedef struct _rev_inst {
1203 unsigned int Rd;
1204 unsigned int Rm;
1205} rev_inst;
1206
1207typedef struct _rsb_inst {
1208 unsigned int I;
1209 unsigned int S;
1210 unsigned int Rn;
1211 unsigned int Rd;
1212 unsigned int shifter_operand;
1213 shtop_fp_t shtop_func;
1214} rsb_inst;
1215
1216typedef struct _rsc_inst {
1217 unsigned int I;
1218 unsigned int S;
1219 unsigned int Rn;
1220 unsigned int Rd;
1221 unsigned int shifter_operand;
1222 shtop_fp_t shtop_func;
1223} rsc_inst;
1224
1225typedef struct _sbc_inst {
1226 unsigned int I;
1227 unsigned int S;
1228 unsigned int Rn;
1229 unsigned int Rd;
1230 unsigned int shifter_operand;
1231 shtop_fp_t shtop_func;
1232} sbc_inst;
1233
1234typedef struct _mul_inst {
1235 unsigned int S;
1236 unsigned int Rd;
1237 unsigned int Rs;
1238 unsigned int Rm;
1239} mul_inst;
1240
1241typedef struct _smul_inst {
1242 unsigned int Rd;
1243 unsigned int Rs;
1244 unsigned int Rm;
1245 unsigned int x;
1246 unsigned int y;
1247} smul_inst;
1248
1249typedef struct _umull_inst {
1250 unsigned int S;
1251 unsigned int RdHi;
1252 unsigned int RdLo;
1253 unsigned int Rs;
1254 unsigned int Rm;
1255} umull_inst;
1256typedef struct _smlad_inst {
1257 unsigned int m;
1258 unsigned int Rm;
1259 unsigned int Rd;
1260 unsigned int Ra;
1261 unsigned int Rn;
1262} smlad_inst;
1263
1264typedef struct _smla_inst {
1265 unsigned int x;
1266 unsigned int y;
1267 unsigned int Rm;
1268 unsigned int Rd;
1269 unsigned int Rs;
1270 unsigned int Rn;
1271} smla_inst;
1272
1273typedef struct _umlal_inst {
1274 unsigned int S;
1275 unsigned int Rm;
1276 unsigned int Rs;
1277 unsigned int RdHi;
1278 unsigned int RdLo;
1279} umlal_inst;
1280
1281typedef struct _smlal_inst {
1282 unsigned int S;
1283 unsigned int Rm;
1284 unsigned int Rs;
1285 unsigned int RdHi;
1286 unsigned int RdLo;
1287} smlal_inst;
1288
1289typedef struct _mla_inst {
1290 unsigned int S;
1291 unsigned int Rn;
1292 unsigned int Rd;
1293 unsigned int Rs;
1294 unsigned int Rm;
1295} mla_inst;
1296
1297typedef struct _mrc_inst {
1298 unsigned int opcode_1;
1299 unsigned int opcode_2;
1300 unsigned int cp_num;
1301 unsigned int crn;
1302 unsigned int crm;
1303 unsigned int Rd;
1304 unsigned int inst;
1305} mrc_inst;
1306
1307typedef struct _mcr_inst {
1308 unsigned int opcode_1;
1309 unsigned int opcode_2;
1310 unsigned int cp_num;
1311 unsigned int crn;
1312 unsigned int crm;
1313 unsigned int Rd;
1314 unsigned int inst;
1315} mcr_inst;
1316
1317typedef struct _mrs_inst {
1318 unsigned int R;
1319 unsigned int Rd;
1320} mrs_inst;
1321
1322typedef struct _msr_inst {
1323 unsigned int field_mask;
1324 unsigned int R;
1325 unsigned int inst;
1326} msr_inst;
1327
1328typedef struct _pld_inst {
1329} pld_inst;
1330
1331typedef struct _sxtb_inst {
1332 unsigned int Rd;
1333 unsigned int Rm;
1334 unsigned int rotate;
1335} sxtb_inst;
1336
1337typedef struct _sxtab_inst {
1338 unsigned int Rd;
1339 unsigned int Rn;
1340 unsigned int Rm;
1341 unsigned rotate;
1342} sxtab_inst;
1343
1344typedef struct _sxtah_inst {
1345 unsigned int Rd;
1346 unsigned int Rn;
1347 unsigned int Rm;
1348 unsigned int rotate;
1349} sxtah_inst;
1350
1351typedef struct _sxth_inst {
1352 unsigned int Rd;
1353 unsigned int Rm;
1354 unsigned int rotate;
1355} sxth_inst;
1356
1357typedef struct _uxtab_inst {
1358 unsigned int Rn;
1359 unsigned int Rd;
1360 unsigned int rotate;
1361 unsigned int Rm;
1362} uxtab_inst;
1363
1364typedef struct _uxtah_inst {
1365 unsigned int Rn;
1366 unsigned int Rd;
1367 unsigned int rotate;
1368 unsigned int Rm;
1369} uxtah_inst;
1370
1371typedef struct _uxth_inst {
1372 unsigned int Rd;
1373 unsigned int Rm;
1374 unsigned int rotate;
1375} uxth_inst;
1376
1377typedef struct _cdp_inst {
1378 unsigned int opcode_1;
1379 unsigned int CRn;
1380 unsigned int CRd;
1381 unsigned int cp_num;
1382 unsigned int opcode_2;
1383 unsigned int CRm;
1384 uint32 inst;
1385}cdp_inst;
1386
1387typedef struct _uxtb_inst {
1388 unsigned int Rd;
1389 unsigned int Rm;
1390 unsigned int rotate;
1391} uxtb_inst;
1392
1393typedef struct _swp_inst {
1394 unsigned int Rn;
1395 unsigned int Rd;
1396 unsigned int Rm;
1397} swp_inst;
1398
1399typedef struct _b_2_thumb {
1400 unsigned int imm;
1401}b_2_thumb;
1402typedef struct _b_cond_thumb {
1403 unsigned int imm;
1404 unsigned int cond;
1405}b_cond_thumb;
1406
1407typedef struct _bl_1_thumb {
1408 unsigned int imm;
1409}bl_1_thumb;
1410typedef struct _bl_2_thumb {
1411 unsigned int imm;
1412}bl_2_thumb;
1413typedef struct _blx_1_thumb {
1414 unsigned int imm;
1415 unsigned int instr;
1416}blx_1_thumb;
1417
1418typedef arm_inst * ARM_INST_PTR;
1419
1420#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
1421char inst_buf[CACHE_BUFFER_SIZE];
1422int top = 0;
1423inline void *AllocBuffer(unsigned int size)
1424{
1425 int start = top;
1426 top += size;
1427 if (top > CACHE_BUFFER_SIZE) {
1428 DEBUG_LOG(ARM11, "inst_buf is full\n");
1429 CITRA_IGNORE_EXIT(-1);
1430 }
1431 return (void *)&inst_buf[start];
1432}
1433
1434int CondPassed(arm_processor *cpu, unsigned int cond)
1435{
1436 #define NFLAG cpu->NFlag
1437 #define ZFLAG cpu->ZFlag
1438 #define CFLAG cpu->CFlag
1439 #define VFLAG cpu->VFlag
1440 int temp;
1441 switch (cond) {
1442 case 0x0:
1443 temp = ZFLAG;
1444 break;
1445 case 0x1: /* NE */
1446 temp = !ZFLAG;
1447 break;
1448 case 0x6: /* VS */
1449 temp = VFLAG;
1450 break;
1451 case 0x7: /* VC */
1452 temp = !VFLAG;
1453 break;
1454 case 0x4: /* MI */
1455 temp = NFLAG;
1456 break;
1457 case 0x5: /* PL */
1458 temp = !NFLAG;
1459 break;
1460 case 0x2: /* CS */
1461 temp = CFLAG;
1462 break;
1463 case 0x3: /* CC */
1464 temp = !CFLAG;
1465 break;
1466 case 0x8: /* HI */
1467 temp = (CFLAG && !ZFLAG);
1468 break;
1469 case 0x9: /* LS */
1470 temp = (!CFLAG || ZFLAG);
1471 break;
1472 case 0xa: /* GE */
1473 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
1474 break;
1475 case 0xb: /* LT */
1476 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
1477 break;
1478 case 0xc: /* GT */
1479 temp = ((!NFLAG && !VFLAG && !ZFLAG)
1480 || (NFLAG && VFLAG && !ZFLAG));
1481 break;
1482 case 0xd: /* LE */
1483 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
1484 || ZFLAG;
1485 break;
1486 case 0xe: /* AL */
1487 temp = 1;
1488 break;
1489 case 0xf:
1490// DEBUG_LOG(ARM11, "inst is %x\n");
1491// DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter);
1492// CITRA_IGNORE_EXIT(-1);
1493 temp = 1;
1494 break;
1495 }
1496 return temp;
1497}
1498
1499enum DECODE_STATUS {
1500 DECODE_SUCCESS,
1501 DECODE_FAILURE
1502};
1503
1504int decode_arm_instr(uint32_t instr, int32_t *idx);
1505
1506shtop_fp_t get_shtop(unsigned int inst)
1507{
1508 if (BIT(inst, 25)) {
1509 return DPO(Immediate);
1510 } else if (BITS(inst, 4, 11) == 0) {
1511 return DPO(Register);
1512 } else if (BITS(inst, 4, 6) == 0) {
1513 return DPO(LogicalShiftLeftByImmediate);
1514 } else if (BITS(inst, 4, 7) == 1) {
1515 return DPO(LogicalShiftLeftByRegister);
1516 } else if (BITS(inst, 4, 6) == 2) {
1517 return DPO(LogicalShiftRightByImmediate);
1518 } else if (BITS(inst, 4, 7) == 3) {
1519 return DPO(LogicalShiftRightByRegister);
1520 } else if (BITS(inst, 4, 6) == 4) {
1521 return DPO(ArithmeticShiftRightByImmediate);
1522 } else if (BITS(inst, 4, 7) == 5) {
1523 return DPO(ArithmeticShiftRightByRegister);
1524 } else if (BITS(inst, 4, 6) == 6) {
1525 return DPO(RotateRightByImmediate);
1526 } else if (BITS(inst, 4, 7) == 7) {
1527 return DPO(RotateRightByRegister);
1528 }
1529 return NULL;
1530}
1531
1532get_addr_fp_t get_calc_addr_op(unsigned int inst)
1533{
1534 /* 1 */
1535 if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
1536// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1537 return LnSWoUB(ImmediateOffset);
1538 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1539// DEBUG_MSG;
1540// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1541 return LnSWoUB(RegisterOffset);
1542 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1543// DEBUG_MSG;
1544// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1545 return LnSWoUB(ScaledRegisterOffset);
1546 } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
1547// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1548 return LnSWoUB(ImmediatePreIndexed);
1549 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
1550 return LnSWoUB(RegisterPreIndexed);
1551 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
1552 return LnSWoUB(ScaledRegisterPreIndexed);
1553 } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
1554 return LnSWoUB(ImmediatePostIndexed);
1555 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1556// DEBUG_MSG;
1557 return LnSWoUB(RegisterPostIndexed);
1558 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1559 return LnSWoUB(ScaledRegisterPostIndexed);
1560// DEBUG_MSG;
1561 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1562 /* 2 */
1563// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1564 return MLnS(ImmediateOffset);
1565// DEBUG_MSG;
1566 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1567// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
1568 return MLnS(RegisterOffset);
1569// DEBUG_MSG;
1570 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1571// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
1572 return MLnS(ImmediatePreIndexed);
1573// DEBUG_MSG;
1574 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1575 return MLnS(RegisterPreIndexed);
1576 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1577// DEBUG_MSG;
1578 return MLnS(ImmediatePostIndexed);
1579 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1580 //DEBUG_MSG;
1581 return MLnS(RegisterPostIndexed);
1582 } else if (BITS(inst, 23, 27) == 0x11) {
1583 /* 3 */
1584// DEBUG_MSG;
1585// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1586 return LdnStM(IncrementAfter);
1587 } else if (BITS(inst, 23, 27) == 0x13) {
1588// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1589 return LdnStM(IncrementBefore);
1590// DEBUG_MSG;
1591 } else if (BITS(inst, 23, 27) == 0x10) {
1592// DEBUG_MSG;
1593// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1594 return LdnStM(DecrementAfter);
1595 } else if (BITS(inst, 23, 27) == 0x12) {
1596// DEBUG_MSG;
1597// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1598 return LdnStM(DecrementBefore);
1599 }
1600 #if 0
1601 DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__);
1602 DEBUG_LOG(ARM11, "inst:%x\n", inst);
1603 CITRA_IGNORE_EXIT(-1);
1604 #endif
1605 return NULL;
1606}
1607
1608#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
1609
1610#define CHECK_RN (inst_cream->Rn == 15)
1611#define CHECK_RM (inst_cream->Rm == 15)
1612#define CHECK_RS (inst_cream->Rs == 15)
1613
1614
1615ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
1616{
1617 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
1618 adc_inst *inst_cream = (adc_inst *)inst_base->component;
1619
1620 inst_base->cond = BITS(inst, 28, 31);
1621 inst_base->idx = index;
1622 inst_base->br = NON_BRANCH;
1623 inst_base->load_r15 = 0;
1624
1625 inst_cream->I = BIT(inst, 25);
1626 inst_cream->S = BIT(inst, 20);
1627 inst_cream->Rn = BITS(inst, 16, 19);
1628 inst_cream->Rd = BITS(inst, 12, 15);
1629 if (CHECK_RN)
1630 inst_base->load_r15 = 1;
1631 inst_cream->shifter_operand = BITS(inst, 0, 11);
1632 inst_cream->shtop_func = get_shtop(inst);
1633 if (inst_cream->Rd == 15) {
1634 inst_base->br = INDIRECT_BRANCH;
1635 }
1636 return inst_base;
1637}
1638ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
1639{
1640 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
1641 add_inst *inst_cream = (add_inst *)inst_base->component;
1642
1643 inst_base->cond = BITS(inst, 28, 31);
1644 inst_base->idx = index;
1645 inst_base->br = NON_BRANCH;
1646 inst_base->load_r15 = 0;
1647
1648 inst_cream->I = BIT(inst, 25);
1649 inst_cream->S = BIT(inst, 20);
1650 inst_cream->Rn = BITS(inst, 16, 19);
1651 inst_cream->Rd = BITS(inst, 12, 15);
1652 if (CHECK_RN)
1653 inst_base->load_r15 = 1;
1654 inst_cream->shifter_operand = BITS(inst, 0, 11);
1655 inst_cream->shtop_func = get_shtop(inst);
1656 if (inst_cream->Rd == 15) {
1657 inst_base->br = INDIRECT_BRANCH;
1658 }
1659 return inst_base;
1660}
1661ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
1662{
1663 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
1664 and_inst *inst_cream = (and_inst *)inst_base->component;
1665
1666 inst_base->cond = BITS(inst, 28, 31);
1667 inst_base->idx = index;
1668 inst_base->br = NON_BRANCH;
1669 inst_base->load_r15 = 0;
1670
1671 inst_cream->I = BIT(inst, 25);
1672 inst_cream->S = BIT(inst, 20);
1673 inst_cream->Rn = BITS(inst, 16, 19);
1674 inst_cream->Rd = BITS(inst, 12, 15);
1675 if (CHECK_RN)
1676 inst_base->load_r15 = 1;
1677 inst_cream->shifter_operand = BITS(inst, 0, 11);
1678 inst_cream->shtop_func = get_shtop(inst);
1679 if (inst_cream->Rd == 15)
1680 inst_base->br = INDIRECT_BRANCH;
1681 return inst_base;
1682}
1683ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
1684{
1685 #define POSBRANCH ((inst & 0x7fffff) << 2)
1686 #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
1687
1688 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
1689 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
1690
1691 inst_base->cond = BITS(inst, 28, 31);
1692 inst_base->idx = index;
1693 inst_base->br = DIRECT_BRANCH;
1694
1695 if (BIT(inst, 24))
1696 inst_base->br = CALL;
1697 if (BITS(inst, 28, 31) <= 0xe)
1698 inst_base->br |= COND;
1699
1700 inst_cream->L = BIT(inst, 24);
1701 inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
1702
1703 return inst_base;
1704}
1705ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
1706{
1707 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
1708 bic_inst *inst_cream = (bic_inst *)inst_base->component;
1709
1710 inst_base->cond = BITS(inst, 28, 31);
1711 inst_base->idx = index;
1712 inst_base->br = NON_BRANCH;
1713 inst_base->load_r15 = 0;
1714
1715 inst_cream->I = BIT(inst, 25);
1716 inst_cream->S = BIT(inst, 20);
1717 inst_cream->Rn = BITS(inst, 16, 19);
1718 inst_cream->Rd = BITS(inst, 12, 15);
1719 if (CHECK_RN)
1720 inst_base->load_r15 = 1;
1721 inst_cream->shifter_operand = BITS(inst, 0, 11);
1722 inst_cream->shtop_func = get_shtop(inst);
1723
1724 if (inst_cream->Rd == 15)
1725 inst_base->br = INDIRECT_BRANCH;
1726 return inst_base;
1727}
1728ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
1729ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
1730{
1731 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
1732 blx_inst *inst_cream = (blx_inst *)inst_base->component;
1733
1734 inst_base->cond = BITS(inst, 28, 31);
1735 inst_base->idx = index;
1736 inst_base->br = INDIRECT_BRANCH;
1737
1738 inst_cream->inst = inst;
1739 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
1740 inst_cream->val.Rm = BITS(inst, 0, 3);
1741 } else {
1742 inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
1743 //DEBUG_LOG(ARM11, " blx inst is %x\n", inst);
1744 //CITRA_IGNORE_EXIT(-1);
1745// DEBUG_MSG;
1746 }
1747
1748 return inst_base;
1749}
1750ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
1751{
1752 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
1753 bx_inst *inst_cream = (bx_inst *)inst_base->component;
1754
1755 inst_base->cond = BITS(inst, 28, 31);
1756 inst_base->idx = index;
1757 inst_base->br = INDIRECT_BRANCH;
1758
1759 inst_cream->Rm = BITS(inst, 0, 3);
1760
1761 return inst_base;
1762}
1763ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
1764ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
1765 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
1766 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
1767 inst_base->cond = BITS(inst, 28, 31);
1768 inst_base->idx = index;
1769 inst_base->br = NON_BRANCH;
1770 inst_base->load_r15 = 0;
1771
1772 inst_cream->CRm = BITS(inst, 0, 3);
1773 inst_cream->CRd = BITS(inst, 12, 15);
1774 inst_cream->CRn = BITS(inst, 16, 19);
1775 inst_cream->cp_num = BITS(inst, 8, 11);
1776 inst_cream->opcode_2 = BITS(inst, 5, 7);
1777 inst_cream->opcode_1 = BITS(inst, 20, 23);
1778 inst_cream->inst = inst;
1779
1780 DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index);
1781 return inst_base;
1782}
1783ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
1784{
1785 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
1786 inst_base->cond = BITS(inst, 28, 31);
1787 inst_base->idx = index;
1788 inst_base->br = NON_BRANCH;
1789
1790 return inst_base;
1791}
1792ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
1793{
1794 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
1795 clz_inst *inst_cream = (clz_inst *)inst_base->component;
1796
1797 inst_base->cond = BITS(inst, 28, 31);
1798 inst_base->idx = index;
1799 inst_base->br = NON_BRANCH;
1800 inst_base->load_r15 = 0;
1801
1802 inst_cream->Rm = BITS(inst, 0, 3);
1803 inst_cream->Rd = BITS(inst, 12, 15);
1804 if (CHECK_RM)
1805 inst_base->load_r15 = 1;
1806
1807 return inst_base;
1808}
1809ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
1810{
1811 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
1812 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
1813
1814 inst_base->cond = BITS(inst, 28, 31);
1815 inst_base->idx = index;
1816 inst_base->br = NON_BRANCH;
1817 inst_base->load_r15 = 0;
1818
1819 inst_cream->I = BIT(inst, 25);
1820 //inst_cream->S = BIT(inst, 20);
1821 inst_cream->Rn = BITS(inst, 16, 19);
1822 //inst_cream->Rd = BITS(inst, 12, 15);
1823 if (CHECK_RN)
1824 inst_base->load_r15 = 1;
1825 inst_cream->shifter_operand = BITS(inst, 0, 11);
1826 inst_cream->shtop_func = get_shtop(inst);
1827 return inst_base;
1828}
1829ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
1830{
1831 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
1832 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
1833
1834 inst_base->cond = BITS(inst, 28, 31);
1835 inst_base->idx = index;
1836 inst_base->br = NON_BRANCH;
1837 inst_base->load_r15 = 0;
1838
1839 inst_cream->I = BIT(inst, 25);
1840 inst_cream->Rn = BITS(inst, 16, 19);
1841 if (CHECK_RN)
1842 inst_base->load_r15 = 1;
1843 inst_cream->shifter_operand = BITS(inst, 0, 11);
1844 inst_cream->shtop_func = get_shtop(inst);
1845 return inst_base;
1846}
1847ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
1848{
1849 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
1850 cps_inst *inst_cream = (cps_inst *)inst_base->component;
1851
1852 inst_base->cond = BITS(inst, 28, 31);
1853 inst_base->idx = index;
1854 inst_base->br = NON_BRANCH;
1855
1856 inst_cream->imod0 = BIT(inst, 18);
1857 inst_cream->imod1 = BIT(inst, 19);
1858 inst_cream->mmod = BIT(inst, 17);
1859 inst_cream->A = BIT(inst, 8);
1860 inst_cream->I = BIT(inst, 7);
1861 inst_cream->F = BIT(inst, 6);
1862 inst_cream->mode = BITS(inst, 0, 4);
1863
1864 return inst_base;
1865}
1866ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
1867{
1868 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
1869 mov_inst *inst_cream = (mov_inst *)inst_base->component;
1870
1871 inst_base->cond = BITS(inst, 28, 31);
1872 inst_base->idx = index;
1873 inst_base->br = NON_BRANCH;
1874
1875 inst_cream->I = BIT(inst, 25);
1876 inst_cream->S = BIT(inst, 20);
1877 inst_cream->Rd = BITS(inst, 12, 15);
1878 inst_cream->shifter_operand = BITS(inst, 0, 11);
1879 inst_cream->shtop_func = get_shtop(inst);
1880
1881 if (inst_cream->Rd == 15) {
1882 inst_base->br = INDIRECT_BRANCH;
1883 }
1884 return inst_base;
1885}
1886ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
1887{
1888 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
1889 eor_inst *inst_cream = (eor_inst *)inst_base->component;
1890
1891 inst_base->cond = BITS(inst, 28, 31);
1892 inst_base->idx = index;
1893 inst_base->br = NON_BRANCH;
1894 inst_base->load_r15 = 0;
1895
1896 inst_cream->I = BIT(inst, 25);
1897 inst_cream->S = BIT(inst, 20);
1898 inst_cream->Rn = BITS(inst, 16, 19);
1899 inst_cream->Rd = BITS(inst, 12, 15);
1900 if (CHECK_RN)
1901 inst_base->load_r15 = 1;
1902 inst_cream->shifter_operand = BITS(inst, 0, 11);
1903 inst_cream->shtop_func = get_shtop(inst);
1904 if (inst_cream->Rd == 15) {
1905 inst_base->br = INDIRECT_BRANCH;
1906 }
1907 return inst_base;
1908}
1909ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
1910{
1911 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
1912 inst_base->cond = BITS(inst, 28, 31);
1913 inst_base->idx = index;
1914 inst_base->br = NON_BRANCH;
1915
1916 return inst_base;
1917}
1918ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
1919{
1920 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1921 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1922
1923 inst_base->cond = BITS(inst, 28, 31);
1924 inst_base->idx = index;
1925 inst_base->br = NON_BRANCH;
1926
1927 inst_cream->inst = inst;
1928 inst_cream->get_addr = get_calc_addr_op(inst);
1929
1930 if (BIT(inst, 15)) {
1931 inst_base->br = INDIRECT_BRANCH;
1932 }
1933 return inst_base;
1934}
1935ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
1936{
1937 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
1938 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
1939
1940 inst_base->cond = BITS(inst, 28, 31);
1941 inst_base->idx = index;
1942 inst_base->br = NON_BRANCH;
1943 inst_base->load_r15 = 0;
1944
1945 inst_cream->Rd = BITS(inst, 12, 15);
1946 inst_cream->Rm = BITS(inst, 0, 3);
1947 inst_cream->rotate = BITS(inst, 10, 11);
1948 if (CHECK_RM)
1949 inst_base->load_r15 = 1;
1950
1951 return inst_base;
1952}
1953ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
1954{
1955 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1956 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1957
1958 inst_base->cond = BITS(inst, 28, 31);
1959 inst_base->idx = index;
1960 inst_base->br = NON_BRANCH;
1961 inst_base->load_r15 = 0;
1962
1963 inst_cream->inst = inst;
1964 inst_cream->get_addr = get_calc_addr_op(inst);
1965
1966 if (BITS(inst, 12, 15) == 15) {
1967 inst_base->br = INDIRECT_BRANCH;
1968 }
1969 return inst_base;
1970}
1971
1972ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
1973{
1974 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1975 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1976
1977 inst_base->cond = BITS(inst, 28, 31);
1978 inst_base->idx = index;
1979 inst_base->br = NON_BRANCH;
1980 inst_base->load_r15 = 0;
1981
1982 inst_cream->inst = inst;
1983 inst_cream->get_addr = get_calc_addr_op(inst);
1984
1985 if (BITS(inst, 12, 15) == 15) {
1986 inst_base->br = INDIRECT_BRANCH;
1987 }
1988 return inst_base;
1989}
1990
1991ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
1992{
1993 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
1994 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
1995
1996 inst_base->cond = BITS(inst, 28, 31);
1997 inst_base->idx = index;
1998 inst_base->br = NON_BRANCH;
1999 inst_base->load_r15 = 0;
2000
2001 inst_cream->Rd = BITS(inst, 12, 15);
2002 inst_cream->rotate = BITS(inst, 10, 11);
2003 inst_cream->Rm = BITS(inst, 0, 3);
2004 if (CHECK_RM)
2005 inst_base->load_r15 = 1;
2006
2007 return inst_base;
2008}
2009ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
2010{
2011 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
2012 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
2013
2014 inst_base->cond = BITS(inst, 28, 31);
2015 inst_base->idx = index;
2016 inst_base->br = NON_BRANCH;
2017 inst_base->load_r15 = 0;
2018
2019 inst_cream->Rn = BITS(inst, 16, 19);
2020 inst_cream->Rd = BITS(inst, 12, 15);
2021 inst_cream->rotate = BITS(inst, 10, 11);
2022 inst_cream->Rm = BITS(inst, 0, 3);
2023 if (CHECK_RM || CHECK_RN)
2024 inst_base->load_r15 = 1;
2025
2026 return inst_base;
2027}
2028ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
2029{
2030 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2031 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2032
2033 inst_base->cond = BITS(inst, 28, 31);
2034 inst_base->idx = index;
2035 inst_base->br = NON_BRANCH;
2036
2037 inst_cream->inst = inst;
2038 inst_cream->get_addr = get_calc_addr_op(inst);
2039
2040 if (BITS(inst, 12, 15) == 15) {
2041 inst_base->br = INDIRECT_BRANCH;
2042 }
2043 return inst_base;
2044}
2045ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
2046{
2047 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2048 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2049
2050 inst_base->cond = BITS(inst, 28, 31);
2051 inst_base->idx = index;
2052 inst_base->br = NON_BRANCH;
2053
2054 inst_cream->inst = inst;
2055 if (I_BIT == 0) {
2056 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2057 } else {
2058 DEBUG_MSG;
2059 }
2060 #if 0
2061 inst_cream->get_addr = get_calc_addr_op(inst);
2062 if(inst == 0x54f13001) {
2063 DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
2064 }
2065 #endif
2066
2067 if (BITS(inst, 12, 15) == 15) {
2068 inst_base->br = INDIRECT_BRANCH;
2069 }
2070 return inst_base;
2071}
2072ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
2073{
2074 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2075 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2076
2077 inst_base->cond = BITS(inst, 28, 31);
2078 inst_base->idx = index;
2079 inst_base->br = NON_BRANCH;
2080
2081 inst_cream->inst = inst;
2082 inst_cream->get_addr = get_calc_addr_op(inst);
2083
2084 return inst_base;
2085}
2086
2087ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
2088{
2089 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2090 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2091
2092 inst_base->cond = BITS(inst, 28, 31);
2093 inst_base->idx = index;
2094 inst_base->br = NON_BRANCH;
2095
2096 inst_cream->inst = inst;
2097 //inst_cream->get_addr = get_calc_addr_op(inst);
2098
2099 if (BITS(inst, 12, 15) == 15) {
2100 inst_base->br = INDIRECT_BRANCH;
2101 }
2102 return inst_base;
2103}
2104ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
2105{
2106 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2107 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2108
2109 inst_base->cond = BITS(inst, 28, 31);
2110 inst_base->idx = index;
2111 inst_base->br = NON_BRANCH;
2112
2113 inst_cream->inst = inst;
2114 inst_cream->get_addr = get_calc_addr_op(inst);
2115
2116 if (BITS(inst, 12, 15) == 15) {
2117 inst_base->br = INDIRECT_BRANCH;
2118 }
2119 return inst_base;
2120}
2121ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
2122{
2123 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2124 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2125
2126 inst_base->cond = BITS(inst, 28, 31);
2127 inst_base->idx = index;
2128 inst_base->br = NON_BRANCH;
2129
2130 inst_cream->inst = inst;
2131 inst_cream->get_addr = get_calc_addr_op(inst);
2132
2133 if (BITS(inst, 12, 15) == 15) {
2134 inst_base->br = INDIRECT_BRANCH;
2135 }
2136 return inst_base;
2137}
2138ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
2139{
2140 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2141 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2142
2143 inst_base->cond = BITS(inst, 28, 31);
2144 inst_base->idx = index;
2145 inst_base->br = NON_BRANCH;
2146
2147 inst_cream->inst = inst;
2148 inst_cream->get_addr = get_calc_addr_op(inst);
2149
2150 if (BITS(inst, 12, 15) == 15) {
2151 inst_base->br = INDIRECT_BRANCH;
2152 }
2153 return inst_base;
2154}
2155ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
2156{
2157 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2158 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2159
2160 inst_base->cond = BITS(inst, 28, 31);
2161 inst_base->idx = index;
2162 inst_base->br = NON_BRANCH;
2163
2164 inst_cream->inst = inst;
2165 inst_cream->get_addr = get_calc_addr_op(inst);
2166
2167 if (BITS(inst, 12, 15) == 15) {
2168 inst_base->br = INDIRECT_BRANCH;
2169 }
2170 return inst_base;
2171}
2172ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
2173{
2174 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2175 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2176
2177 inst_base->cond = BITS(inst, 28, 31);
2178 inst_base->idx = index;
2179 inst_base->br = NON_BRANCH;
2180
2181 inst_cream->inst = inst;
2182 if (I_BIT == 0) {
2183 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2184 } else {
2185 DEBUG_MSG;
2186 }
2187
2188 if (BITS(inst, 12, 15) == 15) {
2189 inst_base->br = INDIRECT_BRANCH;
2190 }
2191 return inst_base;
2192}
2193ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
2194{
2195 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
2196 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
2197 inst_base->cond = BITS(inst, 28, 31);
2198 inst_base->idx = index;
2199 inst_base->br = NON_BRANCH;
2200
2201 inst_cream->crn = BITS(inst, 16, 19);
2202 inst_cream->crm = BITS(inst, 0, 3);
2203 inst_cream->opcode_1 = BITS(inst, 21, 23);
2204 inst_cream->opcode_2 = BITS(inst, 5, 7);
2205 inst_cream->Rd = BITS(inst, 12, 15);
2206 inst_cream->cp_num = BITS(inst, 8, 11);
2207 inst_cream->inst = inst;
2208 return inst_base;
2209}
2210ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2211ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
2212{
2213 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
2214 mla_inst *inst_cream = (mla_inst *)inst_base->component;
2215
2216 inst_base->cond = BITS(inst, 28, 31);
2217 inst_base->idx = index;
2218 inst_base->br = NON_BRANCH;
2219 inst_base->load_r15 = 0;
2220
2221 inst_cream->S = BIT(inst, 20);
2222 inst_cream->Rn = BITS(inst, 12, 15);
2223 inst_cream->Rd = BITS(inst, 16, 19);
2224 inst_cream->Rs = BITS(inst, 8, 11);
2225 inst_cream->Rm = BITS(inst, 0, 3);
2226
2227 if (CHECK_RM || CHECK_RN || CHECK_RS)
2228 inst_base->load_r15 = 1;
2229
2230 return inst_base;
2231}
2232ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
2233{
2234 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
2235 mov_inst *inst_cream = (mov_inst *)inst_base->component;
2236
2237 inst_base->cond = BITS(inst, 28, 31);
2238 inst_base->idx = index;
2239 inst_base->br = NON_BRANCH;
2240
2241 inst_cream->I = BIT(inst, 25);
2242 inst_cream->S = BIT(inst, 20);
2243 inst_cream->Rd = BITS(inst, 12, 15);
2244 inst_cream->shifter_operand = BITS(inst, 0, 11);
2245 inst_cream->shtop_func = get_shtop(inst);
2246
2247 if (inst_cream->Rd == 15) {
2248 inst_base->br = INDIRECT_BRANCH;
2249 }
2250 return inst_base;
2251}
2252ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
2253{
2254 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
2255 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
2256 inst_base->cond = BITS(inst, 28, 31);
2257 inst_base->idx = index;
2258 inst_base->br = NON_BRANCH;
2259
2260 inst_cream->crn = BITS(inst, 16, 19);
2261 inst_cream->crm = BITS(inst, 0, 3);
2262 inst_cream->opcode_1 = BITS(inst, 21, 23);
2263 inst_cream->opcode_2 = BITS(inst, 5, 7);
2264 inst_cream->Rd = BITS(inst, 12, 15);
2265 inst_cream->cp_num = BITS(inst, 8, 11);
2266 inst_cream->inst = inst;
2267 return inst_base;
2268}
2269ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2270ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
2271{
2272 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
2273 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
2274
2275 inst_base->cond = BITS(inst, 28, 31);
2276 inst_base->idx = index;
2277 inst_base->br = NON_BRANCH;
2278
2279 inst_cream->Rd = BITS(inst, 12, 15);
2280 inst_cream->R = BIT(inst, 22);
2281
2282 return inst_base;
2283}
2284ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
2285{
2286 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
2287 msr_inst *inst_cream = (msr_inst *)inst_base->component;
2288
2289 inst_base->cond = BITS(inst, 28, 31);
2290 inst_base->idx = index;
2291 inst_base->br = NON_BRANCH;
2292
2293 inst_cream->field_mask = BITS(inst, 16, 19);
2294 inst_cream->R = BIT(inst, 22);
2295 inst_cream->inst = inst;
2296
2297 return inst_base;
2298}
2299ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
2300{
2301 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
2302 mul_inst *inst_cream = (mul_inst *)inst_base->component;
2303
2304 inst_base->cond = BITS(inst, 28, 31);
2305 inst_base->idx = index;
2306 inst_base->br = NON_BRANCH;
2307 inst_base->load_r15 = 0;
2308
2309 inst_cream->S = BIT(inst, 20);
2310 inst_cream->Rm = BITS(inst, 0, 3);
2311 inst_cream->Rs = BITS(inst, 8, 11);
2312 inst_cream->Rd = BITS(inst, 16, 19);
2313
2314 if (CHECK_RM || CHECK_RS)
2315 inst_base->load_r15 = 1;
2316 return inst_base;
2317}
2318ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
2319{
2320 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
2321 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
2322
2323 inst_base->cond = BITS(inst, 28, 31);
2324 inst_base->idx = index;
2325 inst_base->br = NON_BRANCH;
2326
2327 inst_cream->I = BIT(inst, 25);
2328 inst_cream->S = BIT(inst, 20);
2329 inst_cream->Rd = BITS(inst, 12, 15);
2330 inst_cream->shifter_operand = BITS(inst, 0, 11);
2331 inst_cream->shtop_func = get_shtop(inst);
2332
2333 if (inst_cream->Rd == 15) {
2334 inst_base->br = INDIRECT_BRANCH;
2335 }
2336 return inst_base;
2337
2338}
2339ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
2340{
2341 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
2342 orr_inst *inst_cream = (orr_inst *)inst_base->component;
2343
2344 inst_base->cond = BITS(inst, 28, 31);
2345 inst_base->idx = index;
2346 inst_base->br = NON_BRANCH;
2347 inst_base->load_r15 = 0;
2348
2349 inst_cream->I = BIT(inst, 25);
2350 inst_cream->S = BIT(inst, 20);
2351 inst_cream->Rd = BITS(inst, 12, 15);
2352 inst_cream->Rn = BITS(inst, 16, 19);
2353 inst_cream->shifter_operand = BITS(inst, 0, 11);
2354 inst_cream->shtop_func = get_shtop(inst);
2355
2356 if (CHECK_RN)
2357 inst_base->load_r15 = 1;
2358 if (inst_cream->Rd == 15) {
2359 inst_base->br = INDIRECT_BRANCH;
2360 }
2361 return inst_base;
2362}
2363ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2364ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2365ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2366{
2367 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
2368
2369 inst_base->cond = BITS(inst, 28, 31);
2370 inst_base->idx = index;
2371 inst_base->br = NON_BRANCH;
2372 inst_base->load_r15 = 0;
2373
2374 return inst_base;
2375}
2376ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2377ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2378ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2379ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2380ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2381ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2382ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2383ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2384ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2385ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2386ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2387{
2388 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2389 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2390
2391 inst_base->cond = BITS(inst, 28, 31);
2392 inst_base->idx = index;
2393 inst_base->br = NON_BRANCH;
2394 inst_base->load_r15 = 0;
2395
2396 inst_cream->Rm = BITS(inst, 0, 3);
2397 inst_cream->Rd = BITS(inst, 12, 15);
2398
2399 return inst_base;
2400}
2401ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
2402 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2403 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2404
2405 inst_base->cond = BITS(inst, 28, 31);
2406 inst_base->idx = index;
2407 inst_base->br = NON_BRANCH;
2408 inst_base->load_r15 = 0;
2409
2410 inst_cream->Rm = BITS(inst, 0, 3);
2411 inst_cream->Rd = BITS(inst, 12, 15);
2412
2413 return inst_base;
2414}
2415ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2416ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2417ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
2418{
2419 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
2420 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
2421
2422 inst_base->cond = BITS(inst, 28, 31);
2423 inst_base->idx = index;
2424 inst_base->br = NON_BRANCH;
2425 inst_base->load_r15 = 0;
2426
2427 inst_cream->I = BIT(inst, 25);
2428 inst_cream->S = BIT(inst, 20);
2429 inst_cream->Rn = BITS(inst, 16, 19);
2430 inst_cream->Rd = BITS(inst, 12, 15);
2431 inst_cream->shifter_operand = BITS(inst, 0, 11);
2432 inst_cream->shtop_func = get_shtop(inst);
2433 if (CHECK_RN)
2434 inst_base->load_r15 = 1;
2435
2436 if (inst_cream->Rd == 15) {
2437 inst_base->br = INDIRECT_BRANCH;
2438 }
2439 return inst_base;
2440}
2441ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
2442{
2443 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
2444 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
2445
2446 inst_base->cond = BITS(inst, 28, 31);
2447 inst_base->idx = index;
2448 inst_base->br = NON_BRANCH;
2449 inst_base->load_r15 = 0;
2450
2451 inst_cream->I = BIT(inst, 25);
2452 inst_cream->S = BIT(inst, 20);
2453 inst_cream->Rn = BITS(inst, 16, 19);
2454 inst_cream->Rd = BITS(inst, 12, 15);
2455 inst_cream->shifter_operand = BITS(inst, 0, 11);
2456 inst_cream->shtop_func = get_shtop(inst);
2457 if (CHECK_RN)
2458 inst_base->load_r15 = 1;
2459
2460 if (inst_cream->Rd == 15) {
2461 inst_base->br = INDIRECT_BRANCH;
2462 }
2463 return inst_base;
2464}
2465ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2466ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2467ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2468ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
2469{
2470 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
2471 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
2472
2473 inst_base->cond = BITS(inst, 28, 31);
2474 inst_base->idx = index;
2475 inst_base->br = NON_BRANCH;
2476 inst_base->load_r15 = 0;
2477
2478 inst_cream->I = BIT(inst, 25);
2479 inst_cream->S = BIT(inst, 20);
2480 inst_cream->Rn = BITS(inst, 16, 19);
2481 inst_cream->Rd = BITS(inst, 12, 15);
2482 inst_cream->shifter_operand = BITS(inst, 0, 11);
2483 inst_cream->shtop_func = get_shtop(inst);
2484 if (CHECK_RN)
2485 inst_base->load_r15 = 1;
2486
2487 if (inst_cream->Rd == 15) {
2488 inst_base->br = INDIRECT_BRANCH;
2489 }
2490 return inst_base;
2491}
2492ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2493ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2494ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2495ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2496ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2497ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2498ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2499ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2500ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
2501{
2502 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
2503 smla_inst *inst_cream = (smla_inst *)inst_base->component;
2504
2505 inst_base->cond = BITS(inst, 28, 31);
2506 inst_base->idx = index;
2507 inst_base->br = NON_BRANCH;
2508 inst_base->load_r15 = 0;
2509
2510 inst_cream->x = BIT(inst, 5);
2511 inst_cream->y = BIT(inst, 6);
2512 inst_cream->Rm = BITS(inst, 0, 3);
2513 inst_cream->Rs = BITS(inst, 8, 11);
2514 inst_cream->Rd = BITS(inst, 16, 19);
2515 inst_cream->Rn = BITS(inst, 12, 15);
2516
2517 return inst_base;
2518}
2519ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
2520 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2521 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2522
2523 inst_base->cond = BITS(inst, 28, 31);
2524 inst_base->idx = index;
2525 inst_base->br = NON_BRANCH;
2526 inst_base->load_r15 = 0;
2527
2528 inst_cream->m = BIT(inst, 4);
2529 inst_cream->Rn = BITS(inst, 0, 3);
2530 inst_cream->Rm = BITS(inst, 8, 11);
2531 inst_cream->Rd = BITS(inst, 16, 19);
2532 inst_cream->Ra = BITS(inst, 12, 15);
2533
2534 if (CHECK_RM )
2535 inst_base->load_r15 = 1;
2536 return inst_base;
2537}
2538ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2539{
2540 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
2541 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
2542
2543 inst_base->cond = BITS(inst, 28, 31);
2544 inst_base->idx = index;
2545 inst_base->br = NON_BRANCH;
2546 inst_base->load_r15 = 0;
2547
2548 inst_cream->S = BIT(inst, 20);
2549 inst_cream->Rm = BITS(inst, 0, 3);
2550 inst_cream->Rs = BITS(inst, 8, 11);
2551 inst_cream->RdHi = BITS(inst, 16, 19);
2552 inst_cream->RdLo = BITS(inst, 12, 15);
2553
2554 if (CHECK_RM || CHECK_RS)
2555 inst_base->load_r15 = 1;
2556 return inst_base;
2557}
2558ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2559ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2560ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2561ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2562ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2563ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2564ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2565ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2566ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2567ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
2568{
2569 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
2570 smul_inst *inst_cream = (smul_inst *)inst_base->component;
2571
2572 inst_base->cond = BITS(inst, 28, 31);
2573 inst_base->idx = index;
2574 inst_base->br = NON_BRANCH;
2575 inst_base->load_r15 = 0;
2576
2577 inst_cream->Rd = BITS(inst, 16, 19);
2578 inst_cream->Rs = BITS(inst, 8, 11);
2579 inst_cream->Rm = BITS(inst, 0, 3);
2580
2581 inst_cream->x = BIT(inst, 5);
2582 inst_cream->y = BIT(inst, 6);
2583
2584 if (CHECK_RM || CHECK_RS)
2585 inst_base->load_r15 = 1;
2586 return inst_base;
2587
2588}
2589ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
2590{
2591 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
2592 umull_inst *inst_cream = (umull_inst *)inst_base->component;
2593
2594 inst_base->cond = BITS(inst, 28, 31);
2595 inst_base->idx = index;
2596 inst_base->br = NON_BRANCH;
2597 inst_base->load_r15 = 0;
2598
2599 inst_cream->S = BIT(inst, 20);
2600 inst_cream->Rm = BITS(inst, 0, 3);
2601 inst_cream->Rs = BITS(inst, 8, 11);
2602 inst_cream->RdHi = BITS(inst, 16, 19);
2603 inst_cream->RdLo = BITS(inst, 12, 15);
2604
2605 if (CHECK_RM || CHECK_RS)
2606 inst_base->load_r15 = 1;
2607 return inst_base;
2608}
2609
2610ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
2611{
2612 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2613 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2614
2615 inst_base->cond = BITS(inst, 28, 31);
2616 inst_base->idx = index;
2617 inst_base->br = NON_BRANCH;
2618 inst_base->load_r15 = 0;
2619
2620 inst_cream->m = BIT(inst, 6);
2621 inst_cream->Rm = BITS(inst, 8, 11);
2622 inst_cream->Rn = BITS(inst, 0, 3);
2623 inst_cream->Rd = BITS(inst, 16, 19);
2624
2625 if (CHECK_RM || CHECK_RN)
2626 inst_base->load_r15 = 1;
2627 return inst_base;
2628}
2629ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2630ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2631ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2632ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2633ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2634ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2635ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2636ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
2637{
2638 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
2639 inst_base->cond = BITS(inst, 28, 31);
2640 inst_base->idx = index;
2641 inst_base->br = NON_BRANCH;
2642
2643 return inst_base;
2644}
2645ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
2646{
2647 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2648 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2649
2650 inst_base->cond = BITS(inst, 28, 31);
2651 inst_base->idx = index;
2652 inst_base->br = NON_BRANCH;
2653
2654 inst_cream->inst = inst;
2655 inst_cream->get_addr = get_calc_addr_op(inst);
2656 return inst_base;
2657}
2658ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
2659{
2660 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
2661 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
2662
2663 inst_base->cond = BITS(inst, 28, 31);
2664 inst_base->idx = index;
2665 inst_base->br = NON_BRANCH;
2666 inst_base->load_r15 = 0;
2667
2668 inst_cream->Rd = BITS(inst, 12, 15);
2669 inst_cream->Rm = BITS(inst, 0, 3);
2670 inst_cream->rotate = BITS(inst, 10, 11);
2671
2672 if (CHECK_RM)
2673 inst_base->load_r15 = 1;
2674 return inst_base;
2675}
2676ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
2677{
2678 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2679 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2680
2681 inst_base->cond = BITS(inst, 28, 31);
2682 inst_base->idx = index;
2683 inst_base->br = NON_BRANCH;
2684
2685 inst_cream->inst = inst;
2686 inst_cream->get_addr = get_calc_addr_op(inst);
2687
2688 if (BITS(inst, 12, 15) == 15) {
2689 inst_base->br = INDIRECT_BRANCH;
2690 }
2691 return inst_base;
2692}
2693ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
2694{
2695 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
2696 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
2697
2698 inst_base->cond = BITS(inst, 28, 31);
2699 inst_base->idx = index;
2700 inst_base->br = NON_BRANCH;
2701 inst_base->load_r15 = 0;
2702
2703 inst_cream->Rd = BITS(inst, 12, 15);
2704 inst_cream->rotate = BITS(inst, 10, 11);
2705 inst_cream->Rm = BITS(inst, 0, 3);
2706
2707 if (CHECK_RM)
2708 inst_base->load_r15 = 1;
2709 return inst_base;
2710}
2711ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
2712{
2713 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
2714 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
2715
2716 inst_base->cond = BITS(inst, 28, 31);
2717 inst_base->idx = index;
2718 inst_base->br = NON_BRANCH;
2719 inst_base->load_r15 = 0;
2720
2721 inst_cream->Rd = BITS(inst, 12, 15);
2722 inst_cream->rotate = BITS(inst, 10, 11);
2723 inst_cream->Rm = BITS(inst, 0, 3);
2724 inst_cream->Rn = BITS(inst, 16, 19);
2725
2726 return inst_base;
2727}
2728ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
2729{
2730 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2731 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2732
2733 inst_base->cond = BITS(inst, 28, 31);
2734 inst_base->idx = index;
2735 inst_base->br = NON_BRANCH;
2736
2737 inst_cream->inst = inst;
2738 inst_cream->get_addr = get_calc_addr_op(inst);
2739
2740 if (BITS(inst, 12, 15) == 15) {
2741 inst_base->br = INDIRECT_BRANCH;
2742 }
2743 return inst_base;
2744}
2745ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
2746{
2747 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2748 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2749
2750 inst_base->cond = BITS(inst, 28, 31);
2751 inst_base->idx = index;
2752 inst_base->br = NON_BRANCH;
2753
2754 inst_cream->inst = inst;
2755// inst_cream->get_addr = get_calc_addr_op(inst);
2756 if (I_BIT == 0) {
2757 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2758 } else {
2759 DEBUG_MSG;
2760 }
2761
2762 if (BITS(inst, 12, 15) == 15) {
2763 inst_base->br = INDIRECT_BRANCH;
2764 }
2765 return inst_base;
2766}
2767ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
2768 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2769 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2770
2771 inst_base->cond = BITS(inst, 28, 31);
2772 inst_base->idx = index;
2773 inst_base->br = NON_BRANCH;
2774
2775 inst_cream->inst = inst;
2776 inst_cream->get_addr = get_calc_addr_op(inst);
2777
2778 if (BITS(inst, 12, 15) == 15) {
2779 inst_base->br = INDIRECT_BRANCH;
2780 }
2781 return inst_base;
2782}
2783ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
2784{
2785 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2786 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2787
2788 inst_base->cond = BITS(inst, 28, 31);
2789 inst_base->idx = index;
2790 inst_base->br = NON_BRANCH;
2791
2792 inst_cream->inst = inst;
2793 inst_cream->get_addr = get_calc_addr_op(inst);
2794
2795 if (BITS(inst, 12, 15) == 15) {
2796 inst_base->br = INDIRECT_BRANCH;
2797 }
2798 return inst_base;
2799}
2800ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
2801{
2802 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2803 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2804
2805 inst_base->cond = BITS(inst, 28, 31);
2806 inst_base->idx = index;
2807 inst_base->br = NON_BRANCH;
2808
2809 inst_cream->inst = inst;
2810 inst_cream->get_addr = get_calc_addr_op(inst);
2811
2812 if (BITS(inst, 12, 15) == 15) {
2813 inst_base->br = INDIRECT_BRANCH;
2814 }
2815 return inst_base;
2816}
2817ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
2818{
2819 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2820 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2821
2822 inst_base->cond = BITS(inst, 28, 31);
2823 inst_base->idx = index;
2824 inst_base->br = NON_BRANCH;
2825
2826 inst_cream->inst = inst;
2827 inst_cream->get_addr = get_calc_addr_op(inst);
2828
2829 if (BITS(inst, 12, 15) == 15) {
2830 inst_base->br = INDIRECT_BRANCH;
2831 }
2832 return inst_base;
2833}
2834ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
2835{
2836 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2837 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2838
2839 inst_base->cond = BITS(inst, 28, 31);
2840 inst_base->idx = index;
2841 inst_base->br = NON_BRANCH;
2842
2843 inst_cream->inst = inst;
2844 if (I_BIT == 0) {
2845 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2846 } else {
2847 DEBUG_MSG;
2848 }
2849
2850 if (BITS(inst, 12, 15) == 15) {
2851 inst_base->br = INDIRECT_BRANCH;
2852 }
2853 return inst_base;
2854}
2855ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
2856{
2857 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
2858 sub_inst *inst_cream = (sub_inst *)inst_base->component;
2859
2860 inst_base->cond = BITS(inst, 28, 31);
2861 inst_base->idx = index;
2862 inst_base->br = NON_BRANCH;
2863 inst_base->load_r15 = 0;
2864
2865 inst_cream->I = BIT(inst, 25);
2866 inst_cream->S = BIT(inst, 20);
2867 inst_cream->Rn = BITS(inst, 16, 19);
2868 inst_cream->Rd = BITS(inst, 12, 15);
2869 inst_cream->shifter_operand = BITS(inst, 0, 11);
2870 inst_cream->shtop_func = get_shtop(inst);
2871 if (inst_cream->Rd == 15) {
2872 inst_base->br = INDIRECT_BRANCH;
2873 }
2874 if (CHECK_RN)
2875 inst_base->load_r15 = 1;
2876
2877 return inst_base;
2878}
2879ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
2880{
2881 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
2882 swi_inst *inst_cream = (swi_inst *)inst_base->component;
2883
2884 inst_base->cond = BITS(inst, 28, 31);
2885 inst_base->idx = index;
2886 inst_base->br = NON_BRANCH;
2887
2888 inst_cream->num = BITS(inst, 0, 23);
2889 return inst_base;
2890}
2891ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
2892{
2893 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2894 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2895
2896 inst_base->cond = BITS(inst, 28, 31);
2897 inst_base->idx = index;
2898 inst_base->br = NON_BRANCH;
2899
2900 inst_cream->Rn = BITS(inst, 16, 19);
2901 inst_cream->Rd = BITS(inst, 12, 15);
2902 inst_cream->Rm = BITS(inst, 0, 3);
2903
2904 if (inst_cream->Rd == 15) {
2905 inst_base->br = INDIRECT_BRANCH;
2906 }
2907 return inst_base;
2908}
2909ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
2910 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2911 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2912
2913 inst_base->cond = BITS(inst, 28, 31);
2914 inst_base->idx = index;
2915 inst_base->br = NON_BRANCH;
2916
2917 inst_cream->Rn = BITS(inst, 16, 19);
2918 inst_cream->Rd = BITS(inst, 12, 15);
2919 inst_cream->Rm = BITS(inst, 0, 3);
2920
2921 if (inst_cream->Rd == 15) {
2922 inst_base->br = INDIRECT_BRANCH;
2923 }
2924 return inst_base;
2925}
2926ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
2927 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
2928 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
2929
2930 inst_base->cond = BITS(inst, 28, 31);
2931 inst_base->idx = index;
2932 inst_base->br = NON_BRANCH;
2933 inst_base->load_r15 = 0;
2934
2935 inst_cream->Rd = BITS(inst, 12, 15);
2936 inst_cream->rotate = BITS(inst, 10, 11);
2937 inst_cream->Rm = BITS(inst, 0, 3);
2938 inst_cream->Rn = BITS(inst, 16, 19);
2939
2940 return inst_base;
2941}
2942ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2943ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
2944 DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__);
2945 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
2946 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
2947
2948 inst_base->cond = BITS(inst, 28, 31);
2949 inst_base->idx = index;
2950 inst_base->br = NON_BRANCH;
2951 inst_base->load_r15 = 0;
2952
2953 inst_cream->Rd = BITS(inst, 12, 15);
2954 inst_cream->rotate = BITS(inst, 10, 11);
2955 inst_cream->Rm = BITS(inst, 0, 3);
2956 inst_cream->Rn = BITS(inst, 16, 19);
2957
2958 return inst_base;
2959}
2960ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2961ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
2962{
2963 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
2964 teq_inst *inst_cream = (teq_inst *)inst_base->component;
2965
2966 inst_base->cond = BITS(inst, 28, 31);
2967 inst_base->idx = index;
2968 inst_base->br = NON_BRANCH;
2969 inst_base->load_r15 = 0;
2970
2971 inst_cream->I = BIT(inst, 25);
2972 inst_cream->Rn = BITS(inst, 16, 19);
2973 inst_cream->shifter_operand = BITS(inst, 0, 11);
2974 inst_cream->shtop_func = get_shtop(inst);
2975
2976 if (CHECK_RN)
2977 inst_base->load_r15 = 1;
2978 return inst_base;
2979}
2980ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
2981{
2982 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
2983 tst_inst *inst_cream = (tst_inst *)inst_base->component;
2984
2985 inst_base->cond = BITS(inst, 28, 31);
2986 inst_base->idx = index;
2987 inst_base->br = NON_BRANCH;
2988 inst_base->load_r15 = 0;
2989
2990 inst_cream->I = BIT(inst, 25);
2991 inst_cream->S = BIT(inst, 20);
2992 inst_cream->Rn = BITS(inst, 16, 19);
2993 inst_cream->Rd = BITS(inst, 12, 15);
2994 inst_cream->shifter_operand = BITS(inst, 0, 11);
2995 inst_cream->shtop_func = get_shtop(inst);
2996 if (inst_cream->Rd == 15) {
2997 inst_base->br = INDIRECT_BRANCH;
2998 }
2999
3000 if (CHECK_RN)
3001 inst_base->load_r15 = 1;
3002 return inst_base;
3003}
3004ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3005ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3006ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3007ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3008ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3009ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3010ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3011ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3012ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3013ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3014ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
3015{
3016 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
3017 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
3018
3019 inst_base->cond = BITS(inst, 28, 31);
3020 inst_base->idx = index;
3021 inst_base->br = NON_BRANCH;
3022 inst_base->load_r15 = 0;
3023
3024 inst_cream->S = BIT(inst, 20);
3025 inst_cream->Rm = BITS(inst, 0, 3);
3026 inst_cream->Rs = BITS(inst, 8, 11);
3027 inst_cream->RdHi = BITS(inst, 16, 19);
3028 inst_cream->RdLo = BITS(inst, 12, 15);
3029
3030 if (CHECK_RM || CHECK_RS)
3031 inst_base->load_r15 = 1;
3032 return inst_base;
3033}
3034ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
3035{
3036 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
3037 umull_inst *inst_cream = (umull_inst *)inst_base->component;
3038
3039 inst_base->cond = BITS(inst, 28, 31);
3040 inst_base->idx = index;
3041 inst_base->br = NON_BRANCH;
3042 inst_base->load_r15 = 0;
3043
3044 inst_cream->S = BIT(inst, 20);
3045 inst_cream->Rm = BITS(inst, 0, 3);
3046 inst_cream->Rs = BITS(inst, 8, 11);
3047 inst_cream->RdHi = BITS(inst, 16, 19);
3048 inst_cream->RdLo = BITS(inst, 12, 15);
3049
3050 if (CHECK_RM || CHECK_RS)
3051 inst_base->load_r15 = 1;
3052 return inst_base;
3053}
3054
3055ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
3056{
3057 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
3058 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
3059
3060 inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
3061 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3062 inst_base->idx = index;
3063 inst_base->br = DIRECT_BRANCH;
3064 return inst_base;
3065}
3066
3067ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
3068{
3069 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
3070 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
3071
3072 inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
3073 inst_cream->cond = ((tinst >> 8) & 0xf);
3074 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond);
3075 inst_base->idx = index;
3076 inst_base->br = DIRECT_BRANCH;
3077 return inst_base;
3078}
3079
3080ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
3081{
3082 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
3083 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
3084
3085 inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
3086 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3087
3088 inst_base->idx = index;
3089 inst_base->br = NON_BRANCH;
3090 return inst_base;
3091}
3092ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
3093{
3094 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
3095 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
3096
3097 inst_cream->imm = (tinst & 0x07FF) << 1;
3098 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3099 inst_base->idx = index;
3100 inst_base->br = DIRECT_BRANCH;
3101 return inst_base;
3102}
3103ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
3104{
3105 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
3106 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
3107
3108 inst_cream->imm = (tinst & 0x07FF) << 1;
3109 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3110 inst_cream->instr = tinst;
3111 inst_base->idx = index;
3112 inst_base->br = DIRECT_BRANCH;
3113 return inst_base;
3114}
3115
3116ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3117ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3118ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3119ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3120ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3121ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3122ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3123ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3124ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3125ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3126ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3127ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3128ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3129ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3130ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3131
3132
3133
3134/* Floating point VFPv3 structures and instructions */
3135
3136#define VFP_INTERPRETER_STRUCT
3137#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3138#undef VFP_INTERPRETER_STRUCT
3139
3140#define VFP_INTERPRETER_TRANS
3141#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3142#undef VFP_INTERPRETER_TRANS
3143
3144
3145
3146typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
3147
3148const transop_fp_t arm_instruction_trans[] = {
3149 #define VFP_INTERPRETER_TABLE
3150 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3151 #undef VFP_INTERPRETER_TABLE
3152 INTERPRETER_TRANSLATE(srs),
3153 INTERPRETER_TRANSLATE(rfe),
3154 INTERPRETER_TRANSLATE(bkpt),
3155 INTERPRETER_TRANSLATE(blx),
3156 INTERPRETER_TRANSLATE(cps),
3157 INTERPRETER_TRANSLATE(pld),
3158 INTERPRETER_TRANSLATE(setend),
3159 INTERPRETER_TRANSLATE(clrex),
3160 INTERPRETER_TRANSLATE(rev16),
3161 INTERPRETER_TRANSLATE(usad8),
3162 INTERPRETER_TRANSLATE(sxtb),
3163 INTERPRETER_TRANSLATE(uxtb),
3164 INTERPRETER_TRANSLATE(sxth),
3165 INTERPRETER_TRANSLATE(sxtb16),
3166 INTERPRETER_TRANSLATE(uxth),
3167 INTERPRETER_TRANSLATE(uxtb16),
3168 INTERPRETER_TRANSLATE(cpy),
3169 INTERPRETER_TRANSLATE(uxtab),
3170 INTERPRETER_TRANSLATE(ssub8),
3171 INTERPRETER_TRANSLATE(shsub8),
3172 INTERPRETER_TRANSLATE(ssubaddx),
3173 INTERPRETER_TRANSLATE(strex),
3174 INTERPRETER_TRANSLATE(strexb),
3175 INTERPRETER_TRANSLATE(swp),
3176 INTERPRETER_TRANSLATE(swpb),
3177 INTERPRETER_TRANSLATE(ssub16),
3178 INTERPRETER_TRANSLATE(ssat16),
3179 INTERPRETER_TRANSLATE(shsubaddx),
3180 INTERPRETER_TRANSLATE(qsubaddx),
3181 INTERPRETER_TRANSLATE(shaddsubx),
3182 INTERPRETER_TRANSLATE(shadd8),
3183 INTERPRETER_TRANSLATE(shadd16),
3184 INTERPRETER_TRANSLATE(sel),
3185 INTERPRETER_TRANSLATE(saddsubx),
3186 INTERPRETER_TRANSLATE(sadd8),
3187 INTERPRETER_TRANSLATE(sadd16),
3188 INTERPRETER_TRANSLATE(shsub16),
3189 INTERPRETER_TRANSLATE(umaal),
3190 INTERPRETER_TRANSLATE(uxtab16),
3191 INTERPRETER_TRANSLATE(usubaddx),
3192 INTERPRETER_TRANSLATE(usub8),
3193 INTERPRETER_TRANSLATE(usub16),
3194 INTERPRETER_TRANSLATE(usat16),
3195 INTERPRETER_TRANSLATE(usada8),
3196 INTERPRETER_TRANSLATE(uqsubaddx),
3197 INTERPRETER_TRANSLATE(uqsub8),
3198 INTERPRETER_TRANSLATE(uqsub16),
3199 INTERPRETER_TRANSLATE(uqaddsubx),
3200 INTERPRETER_TRANSLATE(uqadd8),
3201 INTERPRETER_TRANSLATE(uqadd16),
3202 INTERPRETER_TRANSLATE(sxtab),
3203 INTERPRETER_TRANSLATE(uhsubaddx),
3204 INTERPRETER_TRANSLATE(uhsub8),
3205 INTERPRETER_TRANSLATE(uhsub16),
3206 INTERPRETER_TRANSLATE(uhaddsubx),
3207 INTERPRETER_TRANSLATE(uhadd8),
3208 INTERPRETER_TRANSLATE(uhadd16),
3209 INTERPRETER_TRANSLATE(uaddsubx),
3210 INTERPRETER_TRANSLATE(uadd8),
3211 INTERPRETER_TRANSLATE(uadd16),
3212 INTERPRETER_TRANSLATE(sxtah),
3213 INTERPRETER_TRANSLATE(sxtab16),
3214 INTERPRETER_TRANSLATE(qadd8),
3215 INTERPRETER_TRANSLATE(bxj),
3216 INTERPRETER_TRANSLATE(clz),
3217 INTERPRETER_TRANSLATE(uxtah),
3218 INTERPRETER_TRANSLATE(bx),
3219 INTERPRETER_TRANSLATE(rev),
3220 INTERPRETER_TRANSLATE(blx),
3221 INTERPRETER_TRANSLATE(revsh),
3222 INTERPRETER_TRANSLATE(qadd),
3223 INTERPRETER_TRANSLATE(qadd16),
3224 INTERPRETER_TRANSLATE(qaddsubx),
3225 INTERPRETER_TRANSLATE(ldrex),
3226 INTERPRETER_TRANSLATE(qdadd),
3227 INTERPRETER_TRANSLATE(qdsub),
3228 INTERPRETER_TRANSLATE(qsub),
3229 INTERPRETER_TRANSLATE(ldrexb),
3230 INTERPRETER_TRANSLATE(qsub8),
3231 INTERPRETER_TRANSLATE(qsub16),
3232 INTERPRETER_TRANSLATE(smuad),
3233 INTERPRETER_TRANSLATE(smmul),
3234 INTERPRETER_TRANSLATE(smusd),
3235 INTERPRETER_TRANSLATE(smlsd),
3236 INTERPRETER_TRANSLATE(smlsld),
3237 INTERPRETER_TRANSLATE(smmla),
3238 INTERPRETER_TRANSLATE(smmls),
3239 INTERPRETER_TRANSLATE(smlald),
3240 INTERPRETER_TRANSLATE(smlad),
3241 INTERPRETER_TRANSLATE(smlaw),
3242 INTERPRETER_TRANSLATE(smulw),
3243 INTERPRETER_TRANSLATE(pkhtb),
3244 INTERPRETER_TRANSLATE(pkhbt),
3245 INTERPRETER_TRANSLATE(smul),
3246 INTERPRETER_TRANSLATE(smlalxy),
3247 INTERPRETER_TRANSLATE(smla),
3248 INTERPRETER_TRANSLATE(mcrr),
3249 INTERPRETER_TRANSLATE(mrrc),
3250 INTERPRETER_TRANSLATE(cmp),
3251 INTERPRETER_TRANSLATE(tst),
3252 INTERPRETER_TRANSLATE(teq),
3253 INTERPRETER_TRANSLATE(cmn),
3254 INTERPRETER_TRANSLATE(smull),
3255 INTERPRETER_TRANSLATE(umull),
3256 INTERPRETER_TRANSLATE(umlal),
3257 INTERPRETER_TRANSLATE(smlal),
3258 INTERPRETER_TRANSLATE(mul),
3259 INTERPRETER_TRANSLATE(mla),
3260 INTERPRETER_TRANSLATE(ssat),
3261 INTERPRETER_TRANSLATE(usat),
3262 INTERPRETER_TRANSLATE(mrs),
3263 INTERPRETER_TRANSLATE(msr),
3264 INTERPRETER_TRANSLATE(and),
3265 INTERPRETER_TRANSLATE(bic),
3266 INTERPRETER_TRANSLATE(ldm),
3267 INTERPRETER_TRANSLATE(eor),
3268 INTERPRETER_TRANSLATE(add),
3269 INTERPRETER_TRANSLATE(rsb),
3270 INTERPRETER_TRANSLATE(rsc),
3271 INTERPRETER_TRANSLATE(sbc),
3272 INTERPRETER_TRANSLATE(adc),
3273 INTERPRETER_TRANSLATE(sub),
3274 INTERPRETER_TRANSLATE(orr),
3275 INTERPRETER_TRANSLATE(mvn),
3276 INTERPRETER_TRANSLATE(mov),
3277 INTERPRETER_TRANSLATE(stm),
3278 INTERPRETER_TRANSLATE(ldm),
3279 INTERPRETER_TRANSLATE(ldrsh),
3280 INTERPRETER_TRANSLATE(stm),
3281 INTERPRETER_TRANSLATE(ldm),
3282 INTERPRETER_TRANSLATE(ldrsb),
3283 INTERPRETER_TRANSLATE(strd),
3284 INTERPRETER_TRANSLATE(ldrh),
3285 INTERPRETER_TRANSLATE(strh),
3286 INTERPRETER_TRANSLATE(ldrd),
3287 INTERPRETER_TRANSLATE(strt),
3288 INTERPRETER_TRANSLATE(strbt),
3289 INTERPRETER_TRANSLATE(ldrbt),
3290 INTERPRETER_TRANSLATE(ldrt),
3291 INTERPRETER_TRANSLATE(mrc),
3292 INTERPRETER_TRANSLATE(mcr),
3293 INTERPRETER_TRANSLATE(msr),
3294 INTERPRETER_TRANSLATE(ldrb),
3295 INTERPRETER_TRANSLATE(strb),
3296 INTERPRETER_TRANSLATE(ldr),
3297 INTERPRETER_TRANSLATE(ldrcond),
3298 INTERPRETER_TRANSLATE(str),
3299 INTERPRETER_TRANSLATE(cdp),
3300 INTERPRETER_TRANSLATE(stc),
3301 INTERPRETER_TRANSLATE(ldc),
3302 INTERPRETER_TRANSLATE(swi),
3303 INTERPRETER_TRANSLATE(bbl),
3304 /* All the thumb instructions should be placed the end of table */
3305 INTERPRETER_TRANSLATE(b_2_thumb),
3306 INTERPRETER_TRANSLATE(b_cond_thumb),
3307 INTERPRETER_TRANSLATE(bl_1_thumb),
3308 INTERPRETER_TRANSLATE(bl_2_thumb),
3309 INTERPRETER_TRANSLATE(blx_1_thumb)
3310};
3311
3312typedef map<unsigned int, int> bb_map;
3313bb_map CreamCache[65536];
3314bb_map ProfileCache[65536];
3315
3316//#define USE_DUMMY_CACHE
3317
3318#ifdef USE_DUMMY_CACHE
3319unsigned int DummyCache[0x100000];
3320#endif
3321
3322#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536)
3323void insert_bb(unsigned int addr, int start)
3324{
3325#ifdef USE_DUMMY_CACHE
3326 DummyCache[addr] = start;
3327#else
3328// CreamCache[addr] = start;
3329 CreamCache[HASH(addr)][addr] = start;
3330#endif
3331}
3332
3333#define TRANS_THRESHOLD 65000
3334int find_bb(unsigned int addr, int &start)
3335{
3336 int ret = -1;
3337#ifdef USE_DUMMY_CACHE
3338 start = DummyCache[addr];
3339 if (start) {
3340 ret = 0;
3341 } else
3342 ret = -1;
3343#else
3344 bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr);
3345 if (it != CreamCache[HASH(addr)].end()) {
3346 start = static_cast<int>(it->second);
3347 ret = 0;
3348#if HYBRID_MODE
3349#if PROFILE
3350#else
3351 /* increase the bb counter */
3352 if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){
3353 push_to_compiled(cpu, addr);
3354 }
3355#endif
3356#endif
3357 } else {
3358 ret = -1;
3359 }
3360#endif
3361 return ret;
3362}
3363
3364
3365enum {
3366 FETCH_SUCCESS,
3367 FETCH_FAILURE
3368};
3369static 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){
3370 /* Check if in Thumb mode. */
3371 tdstate ret;
3372 ret = thumb_translate (addr, inst, arm_inst, inst_size);
3373 if(ret == t_branch){
3374 /* FIXME, endian should be judged */
3375 uint32 tinstr;
3376 if((addr & 0x3) != 0)
3377 tinstr = inst >> 16;
3378 else
3379 tinstr = inst & 0xFFFF;
3380
3381 //tinstr = inst & 0xFFFF;
3382 int inst_index;
3383 /* table_length */
3384 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
3385
3386 switch((tinstr & 0xF800) >> 11){
3387 /* we will translate the thumb instruction directly here */
3388 /* we will translate the thumb instruction directly here */
3389 case 26:
3390 case 27:
3391 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
3392 uint32 cond = (tinstr & 0x0F00) >> 8;
3393 inst_index = table_length - 4;
3394 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
3395 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3396 }
3397 else{
3398 /* something wrong */
3399 DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__);
3400 }
3401 break;
3402 case 28:
3403 /* Branch 2, unconditional branch */
3404 inst_index = table_length - 5;
3405 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
3406 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3407 break;
3408
3409 case 8:
3410 case 29:
3411 /* For BLX 1 thumb instruction*/
3412 inst_index = table_length - 1;
3413 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3414 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3415 break;
3416 case 30:
3417 /* For BL 1 thumb instruction*/
3418 inst_index = table_length - 3;
3419 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3420 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3421 break;
3422 case 31:
3423 /* For BL 2 thumb instruction*/
3424 inst_index = table_length - 2;
3425 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3426 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3427 break;
3428 default:
3429 ret = t_undefined;
3430 break;
3431 }
3432 }
3433 return ret;
3434}
3435
3436#if 0
3437int FetchInst(cpu_t *core, unsigned int &inst)
3438{
3439 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3440 arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3441// fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32);
3442 fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32);
3443 if (!core->is_user_mode) {
3444 if (fault) {
3445 cpu->abortSig = true;
3446 cpu->Aborted = ARMul_PrefetchAbortV;
3447 cpu->AbortAddr = cpu->translate_pc;
3448 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3449 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc;
3450 return FETCH_FAILURE;
3451 }
3452 }
3453 return FETCH_SUCCESS;
3454}
3455#endif
3456
3457unsigned int *InstLength;
3458
3459enum {
3460 KEEP_GOING,
3461 FETCH_EXCEPTION
3462};
3463
3464typedef struct instruction_set_encoding_item ISEITEM;
3465
3466extern const ISEITEM arm_instruction[];
3467
3468vector<uint64_t> code_page_set;
3469
3470void flush_bb(uint32_t addr)
3471{
3472 bb_map::iterator it;
3473 uint32_t start;
3474
3475 addr &= 0xfffff000;
3476 for (int i = 0; i < 65536; i ++) {
3477 for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) {
3478 start = static_cast<uint32_t>(it->first);
3479 //start = (start >> 12) << 12;
3480 start &= 0xfffff000;
3481 if (start == addr) {
3482 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3483 CreamCache[i].erase(it ++);
3484 } else
3485 ++it;
3486 }
3487 }
3488
3489 for (int i = 0; i < 65536; i ++) {
3490 for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) {
3491 start = static_cast<uint32_t>(it->first);
3492 //start = (start >> 12) << 12;
3493 start &= 0xfffff000;
3494 if (start == addr) {
3495 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3496 ProfileCache[i].erase(it ++);
3497 } else
3498 ++it;
3499 }
3500 }
3501
3502 //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
3503}
3504
3505//static uint32_t get_bank_addr(void *addr)
3506//{
3507// uint64_t address = (uint64_t)addr;
3508// uint64_t bank0 = get_dma_addr(BANK0_START);
3509// if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) {
3510// //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr);
3511// return ((uint64_t)addr - bank0) + BANK0_START;
3512// }
3513// return 0;
3514//}
3515
3516/* shenoubang add win32 2012-6-12 */
3517//#ifndef __WIN32__
3518//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused)
3519//{
3520// DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr);
3521// uint64_t addr = (uint64_t)si->si_addr;
3522// addr = (addr >> 12) << 12;
3523// skyeye_backtrace();
3524// #if 0
3525// if (addr == 0) {
3526// return;
3527// }
3528// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3529// code_page_set.end(),
3530// (uint64_t)addr);
3531// if (it != code_page_set.end()) {
3532// code_page_set.erase(it);
3533// }
3534// mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE);
3535// //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr);
3536// uint32_t phys_addr = get_bank_addr((void *)addr);
3537//// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr);
3538// flush_bb(phys_addr);
3539// flush_bb(phys_addr + 4096);
3540//#if HYBRID_MODE
3541// /* flush the translated BB of dyncom */
3542// clear_translated_cache(phys_addr);
3543//#endif
3544// #endif
3545//}
3546//#endif /* shenoubang */
3547
3548//void protect_code_page(uint32_t addr)
3549//{
3550// void *mem_ptr = (void *)get_dma_addr(addr);
3551// mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL);
3552//
3553// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3554// code_page_set.end(),
3555// (uint64_t)mem_ptr);
3556// if (it != code_page_set.end()) {
3557// return;
3558// }
3559// //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr);
3560// /* shenoubang add win32 2012-6-12 */
3561//#ifndef __WIN32__
3562// struct sigaction sa;
3563//
3564// memset(&sa, 0, sizeof(sa));
3565// sa.sa_flags = SA_RESTART | SA_SIGINFO;
3566// sa.sa_sigaction = &flush_code_cache;
3567// sigaction(SIGSEGV, &sa, NULL);
3568//
3569// //mprotect(mem_ptr, 4096, PROT_READ);
3570//
3571// code_page_set.push_back((uint64_t)mem_ptr);
3572//#endif /* shenoubang */
3573//}
3574
3575
3576
3577int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr)
3578{
3579 /* Decode instruction, get index */
3580 /* Allocate memory and init InsCream */
3581 /* Go on next, until terminal instruction */
3582 /* Save start addr of basicblock in CreamCache */
3583 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3584 //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3585 ARM_INST_PTR inst_base = NULL;
3586 unsigned int inst, inst_size = 4;
3587 int idx;
3588 int ret = NON_BRANCH;
3589 int thumb = 0;
3590 /* instruction size of basic block */
3591 int size = 0;
3592 /* (R15 - 8) ? */
3593 //cpu->translate_pc = cpu->Reg[15];
3594 bb_start = top;
3595
3596 if (cpu->TFlag)
3597 thumb = THUMB;
3598
3599 addr_t phys_addr;
3600 addr_t pc_start;
3601 fault_t fault = NO_FAULT;
3602 //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB);
3603 fault = check_address_validity(cpu, addr, &phys_addr, 1);
3604 if(fault != NO_FAULT){
3605 cpu->abortSig = true;
3606 cpu->Aborted = ARMul_PrefetchAbortV;
3607 cpu->AbortAddr = addr;
3608 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3609 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
3610 return FETCH_EXCEPTION;
3611 }
3612 pc_start = phys_addr;
3613 //phys_addr = get_dma_addr(phys_addr);
3614 while(ret == NON_BRANCH) {
3615 /* shenoubang add win32 2012-6-14 */
3616#ifdef __WIN32__
3617 mem_bank_t* bank;
3618 if (bank = bank_ptr(addr)) {
3619 bank->bank_read(32, phys_addr, &inst);
3620 }
3621 else {
3622 DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr);
3623 return FETCH_FAILURE;
3624 }
3625#else
3626 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
3627#endif
3628 //or_tag(core, phys_addr, TAG_FAST_INTERP);
3629
3630 /*if (ret == FETCH_FAILURE) {
3631 return FETCH_EXCEPTION;
3632 }*/
3633
3634 size ++;
3635 /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */
3636 if (cpu->TFlag){
3637 //if(cpu->Cpsr & (1 << THUMB_BIT)){
3638 uint32_t arm_inst;
3639 tdstate state;
3640 state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3641 //or_tag(core, phys_addr, TAG_THUMB);
3642 //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);
3643 /* we have translated the branch instruction of thumb in thumb decoder */
3644 if(state == t_branch){
3645 goto translated;
3646 }
3647 inst = arm_inst;
3648 }
3649
3650 ret = decode_arm_instr(inst, &idx);
3651 if (ret == DECODE_FAILURE) {
3652 DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst);
3653 DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
3654 CITRA_IGNORE_EXIT(-1);
3655 }
3656// DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name);
3657 inst_base = arm_instruction_trans[idx](inst, idx);
3658// DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst);
3659// DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]);
3660translated:
3661 phys_addr += inst_size;
3662
3663 if ((phys_addr & 0xfff) == 0) {
3664 inst_base->br = END_OF_PAGE;
3665 }
3666 ret = inst_base->br;
3667 };
3668
3669 //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag);
3670 insert_bb(pc_start, bb_start);
3671 return KEEP_GOING;
3672}
3673
3674#define LOG_IN_CLR skyeye_printf_in_color
3675
3676int cmp(const void *x, const void *y)
3677{
3678 return *(unsigned long long int*)x - *(unsigned long long int *)y;
3679}
3680
3681void InterpreterInitInstLength(unsigned long long int *ptr, size_t size)
3682{
3683 int array_size = size / sizeof(void *);
3684 unsigned long long int *InstLabel = new unsigned long long int[array_size];
3685 memcpy(InstLabel, ptr, size);
3686 qsort(InstLabel, array_size, sizeof(void *), cmp);
3687 InstLength = new unsigned int[array_size - 4];
3688 for (int i = 0; i < array_size - 4; i ++) {
3689 for (int j = 0; j < array_size; j ++) {
3690 if (ptr[i] == InstLabel[j]) {
3691 InstLength[i] = InstLabel[j + 1] - InstLabel[j];
3692 break;
3693 }
3694 }
3695 }
3696 for (int i = 0; i < array_size - 4; i ++)
3697 DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]);
3698}
3699
3700int clz(unsigned int x)
3701{
3702 int n;
3703 if (x == 0) return (32);
3704 n = 1;
3705 if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
3706 if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
3707 if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
3708 if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
3709 n = n - (x >> 31);
3710 return n;
3711}
3712
3713unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number);
3714
3715static bool InAPrivilegedMode(arm_core_t *core)
3716{
3717 return (core->Mode != USER32MODE);
3718}
3719
3720/* r15 = r15 + 8 */
3721void InterpreterMainLoop(ARMul_State* state)
3722{
3723 #define CRn inst_cream->crn
3724 #define OPCODE_2 inst_cream->opcode_2
3725 #define CRm inst_cream->crm
3726 #define CP15_REG(n) cpu->CP15[CP15(n)]
3727 #define RD cpu->Reg[inst_cream->Rd]
3728 #define RN cpu->Reg[inst_cream->Rn]
3729 #define RM cpu->Reg[inst_cream->Rm]
3730 #define RS cpu->Reg[inst_cream->Rs]
3731 #define RDHI cpu->Reg[inst_cream->RdHi]
3732 #define RDLO cpu->Reg[inst_cream->RdLo]
3733 #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
3734 #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
3735 #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
3736
3737 #if ENABLE_ICOUNTER
3738 #define INC_ICOUNTER cpu->icounter++; \
3739 if(cpu->Reg[15] > 0xc0000000) \
3740 cpu->kernel_icounter++;
3741 //if (debug_function(core)) \
3742 if (core->check_int_flag) \
3743 goto END
3744 //DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15])
3745 #else
3746 #define INC_ICOUNTER ;
3747 #endif
3748
3749 #define FETCH_INST if (inst_base->br != NON_BRANCH) \
3750 goto PROFILING; \
3751 inst_base = (arm_inst *)&inst_buf[ptr]
3752#define INC_PC(l) ptr += sizeof(arm_inst) + l
3753
3754// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
3755// clunky switch statement.
3756#if defined __GNUC__ || defined __clang__
3757#define GOTO_NEXT_INST goto *InstLabel[inst_base->idx]
3758#else
3759#define GOTO_NEXT_INST switch(inst_base->idx) { \
3760 case 0: goto VMLA_INST; \
3761 case 1: goto VMLS_INST; \
3762 case 2: goto VNMLA_INST; \
3763 case 3: goto VNMLA_INST; \
3764 case 4: goto VNMLS_INST; \
3765 case 5: goto VNMUL_INST; \
3766 case 6: goto VMUL_INST; \
3767 case 7: goto VADD_INST; \
3768 case 8: goto VSUB_INST; \
3769 case 9: goto VDIV_INST; \
3770 case 10: goto VMOVI_INST; \
3771 case 11: goto VMOVR_INST; \
3772 case 12: goto VABS_INST; \
3773 case 13: goto VNEG_INST; \
3774 case 14: goto VSQRT_INST; \
3775 case 15: goto VCMP_INST; \
3776 case 16: goto VCMP2_INST; \
3777 case 17: goto VCVTBDS_INST; \
3778 case 18: goto VCVTBFF_INST; \
3779 case 19: goto VCVTBFI_INST; \
3780 case 20: goto VMOVBRS_INST; \
3781 case 21: goto VMSR_INST; \
3782 case 22: goto VMOVBRC_INST; \
3783 case 23: goto VMRS_INST; \
3784 case 24: goto VMOVBCR_INST; \
3785 case 25: goto VMOVBRRSS_INST; \
3786 case 26: goto VMOVBRRD_INST; \
3787 case 27: goto VSTR_INST; \
3788 case 28: goto VPUSH_INST; \
3789 case 29: goto VSTM_INST; \
3790 case 30: goto VPOP_INST; \
3791 case 31: goto VLDR_INST; \
3792 case 32: goto VLDM_INST ; \
3793 case 33: goto SRS_INST; \
3794 case 34: goto RFE_INST; \
3795 case 35: goto BKPT_INST; \
3796 case 36: goto BLX_INST; \
3797 case 37: goto CPS_INST; \
3798 case 38: goto PLD_INST; \
3799 case 39: goto SETEND_INST; \
3800 case 40: goto CLREX_INST; \
3801 case 41: goto REV16_INST; \
3802 case 42: goto USAD8_INST; \
3803 case 43: goto SXTB_INST; \
3804 case 44: goto UXTB_INST; \
3805 case 45: goto SXTH_INST; \
3806 case 46: goto SXTB16_INST; \
3807 case 47: goto UXTH_INST; \
3808 case 48: goto UXTB16_INST; \
3809 case 49: goto CPY_INST; \
3810 case 50: goto UXTAB_INST; \
3811 case 51: goto SSUB8_INST; \
3812 case 52: goto SHSUB8_INST; \
3813 case 53: goto SSUBADDX_INST; \
3814 case 54: goto STREX_INST; \
3815 case 55: goto STREXB_INST; \
3816 case 56: goto SWP_INST; \
3817 case 57: goto SWPB_INST; \
3818 case 58: goto SSUB16_INST; \
3819 case 59: goto SSAT16_INST; \
3820 case 60: goto SHSUBADDX_INST; \
3821 case 61: goto QSUBADDX_INST; \
3822 case 62: goto SHADDSUBX_INST; \
3823 case 63: goto SHADD8_INST; \
3824 case 64: goto SHADD16_INST; \
3825 case 65: goto SEL_INST; \
3826 case 66: goto SADDSUBX_INST; \
3827 case 67: goto SADD8_INST; \
3828 case 68: goto SADD16_INST; \
3829 case 69: goto SHSUB16_INST; \
3830 case 70: goto UMAAL_INST; \
3831 case 71: goto UXTAB16_INST; \
3832 case 72: goto USUBADDX_INST; \
3833 case 73: goto USUB8_INST; \
3834 case 74: goto USUB16_INST; \
3835 case 75: goto USAT16_INST; \
3836 case 76: goto USADA8_INST; \
3837 case 77: goto UQSUBADDX_INST; \
3838 case 78: goto UQSUB8_INST; \
3839 case 79: goto UQSUB16_INST; \
3840 case 80: goto UQADDSUBX_INST; \
3841 case 81: goto UQADD8_INST; \
3842 case 82: goto UQADD16_INST; \
3843 case 83: goto SXTAB_INST; \
3844 case 84: goto UHSUBADDX_INST; \
3845 case 85: goto UHSUB8_INST; \
3846 case 86: goto UHSUB16_INST; \
3847 case 87: goto UHADDSUBX_INST; \
3848 case 88: goto UHADD8_INST; \
3849 case 89: goto UHADD16_INST; \
3850 case 90: goto UADDSUBX_INST; \
3851 case 91: goto UADD8_INST; \
3852 case 92: goto UADD16_INST; \
3853 case 93: goto SXTAH_INST; \
3854 case 94: goto SXTAB16_INST; \
3855 case 95: goto QADD8_INST; \
3856 case 96: goto BXJ_INST; \
3857 case 97: goto CLZ_INST; \
3858 case 98: goto UXTAH_INST; \
3859 case 99: goto BX_INST; \
3860 case 100: goto REV_INST; \
3861 case 101: goto BLX_INST; \
3862 case 102: goto REVSH_INST; \
3863 case 103: goto QADD_INST; \
3864 case 104: goto QADD16_INST; \
3865 case 105: goto QADDSUBX_INST; \
3866 case 106: goto LDREX_INST; \
3867 case 107: goto QDADD_INST; \
3868 case 108: goto QDSUB_INST; \
3869 case 109: goto QSUB_INST; \
3870 case 110: goto LDREXB_INST; \
3871 case 111: goto QSUB8_INST; \
3872 case 112: goto QSUB16_INST; \
3873 case 113: goto SMUAD_INST; \
3874 case 114: goto SMMUL_INST; \
3875 case 115: goto SMUSD_INST; \
3876 case 116: goto SMLSD_INST; \
3877 case 117: goto SMLSLD_INST; \
3878 case 118: goto SMMLA_INST; \
3879 case 119: goto SMMLS_INST; \
3880 case 120: goto SMLALD_INST; \
3881 case 121: goto SMLAD_INST; \
3882 case 122: goto SMLAW_INST; \
3883 case 123: goto SMULW_INST; \
3884 case 124: goto PKHTB_INST; \
3885 case 125: goto PKHBT_INST; \
3886 case 126: goto SMUL_INST; \
3887 case 127: goto SMLAL_INST; \
3888 case 128: goto SMLA_INST; \
3889 case 129: goto MCRR_INST; \
3890 case 130: goto MRRC_INST; \
3891 case 131: goto CMP_INST; \
3892 case 132: goto TST_INST; \
3893 case 133: goto TEQ_INST; \
3894 case 134: goto CMN_INST; \
3895 case 135: goto SMULL_INST; \
3896 case 136: goto UMULL_INST; \
3897 case 137: goto UMLAL_INST; \
3898 case 138: goto SMLAL_INST; \
3899 case 139: goto MUL_INST; \
3900 case 140: goto MLA_INST; \
3901 case 141: goto SSAT_INST; \
3902 case 142: goto USAT_INST; \
3903 case 143: goto MRS_INST; \
3904 case 144: goto MSR_INST; \
3905 case 145: goto AND_INST; \
3906 case 146: goto BIC_INST; \
3907 case 147: goto LDM_INST; \
3908 case 148: goto EOR_INST; \
3909 case 149: goto ADD_INST; \
3910 case 150: goto RSB_INST; \
3911 case 151: goto RSC_INST; \
3912 case 152: goto SBC_INST; \
3913 case 153: goto ADC_INST; \
3914 case 154: goto SUB_INST; \
3915 case 155: goto ORR_INST; \
3916 case 156: goto MVN_INST; \
3917 case 157: goto MOV_INST; \
3918 case 158: goto STM_INST; \
3919 case 159: goto LDM_INST; \
3920 case 160: goto LDRSH_INST; \
3921 case 161: goto STM_INST; \
3922 case 162: goto LDM_INST; \
3923 case 163: goto LDRSB_INST; \
3924 case 164: goto STRD_INST; \
3925 case 165: goto LDRH_INST; \
3926 case 166: goto STRH_INST; \
3927 case 167: goto LDRD_INST; \
3928 case 168: goto STRT_INST; \
3929 case 169: goto STRBT_INST; \
3930 case 170: goto LDRBT_INST; \
3931 case 171: goto LDRT_INST; \
3932 case 172: goto MRC_INST; \
3933 case 173: goto MCR_INST; \
3934 case 174: goto MSR_INST; \
3935 case 175: goto LDRB_INST; \
3936 case 176: goto STRB_INST; \
3937 case 177: goto LDR_INST; \
3938 case 178: goto LDRCOND_INST ; \
3939 case 179: goto STR_INST; \
3940 case 180: goto CDP_INST; \
3941 case 181: goto STC_INST; \
3942 case 182: goto LDC_INST; \
3943 case 183: goto SWI_INST; \
3944 case 184: goto BBL_INST; \
3945 case 185: goto B_2_THUMB ; \
3946 case 186: goto B_COND_THUMB ; \
3947 case 187: goto BL_1_THUMB ; \
3948 case 188: goto BL_2_THUMB ; \
3949 case 189: goto BLX_1_THUMB ; \
3950 case 190: goto DISPATCH; \
3951 case 191: goto INIT_INST_LENGTH; \
3952 case 192: goto END; \
3953 }
3954#endif
3955
3956 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
3957 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
3958// #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \
3959 (ISNEG(lop) && ISPOS(dst)) || \
3960 (ISPOS(rop) && ISPOS(dst))))
3961 #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
3962 #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
3963 #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
3964 #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
3965 #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
3966 #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out
3967// #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \
3968 (ISNEG(lop) && ISPOS(dst)) || \
3969 (ISPOS(rop) && ISPOS(dst)))
3970 #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
3971 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3972 #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
3973 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3974 #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
3975
3976 #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
3977 (cpu->NFlag << 31) | \
3978 (cpu->ZFlag << 30) | \
3979 (cpu->CFlag << 29) | \
3980 (cpu->VFlag << 28) | \
3981 (cpu->TFlag << 5)
3982 #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
3983 cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
3984 cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
3985 cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
3986 cpu->TFlag = (cpu->Cpsr >> 5) & 1;
3987
3988 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
3989 #define PC (cpu->Reg[15])
3990 #define CHECK_EXT_INT if (!cpu->NirqSig) { \
3991 if (!(cpu->Cpsr & 0x80)) { \
3992 goto END; \
3993 } \
3994 }
3995
3996
3997
3998 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3999 arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
4000
4001 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
4002 // to a clunky switch statement.
4003#if defined __GNUC__ || defined __clang__
4004 void *InstLabel[] = {
4005 #define VFP_INTERPRETER_LABEL
4006 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
4007 #undef VFP_INTERPRETER_LABEL
4008 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
4009 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
4010 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
4011 &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
4012 &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
4013 &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
4014 &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
4015 &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
4016 &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
4017 &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST,
4018 &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
4019 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
4020 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
4021 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
4022 &&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,
4023 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
4024 };
4025#endif
4026 arm_inst * inst_base;
4027 unsigned int lop, rop, dst;
4028 unsigned int addr;
4029 unsigned int phys_addr;
4030 unsigned int last_pc = 0;
4031 fault_t fault;
4032 static unsigned int last_physical_base = 0, last_logical_base = 0;
4033 int ptr;
4034
4035 LOAD_NZCVT;
4036 DISPATCH:
4037 {
4038 if (cpu->NumInstrsToExecute == 0)
4039 return;
4040
4041 cpu->NumInstrsToExecute--;
4042
4043 //NOTICE_LOG(ARM11, "instr!");
4044
4045 if (!cpu->NirqSig) {
4046 if (!(cpu->Cpsr & 0x80)) {
4047 goto END;
4048 }
4049 }
4050
4051 if (cpu->TFlag) {
4052 cpu->Reg[15] &= 0xfffffffe;
4053 } else
4054 cpu->Reg[15] &= 0xfffffffc;
4055#if PROFILE
4056 /* check next instruction address is valid. */
4057 last_pc = cpu->Reg[15];
4058#endif
4059#if USER_MODE_OPT
4060 phys_addr = cpu->Reg[15];
4061#else
4062 {
4063 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4064 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4065 else {
4066 /* check next instruction address is valid. */
4067 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4068 if (fault) {
4069 cpu->abortSig = true;
4070 cpu->Aborted = ARMul_PrefetchAbortV;
4071 cpu->AbortAddr = cpu->Reg[15];
4072 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4073 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4074 goto END;
4075 }
4076 last_logical_base = cpu->Reg[15] & 0xfffff000;
4077 last_physical_base = phys_addr & 0xfffff000;
4078 }
4079 }
4080#if HYBRID_MODE
4081 /* check if the native code of dyncom is available */
4082 //fast_map hash_map = core->dyncom_engine->fmap;
4083 //void * pfunc = NULL;
4084 //PFUNC(phys_addr);
4085 //if(pfunc){
4086 if(is_translated_entry(core, phys_addr)){
4087 int rc = JIT_RETURN_NOERR;
4088 //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
4089 SAVE_NZCVT;
4090// resume_timing();
4091 rc = cpu_run(core);
4092 LOAD_NZCVT;
4093 //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
4094 if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
4095 /* keep the tflag same with the bit in CPSR */
4096 //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
4097 //cpu->TFlag = cpu->Cpsr & (1 << 5);
4098 //switch_mode(cpu, cpu->Cpsr & 0x1f);
4099 //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
4100 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4101 if (fault) {
4102 cpu->abortSig = true;
4103 cpu->Aborted = ARMul_PrefetchAbortV;
4104 cpu->AbortAddr = cpu->Reg[15];
4105 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4106 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4107 goto END;
4108 }
4109 last_logical_base = cpu->Reg[15] & 0xfffff000;
4110 last_physical_base = phys_addr & 0xfffff000;
4111 core->current_page_phys = last_physical_base;
4112 core->current_page_effec = last_logical_base;
4113 //push_to_compiled(core, phys_addr);
4114 }
4115 else{
4116 if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
4117 //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]);
4118 //core->Reg[15] -= get_instr_size(cpu_dyncom);
4119 fill_tlb(cpu);
4120 goto END;
4121 }
4122 if (cpu->syscallSig) {
4123 goto END;
4124 }
4125 if (cpu->abortSig) {
4126 cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
4127 goto END;
4128 }
4129 if (!cpu->NirqSig) {
4130 if (!(cpu->Cpsr & 0x80)) {
4131 goto END;
4132 }
4133 }
4134
4135 /* if regular trap */
4136 cpu->Reg[15] += GET_INST_SIZE(cpu);
4137 /*uint32_t mode = cpu->Cpsr & 0x1f;
4138 if ((mode != cpu->Mode) && (!is_user_mode(core))) {
4139 switch_mode(cpu, mode);
4140 return 1;
4141 }*/
4142
4143 goto END;
4144 }
4145 //phys_addr = cpu->Reg[15];
4146 }
4147 else{
4148 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4149 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4150 else {
4151 /* check next instruction address is valid. */
4152 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4153 if (fault) {
4154 cpu->abortSig = true;
4155 cpu->Aborted = ARMul_PrefetchAbortV;
4156 cpu->AbortAddr = cpu->Reg[15];
4157 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4158 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4159 goto END;
4160 }
4161 last_logical_base = cpu->Reg[15] & 0xfffff000;
4162 last_physical_base = phys_addr & 0xfffff000;
4163 }
4164 }
4165#endif /* #if HYBRID_MODE */
4166#endif /* #if USER_MODE_OPT */
4167 if (true){//if(is_fast_interp_code(core, phys_addr)){
4168 if (find_bb(phys_addr, ptr) == -1)
4169 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4170 goto END;
4171 }
4172 else{
4173 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4174 goto END;
4175 }
4176#if PROFILE
4177 resume_timing();
4178#endif
4179 inst_base = (arm_inst *)&inst_buf[ptr];
4180 GOTO_NEXT_INST;
4181 }
4182 PROFILING:
4183 {
4184 goto DISPATCH;
4185 }
4186 ADC_INST:
4187 {
4188 INC_ICOUNTER;
4189 adc_inst *inst_cream = (adc_inst *)inst_base->component;
4190 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4191 lop = RN;
4192 unsigned int sht_op = SHIFTER_OPERAND;
4193 rop = SHIFTER_OPERAND + cpu->CFlag;
4194 RD = dst = lop + rop;
4195 if (inst_cream->S && (inst_cream->Rd == 15)) {
4196 /* cpsr = spsr */
4197 if (CurrentModeHasSPSR) {
4198 cpu->Cpsr = cpu->Spsr_copy;
4199 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4200 LOAD_NZCVT;
4201 }
4202 } else if (inst_cream->S) {
4203 UPDATE_NFLAG(dst);
4204 UPDATE_ZFLAG(dst);
4205 UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
4206 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4207 }
4208 if (inst_cream->Rd == 15) {
4209 INC_PC(sizeof(adc_inst));
4210 goto PROFILING;
4211 }
4212 }
4213 cpu->Reg[15] += GET_INST_SIZE(cpu);
4214 INC_PC(sizeof(adc_inst));
4215 FETCH_INST;
4216 GOTO_NEXT_INST;
4217 }
4218 ADD_INST:
4219 {
4220 INC_ICOUNTER;
4221 add_inst *inst_cream = (add_inst *)inst_base->component;
4222 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4223 lop = RN;
4224 if (inst_cream->Rn == 15) {
4225 lop += 2 * GET_INST_SIZE(cpu);
4226 }
4227 rop = SHIFTER_OPERAND;
4228 RD = dst = lop + rop;
4229 if (inst_cream->S && (inst_cream->Rd == 15)) {
4230 /* cpsr = spsr*/
4231 if (CurrentModeHasSPSR) {
4232 cpu->Cpsr = cpu->Spsr_copy;
4233 switch_mode(cpu, cpu->Cpsr & 0x1f);
4234 LOAD_NZCVT;
4235 }
4236 } else if (inst_cream->S) {
4237 UPDATE_NFLAG(dst);
4238 UPDATE_ZFLAG(dst);
4239 UPDATE_CFLAG(dst, lop, rop);
4240 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4241 }
4242 if (inst_cream->Rd == 15) {
4243 INC_PC(sizeof(add_inst));
4244 goto PROFILING;
4245 }
4246 }
4247 cpu->Reg[15] += GET_INST_SIZE(cpu);
4248 INC_PC(sizeof(add_inst));
4249 FETCH_INST;
4250 GOTO_NEXT_INST;
4251 }
4252 AND_INST:
4253 {
4254 INC_ICOUNTER;
4255 and_inst *inst_cream = (and_inst *)inst_base->component;
4256 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4257 lop = RN;
4258 rop = SHIFTER_OPERAND;
4259 RD = dst = lop & rop;
4260 if (inst_cream->S && (inst_cream->Rd == 15)) {
4261 /* cpsr = spsr*/
4262 if (CurrentModeHasSPSR) {
4263 cpu->Cpsr = cpu->Spsr_copy;
4264 switch_mode(cpu, cpu->Cpsr & 0x1f);
4265 LOAD_NZCVT;
4266 }
4267 } else if (inst_cream->S) {
4268 UPDATE_NFLAG(dst);
4269 UPDATE_ZFLAG(dst);
4270 UPDATE_CFLAG_WITH_SC;
4271 //UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4272 }
4273 if (inst_cream->Rd == 15) {
4274 INC_PC(sizeof(and_inst));
4275 goto PROFILING;
4276 }
4277 }
4278 cpu->Reg[15] += GET_INST_SIZE(cpu);
4279 INC_PC(sizeof(and_inst));
4280 FETCH_INST;
4281 GOTO_NEXT_INST;
4282 }
4283 BBL_INST:
4284 {
4285 INC_ICOUNTER;
4286 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4287 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
4288 if (inst_cream->L) {
4289 LINK_RTN_ADDR;
4290 }
4291 SET_PC;
4292 INC_PC(sizeof(bbl_inst));
4293 goto PROFILING;
4294 }
4295 cpu->Reg[15] += GET_INST_SIZE(cpu);
4296 INC_PC(sizeof(bbl_inst));
4297 goto PROFILING;
4298 }
4299 BIC_INST:
4300 {
4301 INC_ICOUNTER;
4302 bic_inst *inst_cream = (bic_inst *)inst_base->component;
4303 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4304 lop = RN;
4305 if (inst_cream->Rn == 15) {
4306 lop += 2 * GET_INST_SIZE(cpu);
4307 }
4308 rop = SHIFTER_OPERAND;
4309// RD = dst = lop & (rop ^ 0xffffffff);
4310 RD = dst = lop & (~rop);
4311 if ((inst_cream->S) && (inst_cream->Rd == 15)) {
4312 /* cpsr = spsr */
4313 if (CurrentModeHasSPSR) {
4314 cpu->Cpsr = cpu->Spsr_copy;
4315 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4316 LOAD_NZCVT;
4317 }
4318 } else if (inst_cream->S) {
4319 UPDATE_NFLAG(dst);
4320 UPDATE_ZFLAG(dst);
4321 UPDATE_CFLAG_WITH_SC;
4322 }
4323 if (inst_cream->Rd == 15) {
4324 INC_PC(sizeof(bic_inst));
4325 goto PROFILING;
4326 }
4327 }
4328 cpu->Reg[15] += GET_INST_SIZE(cpu);
4329 INC_PC(sizeof(bic_inst));
4330 FETCH_INST;
4331 GOTO_NEXT_INST;
4332 }
4333 BKPT_INST:
4334 BLX_INST:
4335 {
4336 INC_ICOUNTER;
4337 blx_inst *inst_cream = (blx_inst *)inst_base->component;
4338 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4339 unsigned int inst = inst_cream->inst;
4340 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
4341 //LINK_RTN_ADDR;
4342 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4343 if(cpu->TFlag)
4344 cpu->Reg[14] |= 0x1;
4345 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
4346 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
4347 //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe;
4348 //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1;
4349 } else {
4350 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4351 cpu->TFlag = 0x1;
4352 int signed_int = inst_cream->val.signed_immed_24;
4353 signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
4354 signed_int = signed_int << 2;
4355 // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu)
4356 cpu->Reg[15] = cpu->Reg[15] + 8
4357 + signed_int + (BIT(inst, 24) << 1);
4358 //DEBUG_MSG;
4359 }
4360 INC_PC(sizeof(blx_inst));
4361 goto PROFILING;
4362 }
4363 cpu->Reg[15] += GET_INST_SIZE(cpu);
4364// INC_PC(sizeof(bx_inst));
4365 INC_PC(sizeof(blx_inst));
4366 goto PROFILING;
4367 }
4368 BX_INST:
4369 {
4370 INC_ICOUNTER;
4371 bx_inst *inst_cream = (bx_inst *)inst_base->component;
4372 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4373 if (inst_cream->Rm == 15)
4374 DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]);
4375 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4376 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
4377// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4378 INC_PC(sizeof(bx_inst));
4379 goto PROFILING;
4380 }
4381 cpu->Reg[15] += GET_INST_SIZE(cpu);
4382// INC_PC(sizeof(bx_inst));
4383 INC_PC(sizeof(bx_inst));
4384 goto PROFILING;
4385 }
4386 BXJ_INST:
4387 CDP_INST:
4388 {
4389 INC_ICOUNTER;
4390 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
4391 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4392 /* FIXME, check if cp access allowed */
4393 #define CP_ACCESS_ALLOW 0
4394 if(CP_ACCESS_ALLOW){
4395 /* undefined instruction here */
4396 return;
4397 }
4398 ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
4399 unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
4400 if(cpab != ARMul_DONE){
4401 ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num);
4402 //CITRA_IGNORE_EXIT(-1);
4403 }
4404 }
4405 cpu->Reg[15] += GET_INST_SIZE(cpu);
4406 INC_PC(sizeof(cdp_inst));
4407 FETCH_INST;
4408 GOTO_NEXT_INST;
4409 }
4410
4411 CLREX_INST:
4412 {
4413 INC_ICOUNTER;
4414 remove_exclusive(cpu, 0);
4415 cpu->exclusive_state = 0;
4416
4417 cpu->Reg[15] += GET_INST_SIZE(cpu);
4418 INC_PC(sizeof(clrex_inst));
4419 FETCH_INST;
4420 GOTO_NEXT_INST;
4421 }
4422 CLZ_INST:
4423 {
4424 INC_ICOUNTER;
4425 clz_inst *inst_cream = (clz_inst *)inst_base->component;
4426 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4427 RD = clz(RM);
4428 }
4429 cpu->Reg[15] += GET_INST_SIZE(cpu);
4430 INC_PC(sizeof(clz_inst));
4431 FETCH_INST;
4432 GOTO_NEXT_INST;
4433 }
4434 CMN_INST:
4435 {
4436 INC_ICOUNTER;
4437 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
4438 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4439// DEBUG_LOG(ARM11, "RN is %x\n", RN);
4440 lop = RN;
4441 rop = SHIFTER_OPERAND;
4442 dst = lop + rop;
4443 UPDATE_NFLAG(dst);
4444 UPDATE_ZFLAG(dst);
4445 UPDATE_CFLAG(dst, lop, rop);
4446 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4447 }
4448 cpu->Reg[15] += GET_INST_SIZE(cpu);
4449 INC_PC(sizeof(cmn_inst));
4450 FETCH_INST;
4451 GOTO_NEXT_INST;
4452 }
4453 CMP_INST:
4454 {
4455// DEBUG_LOG(ARM11, "cmp inst\n");
4456// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
4457 INC_ICOUNTER;
4458 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4459// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]);
4460 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
4461 lop = RN;
4462 if (inst_cream->Rn == 15) {
4463 lop += 2 * GET_INST_SIZE(cpu);
4464 }
4465 rop = SHIFTER_OPERAND;
4466 dst = lop - rop;
4467
4468 UPDATE_NFLAG(dst);
4469 UPDATE_ZFLAG(dst);
4470// UPDATE_CFLAG(dst, lop, rop);
4471 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
4472// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4473 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
4474// UPDATE_VFLAG_WITH_NOT(dst, lop, rop);
4475 }
4476 cpu->Reg[15] += GET_INST_SIZE(cpu);
4477 INC_PC(sizeof(cmp_inst));
4478 FETCH_INST;
4479 GOTO_NEXT_INST;
4480 }
4481 CPS_INST:
4482 {
4483 INC_ICOUNTER;
4484 cps_inst *inst_cream = (cps_inst *)inst_base->component;
4485 uint32_t aif_val = 0;
4486 uint32_t aif_mask = 0;
4487 if (InAPrivilegedMode(cpu)) {
4488 /* isInAPrivilegedMode */
4489 if (inst_cream->imod1) {
4490 if (inst_cream->A) {
4491 aif_val |= (inst_cream->imod0 << 8);
4492 aif_mask |= 1 << 8;
4493 }
4494 if (inst_cream->I) {
4495 aif_val |= (inst_cream->imod0 << 7);
4496 aif_mask |= 1 << 7;
4497 }
4498 if (inst_cream->F) {
4499 aif_val |= (inst_cream->imod0 << 6);
4500 aif_mask |= 1 << 6;
4501 }
4502 aif_mask = ~aif_mask;
4503 cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
4504 }
4505 if (inst_cream->mmod) {
4506 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
4507 switch_mode(cpu, inst_cream->mode);
4508 }
4509 }
4510 cpu->Reg[15] += GET_INST_SIZE(cpu);
4511 INC_PC(sizeof(cps_inst));
4512 FETCH_INST;
4513 GOTO_NEXT_INST;
4514 }
4515 CPY_INST:
4516 {
4517 INC_ICOUNTER;
4518 mov_inst *inst_cream = (mov_inst *)inst_base->component;
4519// cpy_inst *inst_cream = (cpy_inst *)inst_base->component;
4520 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4521 RD = SHIFTER_OPERAND;
4522// RD = RM;
4523 if ((inst_cream->Rd == 15)) {
4524 INC_PC(sizeof(mov_inst));
4525 goto PROFILING;
4526 }
4527 }
4528// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]);
4529 cpu->Reg[15] += GET_INST_SIZE(cpu);
4530 INC_PC(sizeof(mov_inst));
4531 FETCH_INST;
4532 GOTO_NEXT_INST;
4533 }
4534 EOR_INST:
4535 {
4536 INC_ICOUNTER;
4537 eor_inst *inst_cream = (eor_inst *)inst_base->component;
4538 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4539 lop = RN;
4540 if (inst_cream->Rn == 15) {
4541 lop += 2 * GET_INST_SIZE(cpu);
4542 }
4543 rop = SHIFTER_OPERAND;
4544 RD = dst = lop ^ rop;
4545 if (inst_cream->S && (inst_cream->Rd == 15)) {
4546 /* cpsr = spsr*/
4547 if (CurrentModeHasSPSR) {
4548 cpu->Cpsr = cpu->Spsr_copy;
4549 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4550 LOAD_NZCVT;
4551 }
4552 } else if (inst_cream->S) {
4553 UPDATE_NFLAG(dst);
4554 UPDATE_ZFLAG(dst);
4555 UPDATE_CFLAG_WITH_SC;
4556// UPDATE_CFLAG(dst, lop, rop);
4557// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4558 }
4559 if (inst_cream->Rd == 15) {
4560 INC_PC(sizeof(eor_inst));
4561 goto PROFILING;
4562 }
4563 }
4564 cpu->Reg[15] += GET_INST_SIZE(cpu);
4565 INC_PC(sizeof(eor_inst));
4566 FETCH_INST;
4567 GOTO_NEXT_INST;
4568 }
4569 LDC_INST:
4570 {
4571 INC_ICOUNTER;
4572 /* NOT IMPL */
4573 cpu->Reg[15] += GET_INST_SIZE(cpu);
4574 INC_PC(sizeof(ldc_inst));
4575 FETCH_INST;
4576 GOTO_NEXT_INST;
4577 }
4578 LDM_INST:
4579 {
4580 INC_ICOUNTER;
4581 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4582 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4583 int i;
4584 unsigned int ret;
4585 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4586 if (fault) {
4587 goto MMU_EXCEPTION;
4588 }
4589 unsigned int inst = inst_cream->inst;
4590 if (BIT(inst, 22) && !BIT(inst, 15)) {
4591// DEBUG_MSG;
4592 #if 1
4593 /* LDM (2) user */
4594 for (i = 0; i < 13; i++) {
4595 if(BIT(inst, i)){
4596 #if 0
4597 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4598 if (fault) {
4599 goto MMU_EXCEPTION;
4600 }
4601 #endif
4602 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4603 //if (fault) goto MMU_EXCEPTION;
4604 cpu->Reg[i] = ret;
4605 addr += 4;
4606 if ((addr & 0xfff) == 0) {
4607 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4608 } else {
4609 phys_addr += 4;
4610 }
4611 }
4612 }
4613 if (BIT(inst, 13)) {
4614 #if 0
4615 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4616 if (fault) {
4617 goto MMU_EXCEPTION;
4618 }
4619 #endif
4620 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4621 //if (fault) goto MMU_EXCEPTION;
4622 if (cpu->Mode == USER32MODE)
4623 cpu->Reg[13] = ret;
4624 else
4625 cpu->Reg_usr[0] = ret;
4626 addr += 4;
4627 if ((addr & 0xfff) == 0) {
4628 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4629 } else {
4630 phys_addr += 4;
4631 }
4632 }
4633 if (BIT(inst, 14)) {
4634 #if 0
4635 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4636 if (fault) {
4637 goto MMU_EXCEPTION;
4638 }
4639 #endif
4640 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4641 //if (fault) goto MMU_EXCEPTION;
4642 if (cpu->Mode == USER32MODE)
4643 cpu->Reg[14] = ret;
4644 else
4645 cpu->Reg_usr[1] = ret;
4646 }
4647 #endif
4648 } else if (!BIT(inst, 22)) {
4649 for( i = 0; i < 16; i ++ ){
4650 if(BIT(inst, i)){
4651 //bus_read(32, addr, &ret);
4652 #if 0
4653 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4654 if (fault) {
4655 goto MMU_EXCEPTION;
4656 }
4657 #endif
4658 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4659 if (fault) goto MMU_EXCEPTION;
4660 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4661 if(i == 15){
4662 cpu->TFlag = ret & 0x1;
4663 ret &= 0xFFFFFFFE;
4664 //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
4665 }
4666
4667 cpu->Reg[i] = ret;
4668 addr += 4;
4669 if ((addr & 0xfff) == 0) {
4670 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4671 } else {
4672 phys_addr += 4;
4673 }
4674 }
4675 }
4676 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4677 for( i = 0; i < 15; i ++ ){
4678 if(BIT(inst, i)){
4679 #if 0
4680 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4681 if (fault) {
4682 goto MMU_EXCEPTION;
4683 }
4684 #endif
4685 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4686 //if (fault) goto MMU_EXCEPTION;
4687 cpu->Reg[i] = ret;
4688 addr += 4;
4689 if ((addr & 0xfff) == 0) {
4690 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4691 } else {
4692 phys_addr += 4;
4693 }
4694 }
4695 }
4696
4697 if (CurrentModeHasSPSR) {
4698 cpu->Cpsr = cpu->Spsr_copy;
4699 switch_mode(cpu, cpu->Cpsr & 0x1f);
4700 LOAD_NZCVT;
4701 }
4702 #if 0
4703 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4704 if (fault) {
4705 goto MMU_EXCEPTION;
4706 }
4707 #endif
4708 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4709 if (fault) {
4710 goto MMU_EXCEPTION;
4711 }
4712 cpu->Reg[15] = ret;
4713 #if 0
4714 addr += 4;
4715 phys_addr += 4;
4716 #endif
4717 }
4718 if (BIT(inst, 15)) {
4719 INC_PC(sizeof(ldst_inst));
4720 goto PROFILING;
4721 }
4722 }
4723 cpu->Reg[15] += GET_INST_SIZE(cpu);
4724 INC_PC(sizeof(ldst_inst));
4725 FETCH_INST;
4726 GOTO_NEXT_INST;
4727 }
4728 SXTH_INST:
4729 {
4730 INC_ICOUNTER;
4731 sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
4732 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4733 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
4734 if (BIT(operand2, 15)) {
4735 operand2 |= 0xffff0000;
4736 } else {
4737 operand2 &= 0xffff;
4738 }
4739 RD = operand2;
4740 }
4741 cpu->Reg[15] += GET_INST_SIZE(cpu);
4742 INC_PC(sizeof(sxth_inst));
4743 FETCH_INST;
4744 GOTO_NEXT_INST;
4745 }
4746 LDR_INST:
4747 {
4748 INC_ICOUNTER;
4749 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4750 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4751 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4752 if (fault) goto MMU_EXCEPTION;
4753 unsigned int value;
4754 //bus_read(32, addr, &value);
4755 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4756 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4757 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4758 else {
4759 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4760 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4761 }
4762 if (BITS(inst_cream->inst, 12, 15) == 15) {
4763 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4764 cpu->TFlag = value & 0x1;
4765 cpu->Reg[15] &= 0xFFFFFFFE;
4766 INC_PC(sizeof(ldst_inst));
4767 goto PROFILING;
4768 }
4769 //}
4770 cpu->Reg[15] += GET_INST_SIZE(cpu);
4771 INC_PC(sizeof(ldst_inst));
4772 FETCH_INST;
4773 GOTO_NEXT_INST;
4774 }
4775 LDRCOND_INST:
4776 {
4777 INC_ICOUNTER;
4778 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4779 if (CondPassed(cpu, inst_base->cond)) {
4780 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4781 if (fault) goto MMU_EXCEPTION;
4782 unsigned int value;
4783 //bus_read(32, addr, &value);
4784 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4785 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4786 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4787 else {
4788 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4789 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4790 }
4791
4792 if (BITS(inst_cream->inst, 12, 15) == 15) {
4793 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4794 cpu->TFlag = value & 0x1;
4795 cpu->Reg[15] &= 0xFFFFFFFE;
4796 INC_PC(sizeof(ldst_inst));
4797 goto PROFILING;
4798 }
4799 }
4800 cpu->Reg[15] += GET_INST_SIZE(cpu);
4801 INC_PC(sizeof(ldst_inst));
4802 FETCH_INST;
4803 GOTO_NEXT_INST;
4804 }
4805 UXTH_INST:
4806 {
4807 INC_ICOUNTER;
4808 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
4809 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4810 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4811 & 0xffff;
4812 RD = operand2;
4813 }
4814 cpu->Reg[15] += GET_INST_SIZE(cpu);
4815 INC_PC(sizeof(uxth_inst));
4816 FETCH_INST;
4817 GOTO_NEXT_INST;
4818 }
4819 UXTAH_INST:
4820 {
4821 INC_ICOUNTER;
4822 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
4823 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4824 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4825 & 0xffff;
4826 RD = RN + operand2;
4827 if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
4828 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
4829 CITRA_IGNORE_EXIT(-1);
4830 }
4831 }
4832 cpu->Reg[15] += GET_INST_SIZE(cpu);
4833 INC_PC(sizeof(uxtah_inst));
4834 FETCH_INST;
4835 GOTO_NEXT_INST;
4836 }
4837 LDRB_INST:
4838 {
4839 INC_ICOUNTER;
4840 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4841 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4842 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4843 if (fault) goto MMU_EXCEPTION;
4844 unsigned int value;
4845 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4846 if (fault) goto MMU_EXCEPTION;
4847 //bus_read(8, addr, &value);
4848 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4849 if (BITS(inst_cream->inst, 12, 15) == 15) {
4850 INC_PC(sizeof(ldst_inst));
4851 goto PROFILING;
4852 }
4853 }
4854 cpu->Reg[15] += GET_INST_SIZE(cpu);
4855 INC_PC(sizeof(ldst_inst));
4856 FETCH_INST;
4857 GOTO_NEXT_INST;
4858 }
4859 LDRBT_INST:
4860 {
4861 INC_ICOUNTER;
4862 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4863 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4864 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4865 if (fault) goto MMU_EXCEPTION;
4866 unsigned int value;
4867 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4868 if (fault) goto MMU_EXCEPTION;
4869 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4870 if (BITS(inst_cream->inst, 12, 15) == 15) {
4871 INC_PC(sizeof(ldst_inst));
4872 goto PROFILING;
4873 }
4874 }
4875 cpu->Reg[15] += GET_INST_SIZE(cpu);
4876 INC_PC(sizeof(ldst_inst));
4877 FETCH_INST;
4878 GOTO_NEXT_INST;
4879 }
4880 LDRD_INST:
4881 {
4882 INC_ICOUNTER;
4883 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4884 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4885 /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */
4886 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4887 if (fault) goto MMU_EXCEPTION;
4888 uint32_t rear_phys_addr;
4889 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
4890 if(fault){
4891 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
4892 CITRA_IGNORE_EXIT(-1);
4893 goto MMU_EXCEPTION;
4894 }
4895 unsigned int value;
4896 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4897 if (fault) goto MMU_EXCEPTION;
4898 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4899 fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
4900 if (fault) goto MMU_EXCEPTION;
4901 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
4902 /* No dispatch since this operation should not modify R15 */
4903 }
4904 cpu->Reg[15] += 4;
4905 INC_PC(sizeof(ldst_inst));
4906 FETCH_INST;
4907 GOTO_NEXT_INST;
4908 }
4909
4910 LDREX_INST:
4911 {
4912 INC_ICOUNTER;
4913 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4914 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4915 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4916 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4917 if (fault) goto MMU_EXCEPTION;
4918 unsigned int value;
4919 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4920 if (fault) goto MMU_EXCEPTION;
4921
4922 add_exclusive_addr(cpu, phys_addr);
4923 cpu->exclusive_state = 1;
4924
4925 //bus_read(32, addr, &value);
4926 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4927 if (BITS(inst_cream->inst, 12, 15) == 15) {
4928 INC_PC(sizeof(ldst_inst));
4929 goto PROFILING;
4930 }
4931 }
4932 cpu->Reg[15] += GET_INST_SIZE(cpu);
4933 INC_PC(sizeof(ldst_inst));
4934 FETCH_INST;
4935 GOTO_NEXT_INST;
4936 }
4937 LDREXB_INST:
4938 {
4939 INC_ICOUNTER;
4940 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4941 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4942 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4943 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4944 if (fault) goto MMU_EXCEPTION;
4945 unsigned int value;
4946 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4947 if (fault) goto MMU_EXCEPTION;
4948
4949 add_exclusive_addr(cpu, phys_addr);
4950 cpu->exclusive_state = 1;
4951
4952 //bus_read(8, addr, &value);
4953 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4954 if (BITS(inst_cream->inst, 12, 15) == 15) {
4955 INC_PC(sizeof(ldst_inst));
4956 goto PROFILING;
4957 }
4958 }
4959 cpu->Reg[15] += GET_INST_SIZE(cpu);
4960 INC_PC(sizeof(ldst_inst));
4961 FETCH_INST;
4962 GOTO_NEXT_INST;
4963 }
4964 LDRH_INST:
4965 {
4966 INC_ICOUNTER;
4967 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4968 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4969 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4970 if (fault) goto MMU_EXCEPTION;
4971 unsigned int value = 0;
4972 fault = interpreter_read_memory(addr, phys_addr, value, 16);
4973// fault = interpreter_read_memory(addr, value, 32);
4974 if (fault) goto MMU_EXCEPTION;
4975 //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) {
4976 // value = 0xffffffff;
4977 //}
4978 //bus_read(16, addr, &value);
4979// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff;
4980 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4981 if (BITS(inst_cream->inst, 12, 15) == 15) {
4982 INC_PC(sizeof(ldst_inst));
4983 goto PROFILING;
4984 }
4985 }
4986 cpu->Reg[15] += GET_INST_SIZE(cpu);
4987 INC_PC(sizeof(ldst_inst));
4988 FETCH_INST;
4989 GOTO_NEXT_INST;
4990 }
4991 LDRSB_INST:
4992 {
4993 INC_ICOUNTER;
4994 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4995 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4996 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4997 if (fault) goto MMU_EXCEPTION;
4998 unsigned int value;
4999// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr);
5000 fault = interpreter_read_memory(addr, phys_addr, value, 8);
5001 if (fault) goto MMU_EXCEPTION;
5002 //bus_read(8, addr, &value);
5003 if (BIT(value, 7)) {
5004 value |= 0xffffff00;
5005 }
5006 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5007 if (BITS(inst_cream->inst, 12, 15) == 15) {
5008 INC_PC(sizeof(ldst_inst));
5009 goto PROFILING;
5010 }
5011 }
5012 cpu->Reg[15] += GET_INST_SIZE(cpu);
5013 INC_PC(sizeof(ldst_inst));
5014 FETCH_INST;
5015 GOTO_NEXT_INST;
5016 }
5017 LDRSH_INST:
5018 {
5019 INC_ICOUNTER;
5020 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5021 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5022 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5023 if (fault) goto MMU_EXCEPTION;
5024 unsigned int value;
5025 fault = interpreter_read_memory(addr, phys_addr, value, 16);
5026 if (fault) goto MMU_EXCEPTION;
5027 //bus_read(16, addr, &value);
5028 if (BIT(value, 15)) {
5029 value |= 0xffff0000;
5030 }
5031 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5032 if (BITS(inst_cream->inst, 12, 15) == 15) {
5033 INC_PC(sizeof(ldst_inst));
5034 goto PROFILING;
5035 }
5036 }
5037 cpu->Reg[15] += GET_INST_SIZE(cpu);
5038 INC_PC(sizeof(ldst_inst));
5039 FETCH_INST;
5040 GOTO_NEXT_INST;
5041 }
5042 LDRT_INST:
5043 {
5044 INC_ICOUNTER;
5045 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5046 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5047 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5048 if (fault) goto MMU_EXCEPTION;
5049 unsigned int value;
5050 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5051 if (fault) goto MMU_EXCEPTION;
5052 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5053
5054 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
5055 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5056 else
5057 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
5058
5059 if (BITS(inst_cream->inst, 12, 15) == 15) {
5060 INC_PC(sizeof(ldst_inst));
5061 goto PROFILING;
5062 }
5063 }
5064 cpu->Reg[15] += GET_INST_SIZE(cpu);
5065 INC_PC(sizeof(ldst_inst));
5066 FETCH_INST;
5067 GOTO_NEXT_INST;
5068 }
5069 MCR_INST:
5070 {
5071 INC_ICOUNTER;
5072 /* NOT IMPL */
5073 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
5074 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5075 unsigned int inst = inst_cream->inst;
5076 if (inst_cream->Rd == 15) {
5077 DEBUG_MSG;
5078 } else {
5079 if (inst_cream->cp_num == 15) {
5080 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5081 //LET(RD, CONST(0x0007b000));
5082 //LET(RD, CONST(0x410FB760));
5083 //LET(CP15_MAIN_ID, R(RD));
5084 CP15_REG(CP15_MAIN_ID) = RD;
5085 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5086 //LET(RD, R(CP15_CONTROL));
5087 CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
5088 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5089 //LET(RD, R(CP15_CONTROL));
5090 CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
5091 } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5092 //LET(CP15_CONTROL, R(RD));
5093 CP15_REG(CP15_CONTROL) = RD;
5094 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5095 //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD));
5096 CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
5097 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5098 //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD));
5099 CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
5100 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
5101 //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD));
5102 CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
5103 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
5104 //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD));
5105 CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
5106 } else if(CRn == MMU_CACHE_OPS){
5107 //SKYEYE_WARNING("cache operation have not implemented.\n");
5108 } else if(CRn == MMU_TLB_OPS){
5109 switch (CRm) {
5110 case 5: /* ITLB */
5111 switch(OPCODE_2){
5112 case 0: /* invalidate all */
5113 //invalidate_all_tlb(state);
5114 DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n");
5115 //remove_tlb(INSN_TLB);
5116 //erase_all(core, INSN_TLB);
5117 break;
5118 case 1: /* invalidate by MVA */
5119 //invalidate_by_mva(state, value);
5120 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n");
5121 //remove_tlb_by_mva(RD, INSN_TLB);
5122 //erase_by_mva(core, RD, INSN_TLB);
5123 break;
5124 case 2: /* invalidate by asid */
5125 //invalidate_by_asid(state, value);
5126 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n");
5127 //erase_by_asid(core, RD, INSN_TLB);
5128 break;
5129 default:
5130 break;
5131 }
5132
5133 break;
5134 case 6: /* DTLB */
5135 switch(OPCODE_2){
5136 case 0: /* invalidate all */
5137 //invalidate_all_tlb(state);
5138 //remove_tlb(DATA_TLB);
5139 //erase_all(core, DATA_TLB);
5140 DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n");
5141 break;
5142 case 1: /* invalidate by MVA */
5143 //invalidate_by_mva(state, value);
5144 //remove_tlb_by_mva(RD, DATA_TLB);
5145 //erase_by_mva(core, RD, DATA_TLB);
5146 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n");
5147 break;
5148 case 2: /* invalidate by asid */
5149 //invalidate_by_asid(state, value);
5150 //remove_tlb_by_asid(RD, DATA_TLB);
5151 //erase_by_asid(core, RD, DATA_TLB);
5152 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n");
5153 break;
5154 default:
5155 break;
5156 }
5157 break;
5158 case 7: /* UNIFILED TLB */
5159 switch(OPCODE_2){
5160 case 0: /* invalidate all */
5161 //invalidate_all_tlb(state);
5162 //erase_all(core, INSN_TLB);
5163 //erase_all(core, DATA_TLB);
5164 //remove_tlb(DATA_TLB);
5165 //remove_tlb(INSN_TLB);
5166 //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n");
5167 break;
5168 case 1: /* invalidate by MVA */
5169 //invalidate_by_mva(state, value);
5170 //erase_by_mva(core, RD, DATA_TLB);
5171 //erase_by_mva(core, RD, INSN_TLB);
5172 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n");
5173 break;
5174 case 2: /* invalidate by asid */
5175 //invalidate_by_asid(state, value);
5176 //erase_by_asid(core, RD, DATA_TLB);
5177 //erase_by_asid(core, RD, INSN_TLB);
5178 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n");
5179 break;
5180 default:
5181 break;
5182 }
5183 break;
5184 default:
5185 break;
5186 }
5187 } else if(CRn == MMU_PID){
5188 if(OPCODE_2 == 0)
5189 CP15_REG(CP15_PID) = RD;
5190 else if(OPCODE_2 == 1)
5191 CP15_REG(CP15_CONTEXT_ID) = RD;
5192 else if(OPCODE_2 == 3){
5193 CP15_REG(CP15_THREAD_URO) = RD;
5194 }
5195 else{
5196 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn);
5197 }
5198
5199 } else {
5200 DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5201 }
5202 }
5203 }
5204 }
5205 cpu->Reg[15] += GET_INST_SIZE(cpu);
5206 INC_PC(sizeof(mcr_inst));
5207 FETCH_INST;
5208 GOTO_NEXT_INST;
5209 }
5210 MCRR_INST:
5211 MLA_INST:
5212 {
5213 INC_ICOUNTER;
5214 mla_inst *inst_cream = (mla_inst *)inst_base->component;
5215 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5216 uint64_t rm = RM;
5217 uint64_t rs = RS;
5218 uint64_t rn = RN;
5219 if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
5220 DEBUG_LOG(ARM11, "in __line__\n", __LINE__);
5221 CITRA_IGNORE_EXIT(-1);
5222 }
5223// RD = dst = RM * RS + RN;
5224 RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
5225 if (inst_cream->S) {
5226 UPDATE_NFLAG(dst);
5227 UPDATE_ZFLAG(dst);
5228 }
5229 if (inst_cream->Rd == 15) {
5230 INC_PC(sizeof(mla_inst));
5231 goto PROFILING;
5232 }
5233 }
5234 cpu->Reg[15] += GET_INST_SIZE(cpu);
5235 INC_PC(sizeof(mla_inst));
5236 FETCH_INST;
5237 GOTO_NEXT_INST;
5238 }
5239 MOV_INST:
5240 {
5241// DEBUG_LOG(ARM11, "mov inst\n");
5242// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
5243// debug_function(cpu);
5244// cpu->icount ++;
5245 INC_ICOUNTER;
5246 mov_inst *inst_cream = (mov_inst *)inst_base->component;
5247 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5248 RD = dst = SHIFTER_OPERAND;
5249 if (inst_cream->S && (inst_cream->Rd == 15)) {
5250 /* cpsr = spsr */
5251 if (CurrentModeHasSPSR) {
5252 cpu->Cpsr = cpu->Spsr_copy;
5253 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5254 LOAD_NZCVT;
5255 }
5256 } else if (inst_cream->S) {
5257 UPDATE_NFLAG(dst);
5258 UPDATE_ZFLAG(dst);
5259 UPDATE_CFLAG_WITH_SC;
5260 }
5261 if (inst_cream->Rd == 15) {
5262 INC_PC(sizeof(mov_inst));
5263 goto PROFILING;
5264 }
5265// return;
5266 }
5267 cpu->Reg[15] += GET_INST_SIZE(cpu);
5268 INC_PC(sizeof(mov_inst));
5269 FETCH_INST;
5270 GOTO_NEXT_INST;
5271 }
5272 MRC_INST:
5273 {
5274 INC_ICOUNTER;
5275 /* NOT IMPL */
5276 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
5277 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5278 unsigned int inst = inst_cream->inst;
5279 if (inst_cream->Rd == 15) {
5280 DEBUG_MSG;
5281 }
5282 if (inst_cream->inst == 0xeef04a10) {
5283 /* undefined instruction fmrx */
5284 RD = 0x20000000;
5285 CITRA_IGNORE_EXIT(-1);
5286 goto END;
5287 } else {
5288 if (inst_cream->cp_num == 15) {
5289 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5290 //LET(RD, CONST(0x0007b000));
5291 //LET(RD, CONST(0x410FB760));
5292 //LET(RD, R(CP15_MAIN_ID));
5293 RD = cpu->CP15[CP15(CP15_MAIN_ID)];
5294 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5295 //LET(RD, R(CP15_CONTROL));
5296 RD = cpu->CP15[CP15(CP15_CONTROL)];
5297 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5298 //LET(RD, R(CP15_CONTROL));
5299 RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
5300 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5301 //LET(RD, R(CP15_CONTROL));
5302 RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
5303 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5304 //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL));
5305 RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
5306 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5307 //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0));
5308 RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
5309 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
5310 //LET(RD, R(CP15_FAULT_STATUS));
5311 RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
5312 } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
5313 //LET(RD, R(CP15_FAULT_ADDRESS));
5314 RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
5315 } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
5316 //LET(RD, R(CP15_CACHE_TYPE));
5317 RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
5318 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
5319 //LET(RD, R(CP15_INSTR_FAULT_STATUS));
5320 RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
5321 } else if (CRn == 13) {
5322 if(OPCODE_2 == 0)
5323 RD = CP15_REG(CP15_PID);
5324 else if(OPCODE_2 == 1)
5325 RD = CP15_REG(CP15_CONTEXT_ID);
5326 else if(OPCODE_2 == 3){
5327 RD = Memory::KERNEL_MEMORY_VADDR;
5328 }
5329 else{
5330 printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn);
5331 }
5332 }
5333 else {
5334 DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5335 }
5336 }
5337 //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5338 }
5339 }
5340 cpu->Reg[15] += GET_INST_SIZE(cpu);
5341 INC_PC(sizeof(mrc_inst));
5342 FETCH_INST;
5343 GOTO_NEXT_INST;
5344 }
5345 MRRC_INST:
5346 MRS_INST:
5347 {
5348 INC_ICOUNTER;
5349 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
5350 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5351 if (inst_cream->R) {
5352 RD = cpu->Spsr_copy;
5353 } else {
5354 SAVE_NZCVT;
5355 RD = cpu->Cpsr;
5356 }
5357 }
5358 cpu->Reg[15] += GET_INST_SIZE(cpu);
5359 INC_PC(sizeof(mrs_inst));
5360 FETCH_INST;
5361 GOTO_NEXT_INST;
5362 }
5363 MSR_INST:
5364 {
5365 INC_ICOUNTER;
5366 msr_inst *inst_cream = (msr_inst *)inst_base->component;
5367 const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
5368 unsigned int inst = inst_cream->inst;
5369 unsigned int operand;
5370
5371 if (BIT(inst, 25)) {
5372 int rot_imm = BITS(inst, 8, 11) * 2;
5373 //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm));
5374 operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
5375 } else {
5376 //operand = R(RM);
5377 operand = cpu->Reg[BITS(inst, 0, 3)];
5378 }
5379 uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
5380 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
5381 uint32_t mask;
5382 if (!inst_cream->R) {
5383 if (InAPrivilegedMode(cpu)) {
5384 if ((operand & StateMask) != 0) {
5385 /* UNPREDICTABLE */
5386 DEBUG_MSG;
5387 } else
5388 mask = byte_mask & (UserMask | PrivMask);
5389 } else {
5390 mask = byte_mask & UserMask;
5391 }
5392 //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5393 SAVE_NZCVT;
5394
5395 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
5396 switch_mode(cpu, cpu->Cpsr & 0x1f);
5397 LOAD_NZCVT;
5398 } else {
5399 if (CurrentModeHasSPSR) {
5400 mask = byte_mask & (UserMask | PrivMask | StateMask);
5401 //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5402 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
5403 }
5404 }
5405 cpu->Reg[15] += GET_INST_SIZE(cpu);
5406 INC_PC(sizeof(msr_inst));
5407 FETCH_INST;
5408 GOTO_NEXT_INST;
5409 }
5410 MUL_INST:
5411 {
5412 INC_ICOUNTER;
5413 mul_inst *inst_cream = (mul_inst *)inst_base->component;
5414 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5415// RD = dst = SHIFTER_OPERAND;
5416 uint64_t rm = RM;
5417 uint64_t rs = RS;
5418 RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
5419 if (inst_cream->S) {
5420 UPDATE_NFLAG(dst);
5421 UPDATE_ZFLAG(dst);
5422 }
5423 if (inst_cream->Rd == 15) {
5424 INC_PC(sizeof(mul_inst));
5425 goto PROFILING;
5426 }
5427 }
5428 cpu->Reg[15] += GET_INST_SIZE(cpu);
5429 INC_PC(sizeof(mul_inst));
5430 FETCH_INST;
5431 GOTO_NEXT_INST;
5432 }
5433 MVN_INST:
5434 {
5435 INC_ICOUNTER;
5436 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
5437 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5438// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff);
5439 RD = dst = ~SHIFTER_OPERAND;
5440 if (inst_cream->S && (inst_cream->Rd == 15)) {
5441 /* cpsr = spsr */
5442 if (CurrentModeHasSPSR) {
5443 cpu->Cpsr = cpu->Spsr_copy;
5444 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5445 LOAD_NZCVT;
5446 }
5447 } else if (inst_cream->S) {
5448 UPDATE_NFLAG(dst);
5449 UPDATE_ZFLAG(dst);
5450 UPDATE_CFLAG_WITH_SC;
5451 }
5452 if (inst_cream->Rd == 15) {
5453 INC_PC(sizeof(mvn_inst));
5454 goto PROFILING;
5455 }
5456 }
5457 cpu->Reg[15] += GET_INST_SIZE(cpu);
5458 INC_PC(sizeof(mvn_inst));
5459 FETCH_INST;
5460 GOTO_NEXT_INST;
5461 }
5462 ORR_INST:
5463 {
5464 INC_ICOUNTER;
5465 orr_inst *inst_cream = (orr_inst *)inst_base->component;
5466 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5467 lop = RN;
5468 rop = SHIFTER_OPERAND;
5469// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]);
5470 RD = dst = lop | rop;
5471 if (inst_cream->S && (inst_cream->Rd == 15)) {
5472 /* cpsr = spsr*/
5473 if (CurrentModeHasSPSR) {
5474 cpu->Cpsr = cpu->Spsr_copy;
5475 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5476 LOAD_NZCVT;
5477 }
5478 } else if (inst_cream->S) {
5479 UPDATE_NFLAG(dst);
5480 UPDATE_ZFLAG(dst);
5481 UPDATE_CFLAG_WITH_SC;
5482// UPDATE_CFLAG(dst, lop, rop);
5483 }
5484 if (inst_cream->Rd == 15) {
5485 INC_PC(sizeof(orr_inst));
5486 goto PROFILING;
5487 }
5488 }
5489 cpu->Reg[15] += GET_INST_SIZE(cpu);
5490 INC_PC(sizeof(orr_inst));
5491 FETCH_INST;
5492 GOTO_NEXT_INST;
5493 }
5494 PKHBT_INST:
5495 PKHTB_INST:
5496 PLD_INST:
5497 {
5498 INC_ICOUNTER;
5499 /* NOT IMPL */
5500 cpu->Reg[15] += GET_INST_SIZE(cpu);
5501 INC_PC(sizeof(stc_inst));
5502 FETCH_INST;
5503 GOTO_NEXT_INST;
5504 }
5505 QADD_INST:
5506 QADD16_INST:
5507 QADD8_INST:
5508 QADDSUBX_INST:
5509 QDADD_INST:
5510 QDSUB_INST:
5511 QSUB_INST:
5512 QSUB16_INST:
5513 QSUB8_INST:
5514 QSUBADDX_INST:
5515 REV_INST:
5516 {
5517 INC_ICOUNTER;
5518 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5519 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5520 RD = ((RM & 0xff) << 24) |
5521 (((RM >> 8) & 0xff) << 16) |
5522 (((RM >> 16) & 0xff) << 8) |
5523 ((RM >> 24) & 0xff);
5524 if (inst_cream->Rm == 15) {
5525 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
5526 CITRA_IGNORE_EXIT(-1);
5527 }
5528 }
5529 cpu->Reg[15] += GET_INST_SIZE(cpu);
5530 INC_PC(sizeof(rev_inst));
5531 FETCH_INST;
5532 GOTO_NEXT_INST;
5533 }
5534 REV16_INST:
5535 {
5536 INC_ICOUNTER;
5537 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5538 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5539 RD = (BITS(RM, 0, 7) << 8) |
5540 BITS(RM, 8, 15) |
5541 (BITS(RM, 16, 23) << 24) |
5542 (BITS(RM, 24, 31) << 16);
5543 }
5544 cpu->Reg[15] += GET_INST_SIZE(cpu);
5545 INC_PC(sizeof(rev_inst));
5546 FETCH_INST;
5547 GOTO_NEXT_INST;
5548 }
5549 REVSH_INST:
5550 RFE_INST:
5551 RSB_INST:
5552 {
5553 INC_ICOUNTER;
5554 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
5555 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5556 rop = RN;
5557 lop = SHIFTER_OPERAND;
5558 if (inst_cream->Rn == 15) {
5559 rop += 2 * GET_INST_SIZE(cpu);;
5560 }
5561 RD = dst = lop - rop;
5562 if (inst_cream->S && (inst_cream->Rd == 15)) {
5563 /* cpsr = spsr */
5564 if (CurrentModeHasSPSR) {
5565 cpu->Cpsr = cpu->Spsr_copy;
5566 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5567 LOAD_NZCVT;
5568 }
5569 } else if (inst_cream->S) {
5570 UPDATE_NFLAG(dst);
5571 UPDATE_ZFLAG(dst);
5572 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
5573// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
5574 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
5575 }
5576 if (inst_cream->Rd == 15) {
5577 INC_PC(sizeof(rsb_inst));
5578 goto PROFILING;
5579 }
5580 }
5581 cpu->Reg[15] += GET_INST_SIZE(cpu);
5582 INC_PC(sizeof(rsb_inst));
5583 FETCH_INST;
5584 GOTO_NEXT_INST;
5585 }
5586 RSC_INST:
5587 {
5588 INC_ICOUNTER;
5589 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
5590 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5591 //lop = RN + !cpu->CFlag;
5592 //rop = SHIFTER_OPERAND;
5593 //RD = dst = rop - lop;
5594 lop = RN;
5595 rop = SHIFTER_OPERAND;
5596 RD = dst = rop - lop - !cpu->CFlag;
5597 if (inst_cream->S && (inst_cream->Rd == 15)) {
5598 /* cpsr = spsr */
5599 if (CurrentModeHasSPSR) {
5600 cpu->Cpsr = cpu->Spsr_copy;
5601 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5602 LOAD_NZCVT;
5603 }
5604 } else if (inst_cream->S) {
5605 UPDATE_NFLAG(dst);
5606 UPDATE_ZFLAG(dst);
5607// UPDATE_CFLAG(dst, lop, rop);
5608// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5609 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
5610// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5611 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
5612 }
5613 if (inst_cream->Rd == 15) {
5614 INC_PC(sizeof(rsc_inst));
5615 goto PROFILING;
5616 }
5617 }
5618 cpu->Reg[15] += GET_INST_SIZE(cpu);
5619 INC_PC(sizeof(rsc_inst));
5620 FETCH_INST;
5621 GOTO_NEXT_INST;
5622 }
5623 SADD16_INST:
5624 SADD8_INST:
5625 SADDSUBX_INST:
5626 SBC_INST:
5627 {
5628 INC_ICOUNTER;
5629 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
5630 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5631 lop = SHIFTER_OPERAND + !cpu->CFlag;
5632 rop = RN;
5633 RD = dst = rop - lop;
5634 if (inst_cream->S && (inst_cream->Rd == 15)) {
5635 /* cpsr = spsr */
5636 if (CurrentModeHasSPSR) {
5637 cpu->Cpsr = cpu->Spsr_copy;
5638 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5639 LOAD_NZCVT;
5640 }
5641 } else if (inst_cream->S) {
5642 UPDATE_NFLAG(dst);
5643 UPDATE_ZFLAG(dst);
5644// UPDATE_CFLAG(dst, lop, rop);
5645 //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5646 //rop = rop - !cpu->CFlag;
5647 if(rop >= !cpu->CFlag)
5648 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
5649 else
5650 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
5651// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5652 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
5653 }
5654 if (inst_cream->Rd == 15) {
5655 INC_PC(sizeof(sbc_inst));
5656 goto PROFILING;
5657 }
5658 }
5659 cpu->Reg[15] += GET_INST_SIZE(cpu);
5660 INC_PC(sizeof(sbc_inst));
5661 FETCH_INST;
5662 GOTO_NEXT_INST;
5663 }
5664 SEL_INST:
5665 SETEND_INST:
5666 SHADD16_INST:
5667 SHADD8_INST:
5668 SHADDSUBX_INST:
5669 SHSUB16_INST:
5670 SHSUB8_INST:
5671 SHSUBADDX_INST:
5672 SMLA_INST:
5673 {
5674 INC_ICOUNTER;
5675 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5676 smla_inst *inst_cream = (smla_inst *)inst_base->component;
5677 int32_t operand1, operand2;
5678 if (inst_cream->x == 0)
5679 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5680 else
5681 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5682
5683 if (inst_cream->y == 0)
5684 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5685 else
5686 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5687 RD = operand1 * operand2 + RN;
5688 //FIXME: UPDATE Q FLAGS
5689 }
5690 cpu->Reg[15] += GET_INST_SIZE(cpu);
5691 INC_PC(sizeof(smla_inst));
5692 FETCH_INST;
5693 GOTO_NEXT_INST;
5694 }
5695 SMLAD_INST:
5696 {
5697 INC_ICOUNTER;
5698 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5699 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5700 long long int rm = cpu->Reg[inst_cream->Rm];
5701 long long int rn = cpu->Reg[inst_cream->Rn];
5702 long long int ra = cpu->Reg[inst_cream->Ra];
5703 /* see SMUAD */
5704 if(inst_cream->Ra == 15)
5705 CITRA_IGNORE_EXIT(-1);
5706 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
5707
5708 int half_rn, half_operand2;
5709 half_rn = rn & 0xFFFF;
5710 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5711
5712 half_operand2 = operand2 & 0xFFFF;
5713 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5714
5715 long long int product1 = half_rn * half_operand2;
5716
5717 half_rn = (rn & 0xFFFF0000) >> 16;
5718 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5719
5720 half_operand2 = (operand2 & 0xFFFF0000) >> 16;
5721 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5722
5723 long long int product2 = half_rn * half_operand2;
5724
5725 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
5726 long long int result = product1 + product2 + signed_ra;
5727 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
5728 /* FIXME , should check Signed overflow */
5729 }
5730 cpu->Reg[15] += GET_INST_SIZE(cpu);
5731 INC_PC(sizeof(umlal_inst));
5732 FETCH_INST;
5733 GOTO_NEXT_INST;
5734 }
5735
5736 SMLAL_INST:
5737 {
5738 INC_ICOUNTER;
5739 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5740 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
5741 long long int rm = RM;
5742 long long int rs = RS;
5743 if (BIT(rm, 31)) {
5744 rm |= 0xffffffff00000000LL;
5745 }
5746 if (BIT(rs, 31)) {
5747 rs |= 0xffffffff00000000LL;
5748 }
5749 long long int rst = rm * rs;
5750 long long int rdhi32 = RDHI;
5751 long long int hilo = (rdhi32 << 32) + RDLO;
5752 rst += hilo;
5753 RDLO = BITS(rst, 0, 31);
5754 RDHI = BITS(rst, 32, 63);
5755 if (inst_cream->S) {
5756 cpu->NFlag = BIT(RDHI, 31);
5757 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5758 }
5759 }
5760 cpu->Reg[15] += GET_INST_SIZE(cpu);
5761 INC_PC(sizeof(umlal_inst));
5762 FETCH_INST;
5763 GOTO_NEXT_INST;
5764 }
5765 SMLALXY_INST:
5766 SMLALD_INST:
5767 SMLAW_INST:
5768 SMLSD_INST:
5769 SMLSLD_INST:
5770 SMMLA_INST:
5771 SMMLS_INST:
5772 SMMUL_INST:
5773 SMUAD_INST:
5774 SMUL_INST:
5775 {
5776 INC_ICOUNTER;
5777 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5778 smul_inst *inst_cream = (smul_inst *)inst_base->component;
5779 uint32_t operand1, operand2;
5780 if (inst_cream->x == 0)
5781 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5782 else
5783 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5784
5785 if (inst_cream->y == 0)
5786 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5787 else
5788 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5789 RD = operand1 * operand2;
5790 }
5791 cpu->Reg[15] += GET_INST_SIZE(cpu);
5792 INC_PC(sizeof(smul_inst));
5793 FETCH_INST;
5794 GOTO_NEXT_INST;
5795 }
5796 SMULL_INST:
5797 {
5798 INC_ICOUNTER;
5799 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5800 umull_inst *inst_cream = (umull_inst *)inst_base->component;
5801// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5802 int64_t rm = RM;
5803 int64_t rs = RS;
5804 if (BIT(rm, 31)) {
5805 rm |= 0xffffffff00000000LL;
5806 }
5807 if (BIT(rs, 31)) {
5808 rs |= 0xffffffff00000000LL;
5809 }
5810 int64_t rst = rm * rs;
5811 RDHI = BITS(rst, 32, 63);
5812 RDLO = BITS(rst, 0, 31);
5813
5814
5815 if (inst_cream->S) {
5816 cpu->NFlag = BIT(RDHI, 31);
5817 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5818 }
5819 }
5820 cpu->Reg[15] += GET_INST_SIZE(cpu);
5821 INC_PC(sizeof(umull_inst));
5822 FETCH_INST;
5823 GOTO_NEXT_INST;
5824 }
5825 SMULW_INST:
5826 INC_ICOUNTER;
5827 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5828 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5829// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5830 int64_t rm = RM;
5831 int64_t rn = RN;
5832 if (inst_cream->m)
5833 rm = BITS(rm,16 , 31);
5834 else
5835 rm = BITS(rm,0 , 15);
5836 int64_t rst = rm * rn;
5837 RD = BITS(rst, 16, 47);
5838 }
5839 cpu->Reg[15] += GET_INST_SIZE(cpu);
5840 INC_PC(sizeof(smlad_inst));
5841 FETCH_INST;
5842 GOTO_NEXT_INST;
5843
5844 SMUSD_INST:
5845 SRS_INST:
5846 SSAT_INST:
5847 SSAT16_INST:
5848 SSUB16_INST:
5849 SSUB8_INST:
5850 SSUBADDX_INST:
5851 STC_INST:
5852 {
5853 INC_ICOUNTER;
5854 /* NOT IMPL */
5855 cpu->Reg[15] += GET_INST_SIZE(cpu);
5856 INC_PC(sizeof(stc_inst));
5857 FETCH_INST;
5858 GOTO_NEXT_INST;
5859 }
5860 STM_INST:
5861 {
5862 INC_ICOUNTER;
5863 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5864 unsigned int inst = inst_cream->inst;
5865 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5866 int i;
5867 unsigned int Rn = BITS(inst, 16, 19);
5868 unsigned int old_RN = cpu->Reg[Rn];
5869
5870 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5871 if (fault) goto MMU_EXCEPTION;
5872 if (BIT(inst_cream->inst, 22) == 1) {
5873// DEBUG_MSG;
5874 #if 1
5875 for (i = 0; i < 13; i++) {
5876 if(BIT(inst_cream->inst, i)){
5877 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5878 if (fault) {
5879 goto MMU_EXCEPTION;
5880 }
5881 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5882 if (fault) goto MMU_EXCEPTION;
5883 addr += 4;
5884 phys_addr += 4;
5885 }
5886 }
5887 if (BIT(inst_cream->inst, 13)) {
5888 if (cpu->Mode == USER32MODE) {
5889 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5890 if (fault) {
5891 goto MMU_EXCEPTION;
5892 }
5893 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5894 if (fault) goto MMU_EXCEPTION;
5895 addr += 4;
5896 phys_addr += 4;
5897 } else {
5898 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
5899 if (fault) goto MMU_EXCEPTION;
5900 addr += 4;
5901 phys_addr += 4;
5902 }
5903 }
5904 if (BIT(inst_cream->inst, 14)) {
5905 if (cpu->Mode == USER32MODE) {
5906 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5907 if (fault) {
5908 goto MMU_EXCEPTION;
5909 }
5910 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5911 if (fault) goto MMU_EXCEPTION;
5912 addr += 4;
5913 phys_addr += 4;
5914 } else {
5915 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5916 if (fault) {
5917 goto MMU_EXCEPTION;
5918 }
5919 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
5920 if (fault) goto MMU_EXCEPTION;
5921 addr += 4;
5922 phys_addr += 4;
5923 }
5924 }
5925 if (BIT(inst_cream->inst, 15)) {
5926 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5927 if (fault) {
5928 goto MMU_EXCEPTION;
5929 }
5930 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5931 if (fault) goto MMU_EXCEPTION;
5932 }
5933 #endif
5934 } else {
5935 for( i = 0; i < 15; i ++ ){
5936 if(BIT(inst_cream->inst, i)){
5937 //arch_write_memory(cpu, bb, Addr, R(i), 32);
5938 //bus_write(32, addr, cpu->Reg[i]);
5939 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5940 if (fault) {
5941 goto MMU_EXCEPTION;
5942 }
5943 if(i == Rn)
5944 fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
5945 else
5946 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5947 if (fault) goto MMU_EXCEPTION;
5948 addr += 4;
5949 phys_addr += 4;
5950 //Addr = ADD(Addr, CONST(4));
5951 }
5952 }
5953
5954 /* check pc reg*/
5955 if(BIT(inst_cream->inst, i)){
5956 //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32);
5957 //bus_write(32, addr, cpu->Reg[i] + 8);
5958 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5959 if (fault) {
5960 goto MMU_EXCEPTION;
5961 }
5962 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5963 if (fault) goto MMU_EXCEPTION;
5964 }
5965 }
5966 }
5967 cpu->Reg[15] += GET_INST_SIZE(cpu);
5968 INC_PC(sizeof(ldst_inst));
5969 FETCH_INST;
5970 GOTO_NEXT_INST;
5971 }
5972 SXTB_INST:
5973 {
5974 INC_ICOUNTER;
5975 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
5976 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5977 if (inst_cream->Rm == 15) {
5978 DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
5979 CITRA_IGNORE_EXIT(-1);
5980 }
5981 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
5982 if (BIT(operand2, 7)) {
5983 operand2 |= 0xffffff00;
5984 } else
5985 operand2 &= 0xff;
5986 RD = operand2;
5987 }
5988 cpu->Reg[15] += GET_INST_SIZE(cpu);
5989 INC_PC(sizeof(sxtb_inst));
5990 FETCH_INST;
5991 GOTO_NEXT_INST;
5992 }
5993 STR_INST:
5994 {
5995 INC_ICOUNTER;
5996 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5997 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5998 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5999 if (fault) goto MMU_EXCEPTION;
6000 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6001 //bus_write(32, addr, value);
6002 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6003 if (fault) goto MMU_EXCEPTION;
6004 }
6005 cpu->Reg[15] += GET_INST_SIZE(cpu);
6006 INC_PC(sizeof(ldst_inst));
6007 FETCH_INST;
6008 GOTO_NEXT_INST;
6009 }
6010 UXTB_INST:
6011 {
6012 INC_ICOUNTER;
6013 uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
6014 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6015 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6016 & 0xff;
6017 RD = operand2;
6018 }
6019 cpu->Reg[15] += GET_INST_SIZE(cpu);
6020 INC_PC(sizeof(uxtb_inst));
6021 FETCH_INST;
6022 GOTO_NEXT_INST;
6023 }
6024 UXTAB_INST:
6025 {
6026 INC_ICOUNTER;
6027 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
6028 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6029 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6030 & 0xff;
6031 RD = RN + operand2;
6032 }
6033 cpu->Reg[15] += GET_INST_SIZE(cpu);
6034 INC_PC(sizeof(uxtab_inst));
6035 FETCH_INST;
6036 GOTO_NEXT_INST;
6037 }
6038 STRB_INST:
6039 {
6040 INC_ICOUNTER;
6041 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6042 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6043 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6044 if (fault) goto MMU_EXCEPTION;
6045 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6046 //bus_write(8, addr, value);
6047 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6048 if (fault) goto MMU_EXCEPTION;
6049 }
6050 cpu->Reg[15] += GET_INST_SIZE(cpu);
6051 INC_PC(sizeof(ldst_inst));
6052 FETCH_INST;
6053 GOTO_NEXT_INST;
6054 }
6055 STRBT_INST:
6056 {
6057 INC_ICOUNTER;
6058 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6059 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6060 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6061 if (fault) goto MMU_EXCEPTION;
6062 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6063 //bus_write(8, addr, value);
6064 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6065 if (fault) goto MMU_EXCEPTION;
6066 }
6067 cpu->Reg[15] += GET_INST_SIZE(cpu);
6068 //if (BITS(inst_cream->inst, 12, 15) == 15)
6069 // goto PROFILING;
6070 INC_PC(sizeof(ldst_inst));
6071 FETCH_INST;
6072 GOTO_NEXT_INST;
6073 }
6074 STRD_INST:
6075 {
6076 INC_ICOUNTER;
6077 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6078 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6079 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6080 if (fault) goto MMU_EXCEPTION;
6081 uint32_t rear_phys_addr;
6082 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
6083 if (fault){
6084 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
6085 CITRA_IGNORE_EXIT(-1);
6086 goto MMU_EXCEPTION;
6087 }
6088
6089 //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0);
6090 //if (fault) goto MMU_EXCEPTION;
6091
6092 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6093 //bus_write(32, addr, value);
6094 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6095 if (fault) goto MMU_EXCEPTION;
6096 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
6097 //bus_write(32, addr, value);
6098 fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
6099 if (fault) goto MMU_EXCEPTION;
6100 }
6101 cpu->Reg[15] += GET_INST_SIZE(cpu);
6102 INC_PC(sizeof(ldst_inst));
6103 FETCH_INST;
6104 GOTO_NEXT_INST;
6105 }
6106 STREX_INST:
6107 {
6108 INC_ICOUNTER;
6109 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6110 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6111 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6112 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
6113 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6114 if (fault) goto MMU_EXCEPTION;
6115
6116 int dest_reg = BITS(inst_cream->inst, 12, 15);
6117 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6118 remove_exclusive(cpu, phys_addr);
6119 cpu->Reg[dest_reg] = 0;
6120 cpu->exclusive_state = 0;
6121
6122 // bus_write(32, addr, value);
6123 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6124 if (fault) goto MMU_EXCEPTION;
6125 }
6126 else{
6127 /* Failed to write due to mutex access */
6128 cpu->Reg[dest_reg] = 1;
6129 }
6130 }
6131 cpu->Reg[15] += GET_INST_SIZE(cpu);
6132 INC_PC(sizeof(ldst_inst));
6133 FETCH_INST;
6134 GOTO_NEXT_INST;
6135 }
6136 STREXB_INST:
6137 {
6138 INC_ICOUNTER;
6139 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6140 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6141 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6142 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
6143 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6144 if (fault) goto MMU_EXCEPTION;
6145 //bus_write(8, addr, value);
6146 int dest_reg = BITS(inst_cream->inst, 12, 15);
6147 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6148 remove_exclusive(cpu, phys_addr);
6149 cpu->Reg[dest_reg] = 0;
6150 cpu->exclusive_state = 0;
6151 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6152 if (fault) goto MMU_EXCEPTION;
6153
6154 }
6155 else{
6156 cpu->Reg[dest_reg] = 1;
6157 }
6158 }
6159 cpu->Reg[15] += GET_INST_SIZE(cpu);
6160 INC_PC(sizeof(ldst_inst));
6161 FETCH_INST;
6162 GOTO_NEXT_INST;
6163 }
6164 STRH_INST:
6165 {
6166 INC_ICOUNTER;
6167 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6168 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6169 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6170 if (fault) goto MMU_EXCEPTION;
6171 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6172 //bus_write(16, addr, value);
6173 fault = interpreter_write_memory(addr, phys_addr, value, 16);
6174 if (fault) goto MMU_EXCEPTION;
6175 }
6176 cpu->Reg[15] += GET_INST_SIZE(cpu);
6177 //if (BITS(inst_cream->inst, 12, 15) == 15)
6178 // goto PROFILING;
6179 INC_PC(sizeof(ldst_inst));
6180 FETCH_INST;
6181 GOTO_NEXT_INST;
6182 }
6183 STRT_INST:
6184 {
6185 INC_ICOUNTER;
6186 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6187 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6188 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6189 if (fault) goto MMU_EXCEPTION;
6190 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6191 //bus_write(16, addr, value);
6192 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6193 if (fault) goto MMU_EXCEPTION;
6194 }
6195 cpu->Reg[15] += GET_INST_SIZE(cpu);
6196 INC_PC(sizeof(ldst_inst));
6197 FETCH_INST;
6198 GOTO_NEXT_INST;
6199 }
6200 SUB_INST:
6201 {
6202 INC_ICOUNTER;
6203 sub_inst *inst_cream = (sub_inst *)inst_base->component;
6204 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6205 lop = RN;
6206 if (inst_cream->Rn == 15) {
6207 lop += 8;
6208 }
6209 rop = SHIFTER_OPERAND;
6210 RD = dst = lop - rop;
6211 if (inst_cream->S && (inst_cream->Rd == 15)) {
6212 /* cpsr = spsr */
6213 if (CurrentModeHasSPSR) {
6214 cpu->Cpsr = cpu->Spsr_copy;
6215 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
6216 LOAD_NZCVT;
6217 }
6218 } else if (inst_cream->S) {
6219 UPDATE_NFLAG(dst);
6220 UPDATE_ZFLAG(dst);
6221// UPDATE_CFLAG(dst, lop, rop);
6222 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
6223 // UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
6224 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
6225 }
6226 if (inst_cream->Rd == 15) {
6227 INC_PC(sizeof(sub_inst));
6228 goto PROFILING;
6229 }
6230 }
6231 cpu->Reg[15] += GET_INST_SIZE(cpu);
6232 INC_PC(sizeof(sub_inst));
6233 FETCH_INST;
6234 GOTO_NEXT_INST;
6235 }
6236 SWI_INST:
6237 {
6238 INC_ICOUNTER;
6239 swi_inst *inst_cream = (swi_inst *)inst_base->component;
6240 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6241 if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode
6242 //arm_dyncom_SWI(cpu, inst_cream->num);
6243 HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
6244 } else {
6245 cpu->syscallSig = 1;
6246 goto END;
6247 }
6248 }
6249 cpu->Reg[15] += GET_INST_SIZE(cpu);
6250 INC_PC(sizeof(swi_inst));
6251 FETCH_INST;
6252 GOTO_NEXT_INST;
6253 }
6254 SWP_INST:
6255 {
6256 INC_ICOUNTER;
6257 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6258 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6259 addr = RN;
6260 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6261 if (fault) goto MMU_EXCEPTION;
6262 unsigned int value;
6263 fault = interpreter_read_memory(addr, phys_addr, value, 32);
6264 if (fault) goto MMU_EXCEPTION;
6265 fault = interpreter_write_memory(addr, phys_addr, RM, 32);
6266 if (fault) goto MMU_EXCEPTION;
6267
6268 /* ROR(data, 8*UInt(address<1:0>)); */
6269 assert((phys_addr & 0x3) == 0);
6270 RD = value;
6271 }
6272 cpu->Reg[15] += GET_INST_SIZE(cpu);
6273 INC_PC(sizeof(swp_inst));
6274 FETCH_INST;
6275 GOTO_NEXT_INST;
6276 }
6277 SWPB_INST:
6278 {
6279 INC_ICOUNTER;
6280 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6281 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6282 addr = RN;
6283 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6284 if (fault) goto MMU_EXCEPTION;
6285 unsigned int value;
6286 fault = interpreter_read_memory(addr, phys_addr, value, 8);
6287 if (fault) goto MMU_EXCEPTION;
6288 fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
6289 if (fault) goto MMU_EXCEPTION;
6290
6291 /* FIXME */
6292 #if 0
6293 if Shared(address) then
6294 /* ARMv6 */
6295 physical_address = TLB(address)
6296 ClearExclusiveByAddress(physical_address,processor_id,1)
6297 /* See Summary of operation on page A2-49 */
6298 #endif
6299 }
6300 cpu->Reg[15] += GET_INST_SIZE(cpu);
6301 INC_PC(sizeof(swp_inst));
6302 FETCH_INST;
6303 GOTO_NEXT_INST;
6304 }
6305 SXTAB_INST:
6306 {
6307 INC_ICOUNTER;
6308 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
6309 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6310 /* R15 should be check */
6311 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6312 CITRA_IGNORE_EXIT(-1);
6313 }
6314 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6315 & 0xff;
6316 /* sign extend for byte */
6317 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
6318 RD = RN + operand2;
6319 }
6320 cpu->Reg[15] += GET_INST_SIZE(cpu);
6321 INC_PC(sizeof(uxtab_inst));
6322 FETCH_INST;
6323 GOTO_NEXT_INST;
6324 }
6325 SXTAB16_INST:
6326 SXTAH_INST:
6327 {
6328 INC_ICOUNTER;
6329 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
6330 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6331 /* R15 should be check */
6332 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6333 CITRA_IGNORE_EXIT(-1);
6334 }
6335 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
6336 /* sign extend for half */
6337 operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2;
6338 RD = RN + operand2;
6339 }
6340 cpu->Reg[15] += GET_INST_SIZE(cpu);
6341 INC_PC(sizeof(sxtah_inst));
6342 FETCH_INST;
6343 GOTO_NEXT_INST;
6344 }
6345 SXTB16_INST:
6346 TEQ_INST:
6347 {
6348 INC_ICOUNTER;
6349 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6350 teq_inst *inst_cream = (teq_inst *)inst_base->component;
6351 lop = RN;
6352 if (inst_cream->Rn == 15)
6353 lop += GET_INST_SIZE(cpu) * 2;
6354
6355 rop = SHIFTER_OPERAND;
6356 dst = lop ^ rop;
6357
6358 UPDATE_NFLAG(dst);
6359 UPDATE_ZFLAG(dst);
6360 UPDATE_CFLAG_WITH_SC;
6361 }
6362 cpu->Reg[15] += GET_INST_SIZE(cpu);
6363 INC_PC(sizeof(teq_inst));
6364 FETCH_INST;
6365 GOTO_NEXT_INST;
6366 }
6367 TST_INST:
6368 {
6369 INC_ICOUNTER;
6370 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6371 tst_inst *inst_cream = (tst_inst *)inst_base->component;
6372 lop = RN;
6373 if (inst_cream->Rn == 15)
6374 lop += GET_INST_SIZE(cpu) * 2;
6375 rop = SHIFTER_OPERAND;
6376 dst = lop & rop;
6377
6378 UPDATE_NFLAG(dst);
6379 UPDATE_ZFLAG(dst);
6380 UPDATE_CFLAG_WITH_SC;
6381 }
6382 cpu->Reg[15] += GET_INST_SIZE(cpu);
6383 INC_PC(sizeof(tst_inst));
6384 FETCH_INST;
6385 GOTO_NEXT_INST;
6386 }
6387 UADD16_INST:
6388 UADD8_INST:
6389 UADDSUBX_INST:
6390 UHADD16_INST:
6391 UHADD8_INST:
6392 UHADDSUBX_INST:
6393 UHSUB16_INST:
6394 UHSUB8_INST:
6395 UHSUBADDX_INST:
6396 UMAAL_INST:
6397 UMLAL_INST:
6398 {
6399 INC_ICOUNTER;
6400 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6401 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
6402 unsigned long long int rm = RM;
6403 unsigned long long int rs = RS;
6404 unsigned long long int rst = rm * rs;
6405 unsigned long long int add = ((unsigned long long) RDHI)<<32;
6406 add += RDLO;
6407 //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add);
6408 rst += add;
6409 RDLO = BITS(rst, 0, 31);
6410 RDHI = BITS(rst, 32, 63);
6411
6412 if (inst_cream->S)
6413 {
6414 cpu->NFlag = BIT(RDHI, 31);
6415 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6416 }
6417 }
6418 cpu->Reg[15] += GET_INST_SIZE(cpu);
6419 INC_PC(sizeof(umlal_inst));
6420 FETCH_INST;
6421 GOTO_NEXT_INST;
6422 }
6423 UMULL_INST:
6424 {
6425 INC_ICOUNTER;
6426 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6427 umull_inst *inst_cream = (umull_inst *)inst_base->component;
6428 unsigned long long int rm = RM;
6429 unsigned long long int rs = RS;
6430 unsigned long long int rst = rm * rs;
6431// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
6432 RDHI = BITS(rst, 32, 63);
6433 RDLO = BITS(rst, 0, 31);
6434
6435 if (inst_cream->S) {
6436 cpu->NFlag = BIT(RDHI, 31);
6437 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6438 }
6439 }
6440 cpu->Reg[15] += GET_INST_SIZE(cpu);
6441 INC_PC(sizeof(umull_inst));
6442 FETCH_INST;
6443 GOTO_NEXT_INST;
6444 }
6445 B_2_THUMB:
6446 {
6447 INC_ICOUNTER;
6448 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
6449 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6450 //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]);
6451 INC_PC(sizeof(b_2_thumb));
6452 goto PROFILING;
6453 }
6454 B_COND_THUMB:
6455 {
6456 INC_ICOUNTER;
6457 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
6458 if(CondPassed(cpu, inst_cream->cond))
6459 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6460 else
6461 cpu->Reg[15] += 2;
6462 //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]);
6463 INC_PC(sizeof(b_cond_thumb));
6464 goto PROFILING;
6465 }
6466 BL_1_THUMB:
6467 {
6468 INC_ICOUNTER;
6469 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
6470 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
6471 //cpu->Reg[15] += 2;
6472 //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]);
6473
6474 cpu->Reg[15] += GET_INST_SIZE(cpu);
6475 INC_PC(sizeof(bl_1_thumb));
6476 FETCH_INST;
6477 GOTO_NEXT_INST;
6478
6479 }
6480 BL_2_THUMB:
6481 {
6482 INC_ICOUNTER;
6483 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
6484 int tmp = ((cpu->Reg[15] + 2) | 1);
6485 cpu->Reg[15] =
6486 (cpu->Reg[14] + inst_cream->imm);
6487 cpu->Reg[14] = tmp;
6488 //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]);
6489 INC_PC(sizeof(bl_2_thumb));
6490 goto PROFILING;
6491 }
6492 BLX_1_THUMB:
6493 {
6494 /* BLX 1 for armv5t and above */
6495 INC_ICOUNTER;
6496 uint32 tmp = cpu->Reg[15];
6497 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
6498 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
6499 //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);
6500 cpu->Reg[14] = ((tmp + 2) | 1);
6501 //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
6502 /* switch to arm state from thumb state */
6503 cpu->TFlag = 0;
6504 //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]);
6505 INC_PC(sizeof(blx_1_thumb));
6506 goto PROFILING;
6507 }
6508
6509 UQADD16_INST:
6510 UQADD8_INST:
6511 UQADDSUBX_INST:
6512 UQSUB16_INST:
6513 UQSUB8_INST:
6514 UQSUBADDX_INST:
6515 USAD8_INST:
6516 USADA8_INST:
6517 USAT_INST:
6518 USAT16_INST:
6519 USUB16_INST:
6520 USUB8_INST:
6521 USUBADDX_INST:
6522 UXTAB16_INST:
6523 UXTB16_INST:
6524 #define VFP_INTERPRETER_IMPL
6525 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
6526 #undef VFP_INTERPRETER_IMPL
6527 MMU_EXCEPTION:
6528 {
6529 SAVE_NZCVT;
6530 cpu->abortSig = true;
6531 cpu->Aborted = ARMul_DataAbortV;
6532 cpu->AbortAddr = addr;
6533 cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
6534 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
6535 return;
6536 }
6537 END:
6538 {
6539 SAVE_NZCVT;
6540 return;
6541 }
6542 INIT_INST_LENGTH:
6543 {
6544#if 0
6545 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6546 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6547 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6548 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6549#endif
6550#if defined __GNUC__ || defined __clang__
6551 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
6552#endif
6553#if 0
6554 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6555 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6556 DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
6557 DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
6558 DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
6559#endif
6560 return;
6561 }
6562}
6563
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 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7void 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 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_run.cpp
20* @brief The dyncom run implementation for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-20
24*/
25
26#include <assert.h>
27
28#include "core/arm/skyeye_common/armdefs.h"
29
30void switch_mode(arm_core_t *core, uint32_t mode)
31{
32 uint32_t tmp1, tmp2;
33 if (core->Mode == mode) {
34 //Mode not changed.
35 //printf("mode not changed\n");
36 return;
37 }
38 //printf("%d --->>> %d\n", core->Mode, mode);
39 //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);
40 if (mode != USERBANK) {
41 switch (core->Mode) {
42 case USER32MODE:
43 core->Reg_usr[0] = core->Reg[13];
44 core->Reg_usr[1] = core->Reg[14];
45 break;
46 case IRQ32MODE:
47 core->Reg_irq[0] = core->Reg[13];
48 core->Reg_irq[1] = core->Reg[14];
49 core->Spsr[IRQBANK] = core->Spsr_copy;
50 break;
51 case SVC32MODE:
52 core->Reg_svc[0] = core->Reg[13];
53 core->Reg_svc[1] = core->Reg[14];
54 core->Spsr[SVCBANK] = core->Spsr_copy;
55 break;
56 case ABORT32MODE:
57 core->Reg_abort[0] = core->Reg[13];
58 core->Reg_abort[1] = core->Reg[14];
59 core->Spsr[ABORTBANK] = core->Spsr_copy;
60 break;
61 case UNDEF32MODE:
62 core->Reg_undef[0] = core->Reg[13];
63 core->Reg_undef[1] = core->Reg[14];
64 core->Spsr[UNDEFBANK] = core->Spsr_copy;
65 break;
66 case FIQ32MODE:
67 core->Reg_firq[0] = core->Reg[13];
68 core->Reg_firq[1] = core->Reg[14];
69 core->Spsr[FIQBANK] = core->Spsr_copy;
70 break;
71
72 }
73
74 switch (mode) {
75 case USER32MODE:
76 core->Reg[13] = core->Reg_usr[0];
77 core->Reg[14] = core->Reg_usr[1];
78 core->Bank = USERBANK;
79 break;
80 case IRQ32MODE:
81 core->Reg[13] = core->Reg_irq[0];
82 core->Reg[14] = core->Reg_irq[1];
83 core->Spsr_copy = core->Spsr[IRQBANK];
84 core->Bank = IRQBANK;
85 break;
86 case SVC32MODE:
87 core->Reg[13] = core->Reg_svc[0];
88 core->Reg[14] = core->Reg_svc[1];
89 core->Spsr_copy = core->Spsr[SVCBANK];
90 core->Bank = SVCBANK;
91 break;
92 case ABORT32MODE:
93 core->Reg[13] = core->Reg_abort[0];
94 core->Reg[14] = core->Reg_abort[1];
95 core->Spsr_copy = core->Spsr[ABORTBANK];
96 core->Bank = ABORTBANK;
97 break;
98 case UNDEF32MODE:
99 core->Reg[13] = core->Reg_undef[0];
100 core->Reg[14] = core->Reg_undef[1];
101 core->Spsr_copy = core->Spsr[UNDEFBANK];
102 core->Bank = UNDEFBANK;
103 break;
104 case FIQ32MODE:
105 core->Reg[13] = core->Reg_firq[0];
106 core->Reg[14] = core->Reg_firq[1];
107 core->Spsr_copy = core->Spsr[FIQBANK];
108 core->Bank = FIQBANK;
109 break;
110
111 }
112 core->Mode = mode;
113 //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);
114 //printf("\n--------------------------------------\n");
115 }
116 else {
117 printf("user mode\n");
118 exit(-2);
119 }
120}
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 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19#ifndef __ARM_DYNCOM_RUN__
20#define __ARM_DYNCOM_RUN__
21
22#include "core/arm/skyeye_common/skyeye_types.h"
23
24void switch_mode(arm_core_t *core, uint32_t mode);
25
26/* FIXME, we temporarily think thumb instruction is always 16 bit */
27static inline uint32 GET_INST_SIZE(arm_core_t* core){
28 return core->TFlag? 2 : 4;
29}
30
31/**
32* @brief Read R15 and forced R15 to wold align, used address calculation
33*
34* @param core
35* @param Rn
36*
37* @return
38*/
39static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
40 return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
41}
42
43/**
44* @brief Read R15, used to data processing with pc
45*
46* @param core
47* @param Rn
48*
49* @return
50*/
51static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){
52 return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
53}
54
55#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 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_thumb.c
20* @brief The thumb dynamic interpreter
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-07
24*/
25
26/* We can provide simple Thumb simulation by decoding the Thumb
27instruction into its corresponding ARM instruction, and using the
28existing ARM simulator. */
29
30#include "core/arm/skyeye_common/skyeye_defs.h"
31
32#ifndef MODET /* required for the Thumb instruction support */
33#if 1
34#error "MODET needs to be defined for the Thumb world to work"
35#else
36#define MODET (1)
37#endif
38#endif
39
40#include "core/arm/skyeye_common/armos.h"
41#include "core/arm/dyncom/arm_dyncom_thumb.h"
42
43/* Decode a 16bit Thumb instruction. The instruction is in the low
44 16-bits of the tinstr field, with the following Thumb instruction
45 held in the high 16-bits. Passing in two Thumb instructions allows
46 easier simulation of the special dual BL instruction. */
47
48tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size)
49{
50 tdstate valid = t_uninitialized;
51 ARMword next_instr;
52 ARMword tinstr;
53 tinstr = instr;
54 /* The endian should be judge here */
55 #if 0
56 if (state->bigendSig) {
57 next_instr = tinstr & 0xFFFF;
58 tinstr >>= 16;
59 }
60 else {
61 next_instr = tinstr >> 16;
62 tinstr &= 0xFFFF;
63 }
64 #endif
65 if((addr & 0x3) != 0)
66 tinstr = instr >> 16;
67 else
68 tinstr &= 0xFFFF;
69
70 //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc);
71#if 1 /* debugging to catch non updates */
72 *ainstr = 0xDEADC0DE;
73#endif
74
75 switch ((tinstr & 0xF800) >> 11) {
76 case 0: /* LSL */
77 case 1: /* LSR */
78 case 2: /* ASR */
79 /* Format 1 */
80 *ainstr = 0xE1B00000 /* base opcode */
81 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
82 |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
83 |((tinstr & 0x0038) >> 3) /* Rs */
84 |((tinstr & 0x0007) << 12); /* Rd */
85 break;
86 case 3: /* ADD/SUB */
87 /* Format 2 */
88 {
89 ARMword subset[4] = {
90 0xE0900000, /* ADDS Rd,Rs,Rn */
91 0xE0500000, /* SUBS Rd,Rs,Rn */
92 0xE2900000, /* ADDS Rd,Rs,#imm3 */
93 0xE2500000 /* SUBS Rd,Rs,#imm3 */
94 };
95 /* It is quicker indexing into a table, than performing switch
96 or conditionals: */
97 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
98 |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
99 |((tinstr & 0x0038) << (16 - 3)) /* Rs */
100 |((tinstr & 0x0007) << (12 - 0)); /* Rd */
101 }
102 break;
103 case 4: /* MOV */
104 case 5: /* CMP */
105 case 6: /* ADD */
106 case 7: /* SUB */
107 /* Format 3 */
108 {
109 ARMword subset[4] = {
110 0xE3B00000, /* MOVS Rd,#imm8 */
111 0xE3500000, /* CMP Rd,#imm8 */
112 0xE2900000, /* ADDS Rd,Rd,#imm8 */
113 0xE2500000, /* SUBS Rd,Rd,#imm8 */
114 };
115 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
116 |((tinstr & 0x00FF) >> 0) /* imm8 */
117 |((tinstr & 0x0700) << (16 - 8)) /* Rn */
118 |((tinstr & 0x0700) << (12 - 8)); /* Rd */
119 }
120 break;
121 case 8: /* Arithmetic and high register transfers */
122 /* TODO: Since the subsets for both Format 4 and Format 5
123 instructions are made up of different ARM encodings, we could
124 save the following conditional, and just have one large
125 subset. */
126 if ((tinstr & (1 << 10)) == 0) {
127 typedef enum
128 { t_norm, t_shift, t_neg, t_mul }otype_t;
129
130 /* Format 4 */
131 struct
132 {
133 ARMword opcode;
134 otype_t otype;
135 }
136 subset[16] = {
137 {
138 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
139 {
140 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
141 {
142 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
143 {
144 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
145 {
146 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
147 {
148 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
149 {
150 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
151 {
152 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
153 {
154 0xE1100000, t_norm}, /* TST Rd,Rs */
155 {
156 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
157 {
158 0xE1500000, t_norm}, /* CMP Rd,Rs */
159 {
160 0xE1700000, t_norm}, /* CMN Rd,Rs */
161 {
162 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
163 {
164 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
165 {
166 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
167 {
168 0xE1F00000, t_norm} /* MVNS Rd,Rs */
169 };
170 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
171 switch (subset[(tinstr & 0x03C0) >> 6].otype) {
172 case t_norm:
173 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
174 |((tinstr & 0x0007) << 12) /* Rd */
175 |((tinstr & 0x0038) >> 3); /* Rs */
176 break;
177 case t_shift:
178 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
179 |((tinstr & 0x0007) >> 0) /* Rm */
180 |((tinstr & 0x0038) << (8 - 3)); /* Rs */
181 break;
182 case t_neg:
183 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
184 |((tinstr & 0x0038) << (16 - 3)); /* Rn */
185 break;
186 case t_mul:
187 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
188 |((tinstr & 0x0007) << 8) /* Rs */
189 |((tinstr & 0x0038) >> 3); /* Rm */
190 break;
191 }
192 }
193 else {
194 /* Format 5 */
195 ARMword Rd = ((tinstr & 0x0007) >> 0);
196 ARMword Rs = ((tinstr & 0x0038) >> 3);
197 if (tinstr & (1 << 7))
198 Rd += 8;
199 if (tinstr & (1 << 6))
200 Rs += 8;
201 switch ((tinstr & 0x03C0) >> 6) {
202 case 0x1: /* ADD Rd,Rd,Hs */
203 case 0x2: /* ADD Hd,Hd,Rs */
204 case 0x3: /* ADD Hd,Hd,Hs */
205 *ainstr = 0xE0800000 /* base */
206 | (Rd << 16) /* Rn */
207 |(Rd << 12) /* Rd */
208 |(Rs << 0); /* Rm */
209 break;
210 case 0x5: /* CMP Rd,Hs */
211 case 0x6: /* CMP Hd,Rs */
212 case 0x7: /* CMP Hd,Hs */
213 *ainstr = 0xE1500000 /* base */
214 | (Rd << 16) /* Rn */
215 |(Rd << 12) /* Rd */
216 |(Rs << 0); /* Rm */
217 break;
218 case 0x9: /* MOV Rd,Hs */
219 case 0xA: /* MOV Hd,Rs */
220 case 0xB: /* MOV Hd,Hs */
221 *ainstr = 0xE1A00000 /* base */
222 | (Rd << 16) /* Rn */
223 |(Rd << 12) /* Rd */
224 |(Rs << 0); /* Rm */
225 break;
226 case 0xC: /* BX Rs */
227 case 0xD: /* BX Hs */
228 *ainstr = 0xE12FFF10 /* base */
229 | ((tinstr & 0x0078) >> 3); /* Rd */
230 break;
231 case 0x0: /* UNDEFINED */
232 case 0x4: /* UNDEFINED */
233 case 0x8: /* UNDEFINED */
234 valid = t_undefined;
235 break;
236 case 0xE: /* BLX */
237 case 0xF: /* BLX */
238
239 //if (state->is_v5) {
240 if(1){
241 //valid = t_branch;
242 #if 1
243 *ainstr = 0xE1200030 /* base */
244 |(Rs << 0); /* Rm */
245 #endif
246 } else {
247 valid = t_undefined;
248 }
249 break;
250 }
251 }
252 break;
253 case 9: /* LDR Rd,[PC,#imm8] */
254 /* Format 6 */
255 *ainstr = 0xE59F0000 /* base */
256 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
257 |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
258 break;
259 case 10:
260 case 11:
261 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
262 the following could be merged into a single subset, saving on
263 the following boolean: */
264 if ((tinstr & (1 << 9)) == 0) {
265 /* Format 7 */
266 ARMword subset[4] = {
267 0xE7800000, /* STR Rd,[Rb,Ro] */
268 0xE7C00000, /* STRB Rd,[Rb,Ro] */
269 0xE7900000, /* LDR Rd,[Rb,Ro] */
270 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
271 };
272 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
273 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
274 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
275 |((tinstr & 0x01C0) >> 6); /* Ro */
276 }
277 else {
278 /* Format 8 */
279 ARMword subset[4] = {
280 0xE18000B0, /* STRH Rd,[Rb,Ro] */
281 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
282 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
283 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
284 };
285 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
286 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
287 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
288 |((tinstr & 0x01C0) >> 6); /* Ro */
289 }
290 break;
291 case 12: /* STR Rd,[Rb,#imm5] */
292 case 13: /* LDR Rd,[Rb,#imm5] */
293 case 14: /* STRB Rd,[Rb,#imm5] */
294 case 15: /* LDRB Rd,[Rb,#imm5] */
295 /* Format 9 */
296 {
297 ARMword subset[4] = {
298 0xE5800000, /* STR Rd,[Rb,#imm5] */
299 0xE5900000, /* LDR Rd,[Rb,#imm5] */
300 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
301 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
302 };
303 /* The offset range defends on whether we are transferring a
304 byte or word value: */
305 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
306 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
307 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
308 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
309 }
310 break;
311 case 16: /* STRH Rd,[Rb,#imm5] */
312 case 17: /* LDRH Rd,[Rb,#imm5] */
313 /* Format 10 */
314 *ainstr = ((tinstr & (1 << 11)) /* base */
315 ? 0xE1D000B0 /* LDRH */
316 : 0xE1C000B0) /* STRH */
317 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
318 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
319 |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
320 |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
321 break;
322 case 18: /* STR Rd,[SP,#imm8] */
323 case 19: /* LDR Rd,[SP,#imm8] */
324 /* Format 11 */
325 *ainstr = ((tinstr & (1 << 11)) /* base */
326 ? 0xE59D0000 /* LDR */
327 : 0xE58D0000) /* STR */
328 |((tinstr & 0x0700) << (12 - 8)) /* Rd */
329 |((tinstr & 0x00FF) << 2); /* off8 */
330 break;
331 case 20: /* ADD Rd,PC,#imm8 */
332 case 21: /* ADD Rd,SP,#imm8 */
333 /* Format 12 */
334 if ((tinstr & (1 << 11)) == 0) {
335 /* NOTE: The PC value used here should by word aligned */
336 /* We encode shift-left-by-2 in the rotate immediate field,
337 so no shift of off8 is needed. */
338 *ainstr = 0xE28F0F00 /* base */
339 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
340 |(tinstr & 0x00FF); /* off8 */
341 }
342 else {
343 /* We encode shift-left-by-2 in the rotate immediate field,
344 so no shift of off8 is needed. */
345 *ainstr = 0xE28D0F00 /* base */
346 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
347 |(tinstr & 0x00FF); /* off8 */
348 }
349 break;
350 case 22:
351 case 23:
352 if ((tinstr & 0x0F00) == 0x0000) {
353 /* Format 13 */
354 /* NOTE: The instruction contains a shift left of 2
355 equivalent (implemented as ROR #30): */
356 *ainstr = ((tinstr & (1 << 7)) /* base */
357 ? 0xE24DDF00 /* SUB */
358 : 0xE28DDF00) /* ADD */
359 |(tinstr & 0x007F); /* off7 */
360 }
361 else if ((tinstr & 0x0F00) == 0x0e00)
362 *ainstr = 0xEF000000 | SWI_Breakpoint;
363 else {
364 /* Format 14 */
365 ARMword subset[4] = {
366 0xE92D0000, /* STMDB sp!,{rlist} */
367 0xE92D4000, /* STMDB sp!,{rlist,lr} */
368 0xE8BD0000, /* LDMIA sp!,{rlist} */
369 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
370 };
371 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
372 |(tinstr & 0x00FF); /* mask8 */
373 }
374 break;
375 case 24: /* STMIA */
376 case 25: /* LDMIA */
377 /* Format 15 */
378 *ainstr = ((tinstr & (1 << 11)) /* base */
379 ? 0xE8B00000 /* LDMIA */
380 : 0xE8A00000) /* STMIA */
381 |((tinstr & 0x0700) << (16 - 8)) /* Rb */
382 |(tinstr & 0x00FF); /* mask8 */
383 break;
384 case 26: /* Bcc */
385 case 27: /* Bcc/SWI */
386 if ((tinstr & 0x0F00) == 0x0F00) {
387 #if 0
388 if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
389 state->AbortAddr == pc) {
390 *ainstr = ARMul_ABORTWORD;
391 break;
392 }
393 #endif
394 /* Format 17 : SWI */
395 *ainstr = 0xEF000000;
396 /* Breakpoint must be handled specially. */
397 if ((tinstr & 0x00FF) == 0x18)
398 *ainstr |= ((tinstr & 0x00FF) << 16);
399 /* New breakpoint value. See gdb/arm-tdep.c */
400 else if ((tinstr & 0x00FF) == 0xFE)
401 *ainstr |= SWI_Breakpoint;
402 else
403 *ainstr |= (tinstr & 0x00FF);
404 }
405 else if ((tinstr & 0x0F00) != 0x0E00) {
406 /* Format 16 */
407 #if 0
408 int doit = FALSE;
409 /* TODO: Since we are doing a switch here, we could just add
410 the SWI and undefined instruction checks into this
411 switch to same on a couple of conditionals: */
412 switch ((tinstr & 0x0F00) >> 8) {
413 case EQ:
414 doit = ZFLAG;
415 break;
416 case NE:
417 doit = !ZFLAG;
418 break;
419 case VS:
420 doit = VFLAG;
421 break;
422 case VC:
423 doit = !VFLAG;
424 break;
425 case MI:
426 doit = NFLAG;
427 break;
428 case PL:
429 doit = !NFLAG;
430 break;
431 case CS:
432 doit = CFLAG;
433 break;
434 case CC:
435 doit = !CFLAG;
436 break;
437 case HI:
438 doit = (CFLAG && !ZFLAG);
439 break;
440 case LS:
441 doit = (!CFLAG || ZFLAG);
442 break;
443 case GE:
444 doit = ((!NFLAG && !VFLAG)
445 || (NFLAG && VFLAG));
446 break;
447 case LT:
448 doit = ((NFLAG && !VFLAG)
449 || (!NFLAG && VFLAG));
450 break;
451 case GT:
452 doit = ((!NFLAG && !VFLAG && !ZFLAG)
453 || (NFLAG && VFLAG && !ZFLAG));
454 break;
455 case LE:
456 doit = ((NFLAG && !VFLAG)
457 || (!NFLAG && VFLAG)) || ZFLAG;
458 break;
459 }
460 if (doit) {
461 state->Reg[15] = (pc + 4
462 + (((tinstr & 0x7F) << 1)
463 | ((tinstr & (1 << 7)) ?
464 0xFFFFFF00 : 0)));
465 FLUSHPIPE;
466 }
467 #endif
468 valid = t_branch;
469 }
470 else /* UNDEFINED : cc=1110(AL) uses different format */
471 valid = t_undefined;
472 break;
473 case 28: /* B */
474 /* Format 18 */
475 #if 0
476 state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
477 | ((tinstr & (1 << 10)) ?
478 0xFFFFF800 : 0)));
479 #endif
480 //FLUSHPIPE;
481 valid = t_branch;
482 break;
483 case 29:
484 if(tinstr & 0x1)
485 valid = t_undefined;
486 else{
487 /* BLX 1 for armv5t and above */
488 //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);
489 valid = t_branch;
490 }
491 break;
492 case 30: /* BL instruction 1 */
493 /* Format 19 */
494 /* There is no single ARM instruction equivalent for this Thumb
495 instruction. To keep the simulation simple (from the user
496 perspective) we check if the following instruction is the
497 second half of this BL, and if it is we simulate it
498 immediately. */
499 valid = t_branch;
500 break;
501 case 31: /* BL instruction 2 */
502 /* Format 19 */
503 /* There is no single ARM instruction equivalent for this
504 instruction. Also, it should only ever be matched with the
505 fmt19 "BL instruction 1" instruction. However, we do allow
506 the simulation of it on its own, with undefined results if
507 r14 is not suitably initialised. */
508 {
509 #if 0
510 ARMword tmp = (pc + 2);
511 state->Reg[15] =
512 (state->Reg[14] + ((tinstr & 0x07FF) << 1));
513 state->Reg[14] = (tmp | 1);
514 #endif
515 valid = t_branch;
516 }
517 break;
518 }
519 *inst_size = 2;
520 return valid;
521}
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 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19/**
20* @file arm_dyncom_thumb.h
21* @brief The thumb dyncom
22* @author Michael.Kang blackfin.kang@gmail.com
23* @version 78.77
24* @date 2011-11-07
25*/
26
27#ifndef __ARM_DYNCOM_THUMB_H__
28#define __ARM_DYNCOM_THUMB_H__
29
30#include "core/arm/skyeye_common/armdefs.h"
31#include "core/arm/skyeye_common/skyeye_types.h"
32
33enum tdstate {
34 t_undefined, // Undefined Thumb instruction
35 t_decoded, // Instruction decoded to ARM equivalent
36 t_branch, // Thumb branch (already processed)
37 t_uninitialized,
38};
39
40tdstate
41thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size);
42static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){
43 uint32 tinstr;
44 if ((pc & 0x3) != 0)
45 tinstr = instr >> 16;
46 else
47 tinstr = instr & 0xFFFF;
48 return tinstr;
49}
50
51#endif