summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar bunnei2014-09-12 18:34:51 -0400
committerGravatar bunnei2014-10-25 14:11:39 -0400
commit53a22b84da9690865954f666694de885ccb7c286 (patch)
tree77fa8c9fb653173cc78ffd7b0110d695c3fbb772 /src/core/arm
parentARM: Reorganized file structure to move shared SkyEye code to a more common a... (diff)
downloadyuzu-53a22b84da9690865954f666694de885ccb7c286.tar.gz
yuzu-53a22b84da9690865954f666694de885ccb7c286.tar.xz
yuzu-53a22b84da9690865954f666694de885ccb7c286.zip
ARM: Integrate SkyEye faster "dyncom" interpreter.
Fixed typo (make protected member public) Added license header back in. I originally removed this because I mostly rewrote the file, but meh ARM: Fixed a type error in dyncom interpreter. ARM: Updated dyncom to use unique_ptr for internal ARM state.
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp164
-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.cpp6559
-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
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h2
-rw-r--r--src/core/arm/interpreter/armsupp.cpp15
-rw-r--r--src/core/arm/skyeye_common/arm_regformat.h4
-rw-r--r--src/core/arm/skyeye_common/armcpu.h5
-rw-r--r--src/core/arm/skyeye_common/armos.h9
-rw-r--r--src/core/arm/skyeye_common/skyeye_defs.h4
-rw-r--r--src/core/arm/skyeye_common/skyeye_types.h55
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp48
18 files changed, 8216 insertions, 50 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..7a65669ef
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -0,0 +1,164 @@
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 mmu_init(state);
31
32 // Reset the core to initial state
33 ARMul_CoProInit(state.get());
34 ARMul_Reset(state.get());
35 state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
36 state->Emulate = 3;
37
38 state->pc = state->Reg[15] = 0x00000000;
39 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
40 state->servaddr = 0xFFFF0000;
41 state->NirqSig = HIGH;
42
43 VFPInit(state.get()); // Initialize the VFP
44
45 ARMul_EmulateInit();
46}
47
48ARM_DynCom::~ARM_DynCom() {
49}
50
51/**
52 * Set the Program Counter to an address
53 * @param addr Address to set PC to
54 */
55void ARM_DynCom::SetPC(u32 pc) {
56 state->pc = state->Reg[15] = pc;
57}
58
59/*
60 * Get the current Program Counter
61 * @return Returns current PC
62 */
63u32 ARM_DynCom::GetPC() const {
64 return state->pc;
65}
66
67/**
68 * Get an ARM register
69 * @param index Register index (0-15)
70 * @return Returns the value in the register
71 */
72u32 ARM_DynCom::GetReg(int index) const {
73 return state->Reg[index];
74}
75
76/**
77 * Set an ARM register
78 * @param index Register index (0-15)
79 * @param value Value to set register to
80 */
81void ARM_DynCom::SetReg(int index, u32 value) {
82 state->Reg[index] = value;
83}
84
85/**
86 * Get the current CPSR register
87 * @return Returns the value of the CPSR register
88 */
89u32 ARM_DynCom::GetCPSR() const {
90 return state->Cpsr;
91}
92
93/**
94 * Set the current CPSR register
95 * @param cpsr Value to set CPSR to
96 */
97void ARM_DynCom::SetCPSR(u32 cpsr) {
98 state->Cpsr = cpsr;
99}
100
101/**
102 * Returns the number of clock ticks since the last reset
103 * @return Returns number of clock ticks
104 */
105u64 ARM_DynCom::GetTicks() const {
106 return ticks;
107}
108
109/**
110 * Executes the given number of instructions
111 * @param num_instructions Number of instructions to executes
112 */
113void ARM_DynCom::ExecuteInstructions(int num_instructions) {
114 ticks += num_instructions;
115 state->NumInstrsToExecute = num_instructions;
116 InterpreterMainLoop(state.get());
117}
118
119/**
120 * Saves the current CPU context
121 * @param ctx Thread context to save
122 * @todo Do we need to save Reg[15] and NextInstr?
123 */
124void ARM_DynCom::SaveContext(ThreadContext& ctx) {
125 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
126 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
127
128 ctx.sp = state->Reg[13];
129 ctx.lr = state->Reg[14];
130 ctx.pc = state->pc;
131 ctx.cpsr = state->Cpsr;
132
133 ctx.fpscr = state->VFP[1];
134 ctx.fpexc = state->VFP[2];
135
136 ctx.reg_15 = state->Reg[15];
137 ctx.mode = state->NextInstr;
138}
139
140/**
141 * Loads a CPU context
142 * @param ctx Thread context to load
143 * @param Do we need to load Reg[15] and NextInstr?
144 */
145void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
146 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
147 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
148
149 state->Reg[13] = ctx.sp;
150 state->Reg[14] = ctx.lr;
151 state->pc = ctx.pc;
152 state->Cpsr = ctx.cpsr;
153
154 state->VFP[1] = ctx.fpscr;
155 state->VFP[2] = ctx.fpexc;
156
157 state->Reg[15] = ctx.reg_15;
158 state->NextInstr = ctx.mode;
159}
160
161/// Prepare core for thread reschedule (if needed to correctly handle state)
162void ARM_DynCom::PrepareReschedule() {
163 state->NumInstrsToExecute = 0;
164}
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..8739b8c14
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -0,0 +1,6559 @@
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#ifdef __GNUC__
3755#define GOTO_NEXT_INST goto *InstLabel[inst_base->idx]
3756#else
3757#define GOTO_NEXT_INST switch(inst_base->idx) { \
3758 case 0: goto VMLA_INST; \
3759 case 1: goto VMLS_INST; \
3760 case 2: goto VNMLA_INST; \
3761 case 3: goto VNMLA_INST; \
3762 case 4: goto VNMLS_INST; \
3763 case 5: goto VNMUL_INST; \
3764 case 6: goto VMUL_INST; \
3765 case 7: goto VADD_INST; \
3766 case 8: goto VSUB_INST; \
3767 case 9: goto VDIV_INST; \
3768 case 10: goto VMOVI_INST; \
3769 case 11: goto VMOVR_INST; \
3770 case 12: goto VABS_INST; \
3771 case 13: goto VNEG_INST; \
3772 case 14: goto VSQRT_INST; \
3773 case 15: goto VCMP_INST; \
3774 case 16: goto VCMP2_INST; \
3775 case 17: goto VCVTBDS_INST; \
3776 case 18: goto VCVTBFF_INST; \
3777 case 19: goto VCVTBFI_INST; \
3778 case 20: goto VMOVBRS_INST; \
3779 case 21: goto VMSR_INST; \
3780 case 22: goto VMOVBRC_INST; \
3781 case 23: goto VMRS_INST; \
3782 case 24: goto VMOVBCR_INST; \
3783 case 25: goto VMOVBRRSS_INST; \
3784 case 26: goto VMOVBRRD_INST; \
3785 case 27: goto VSTR_INST; \
3786 case 28: goto VPUSH_INST; \
3787 case 29: goto VSTM_INST; \
3788 case 30: goto VPOP_INST; \
3789 case 31: goto VLDR_INST; \
3790 case 32: goto VLDM_INST ; \
3791 case 33: goto SRS_INST; \
3792 case 34: goto RFE_INST; \
3793 case 35: goto BKPT_INST; \
3794 case 36: goto BLX_INST; \
3795 case 37: goto CPS_INST; \
3796 case 38: goto PLD_INST; \
3797 case 39: goto SETEND_INST; \
3798 case 40: goto CLREX_INST; \
3799 case 41: goto REV16_INST; \
3800 case 42: goto USAD8_INST; \
3801 case 43: goto SXTB_INST; \
3802 case 44: goto UXTB_INST; \
3803 case 45: goto SXTH_INST; \
3804 case 46: goto SXTB16_INST; \
3805 case 47: goto UXTH_INST; \
3806 case 48: goto UXTB16_INST; \
3807 case 49: goto CPY_INST; \
3808 case 50: goto UXTAB_INST; \
3809 case 51: goto SSUB8_INST; \
3810 case 52: goto SHSUB8_INST; \
3811 case 53: goto SSUBADDX_INST; \
3812 case 54: goto STREX_INST; \
3813 case 55: goto STREXB_INST; \
3814 case 56: goto SWP_INST; \
3815 case 57: goto SWPB_INST; \
3816 case 58: goto SSUB16_INST; \
3817 case 59: goto SSAT16_INST; \
3818 case 60: goto SHSUBADDX_INST; \
3819 case 61: goto QSUBADDX_INST; \
3820 case 62: goto SHADDSUBX_INST; \
3821 case 63: goto SHADD8_INST; \
3822 case 64: goto SHADD16_INST; \
3823 case 65: goto SEL_INST; \
3824 case 66: goto SADDSUBX_INST; \
3825 case 67: goto SADD8_INST; \
3826 case 68: goto SADD16_INST; \
3827 case 69: goto SHSUB16_INST; \
3828 case 70: goto UMAAL_INST; \
3829 case 71: goto UXTAB16_INST; \
3830 case 72: goto USUBADDX_INST; \
3831 case 73: goto USUB8_INST; \
3832 case 74: goto USUB16_INST; \
3833 case 75: goto USAT16_INST; \
3834 case 76: goto USADA8_INST; \
3835 case 77: goto UQSUBADDX_INST; \
3836 case 78: goto UQSUB8_INST; \
3837 case 79: goto UQSUB16_INST; \
3838 case 80: goto UQADDSUBX_INST; \
3839 case 81: goto UQADD8_INST; \
3840 case 82: goto UQADD16_INST; \
3841 case 83: goto SXTAB_INST; \
3842 case 84: goto UHSUBADDX_INST; \
3843 case 85: goto UHSUB8_INST; \
3844 case 86: goto UHSUB16_INST; \
3845 case 87: goto UHADDSUBX_INST; \
3846 case 88: goto UHADD8_INST; \
3847 case 89: goto UHADD16_INST; \
3848 case 90: goto UADDSUBX_INST; \
3849 case 91: goto UADD8_INST; \
3850 case 92: goto UADD16_INST; \
3851 case 93: goto SXTAH_INST; \
3852 case 94: goto SXTAB16_INST; \
3853 case 95: goto QADD8_INST; \
3854 case 96: goto BXJ_INST; \
3855 case 97: goto CLZ_INST; \
3856 case 98: goto UXTAH_INST; \
3857 case 99: goto BX_INST; \
3858 case 100: goto REV_INST; \
3859 case 101: goto BLX_INST; \
3860 case 102: goto REVSH_INST; \
3861 case 103: goto QADD_INST; \
3862 case 104: goto QADD16_INST; \
3863 case 105: goto QADDSUBX_INST; \
3864 case 106: goto LDREX_INST; \
3865 case 107: goto QDADD_INST; \
3866 case 108: goto QDSUB_INST; \
3867 case 109: goto QSUB_INST; \
3868 case 110: goto LDREXB_INST; \
3869 case 111: goto QSUB8_INST; \
3870 case 112: goto QSUB16_INST; \
3871 case 113: goto SMUAD_INST; \
3872 case 114: goto SMMUL_INST; \
3873 case 115: goto SMUSD_INST; \
3874 case 116: goto SMLSD_INST; \
3875 case 117: goto SMLSLD_INST; \
3876 case 118: goto SMMLA_INST; \
3877 case 119: goto SMMLS_INST; \
3878 case 120: goto SMLALD_INST; \
3879 case 121: goto SMLAD_INST; \
3880 case 122: goto SMLAW_INST; \
3881 case 123: goto SMULW_INST; \
3882 case 124: goto PKHTB_INST; \
3883 case 125: goto PKHBT_INST; \
3884 case 126: goto SMUL_INST; \
3885 case 127: goto SMLAL_INST; \
3886 case 128: goto SMLA_INST; \
3887 case 129: goto MCRR_INST; \
3888 case 130: goto MRRC_INST; \
3889 case 131: goto CMP_INST; \
3890 case 132: goto TST_INST; \
3891 case 133: goto TEQ_INST; \
3892 case 134: goto CMN_INST; \
3893 case 135: goto SMULL_INST; \
3894 case 136: goto UMULL_INST; \
3895 case 137: goto UMLAL_INST; \
3896 case 138: goto SMLAL_INST; \
3897 case 139: goto MUL_INST; \
3898 case 140: goto MLA_INST; \
3899 case 141: goto SSAT_INST; \
3900 case 142: goto USAT_INST; \
3901 case 143: goto MRS_INST; \
3902 case 144: goto MSR_INST; \
3903 case 145: goto AND_INST; \
3904 case 146: goto BIC_INST; \
3905 case 147: goto LDM_INST; \
3906 case 148: goto EOR_INST; \
3907 case 149: goto ADD_INST; \
3908 case 150: goto RSB_INST; \
3909 case 151: goto RSC_INST; \
3910 case 152: goto SBC_INST; \
3911 case 153: goto ADC_INST; \
3912 case 154: goto SUB_INST; \
3913 case 155: goto ORR_INST; \
3914 case 156: goto MVN_INST; \
3915 case 157: goto MOV_INST; \
3916 case 158: goto STM_INST; \
3917 case 159: goto LDM_INST; \
3918 case 160: goto LDRSH_INST; \
3919 case 161: goto STM_INST; \
3920 case 162: goto LDM_INST; \
3921 case 163: goto LDRSB_INST; \
3922 case 164: goto STRD_INST; \
3923 case 165: goto LDRH_INST; \
3924 case 166: goto STRH_INST; \
3925 case 167: goto LDRD_INST; \
3926 case 168: goto STRT_INST; \
3927 case 169: goto STRBT_INST; \
3928 case 170: goto LDRBT_INST; \
3929 case 171: goto LDRT_INST; \
3930 case 172: goto MRC_INST; \
3931 case 173: goto MCR_INST; \
3932 case 174: goto MSR_INST; \
3933 case 175: goto LDRB_INST; \
3934 case 176: goto STRB_INST; \
3935 case 177: goto LDR_INST; \
3936 case 178: goto LDRCOND_INST ; \
3937 case 179: goto STR_INST; \
3938 case 180: goto CDP_INST; \
3939 case 181: goto STC_INST; \
3940 case 182: goto LDC_INST; \
3941 case 183: goto SWI_INST; \
3942 case 184: goto BBL_INST; \
3943 case 185: goto B_2_THUMB ; \
3944 case 186: goto B_COND_THUMB ; \
3945 case 187: goto BL_1_THUMB ; \
3946 case 188: goto BL_2_THUMB ; \
3947 case 189: goto BLX_1_THUMB ; \
3948 case 190: goto DISPATCH; \
3949 case 191: goto INIT_INST_LENGTH; \
3950 case 192: goto END; \
3951 }
3952#endif
3953
3954 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
3955 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
3956// #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \
3957 (ISNEG(lop) && ISPOS(dst)) || \
3958 (ISPOS(rop) && ISPOS(dst))))
3959 #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
3960 #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
3961 #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
3962 #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
3963 #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
3964 #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out
3965// #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \
3966 (ISNEG(lop) && ISPOS(dst)) || \
3967 (ISPOS(rop) && ISPOS(dst)))
3968 #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
3969 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3970 #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
3971 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3972 #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
3973
3974 #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
3975 (cpu->NFlag << 31) | \
3976 (cpu->ZFlag << 30) | \
3977 (cpu->CFlag << 29) | \
3978 (cpu->VFlag << 28) | \
3979 (cpu->TFlag << 5)
3980 #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
3981 cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
3982 cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
3983 cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
3984 cpu->TFlag = (cpu->Cpsr >> 5) & 1;
3985
3986 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
3987 #define PC (cpu->Reg[15])
3988 #define CHECK_EXT_INT if (!cpu->NirqSig) { \
3989 if (!(cpu->Cpsr & 0x80)) { \
3990 goto END; \
3991 } \
3992 }
3993
3994
3995
3996 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3997 arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
3998
3999#if __GNUC__
4000 void *InstLabel[] = {
4001 #define VFP_INTERPRETER_LABEL
4002 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
4003 #undef VFP_INTERPRETER_LABEL
4004 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
4005 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
4006 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
4007 &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
4008 &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
4009 &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
4010 &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
4011 &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
4012 &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
4013 &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST,
4014 &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
4015 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
4016 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
4017 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
4018 &&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,
4019 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
4020 };
4021#endif
4022 arm_inst * inst_base;
4023 unsigned int lop, rop, dst;
4024 unsigned int addr;
4025 unsigned int phys_addr;
4026 unsigned int last_pc = 0;
4027 fault_t fault;
4028 static unsigned int last_physical_base = 0, last_logical_base = 0;
4029 int ptr;
4030
4031 LOAD_NZCVT;
4032 DISPATCH:
4033 {
4034 if (cpu->NumInstrsToExecute == 0)
4035 return;
4036
4037 cpu->NumInstrsToExecute--;
4038
4039 //NOTICE_LOG(ARM11, "instr!");
4040
4041 if (!cpu->NirqSig) {
4042 if (!(cpu->Cpsr & 0x80)) {
4043 goto END;
4044 }
4045 }
4046
4047 if (cpu->TFlag) {
4048 cpu->Reg[15] &= 0xfffffffe;
4049 } else
4050 cpu->Reg[15] &= 0xfffffffc;
4051#if PROFILE
4052 /* check next instruction address is valid. */
4053 last_pc = cpu->Reg[15];
4054#endif
4055#if USER_MODE_OPT
4056 phys_addr = cpu->Reg[15];
4057#else
4058 {
4059 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4060 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4061 else {
4062 /* check next instruction address is valid. */
4063 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4064 if (fault) {
4065 cpu->abortSig = true;
4066 cpu->Aborted = ARMul_PrefetchAbortV;
4067 cpu->AbortAddr = cpu->Reg[15];
4068 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4069 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4070 goto END;
4071 }
4072 last_logical_base = cpu->Reg[15] & 0xfffff000;
4073 last_physical_base = phys_addr & 0xfffff000;
4074 }
4075 }
4076#if HYBRID_MODE
4077 /* check if the native code of dyncom is available */
4078 //fast_map hash_map = core->dyncom_engine->fmap;
4079 //void * pfunc = NULL;
4080 //PFUNC(phys_addr);
4081 //if(pfunc){
4082 if(is_translated_entry(core, phys_addr)){
4083 int rc = JIT_RETURN_NOERR;
4084 //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
4085 SAVE_NZCVT;
4086// resume_timing();
4087 rc = cpu_run(core);
4088 LOAD_NZCVT;
4089 //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
4090 if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
4091 /* keep the tflag same with the bit in CPSR */
4092 //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
4093 //cpu->TFlag = cpu->Cpsr & (1 << 5);
4094 //switch_mode(cpu, cpu->Cpsr & 0x1f);
4095 //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
4096 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4097 if (fault) {
4098 cpu->abortSig = true;
4099 cpu->Aborted = ARMul_PrefetchAbortV;
4100 cpu->AbortAddr = cpu->Reg[15];
4101 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4102 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4103 goto END;
4104 }
4105 last_logical_base = cpu->Reg[15] & 0xfffff000;
4106 last_physical_base = phys_addr & 0xfffff000;
4107 core->current_page_phys = last_physical_base;
4108 core->current_page_effec = last_logical_base;
4109 //push_to_compiled(core, phys_addr);
4110 }
4111 else{
4112 if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
4113 //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]);
4114 //core->Reg[15] -= get_instr_size(cpu_dyncom);
4115 fill_tlb(cpu);
4116 goto END;
4117 }
4118 if (cpu->syscallSig) {
4119 goto END;
4120 }
4121 if (cpu->abortSig) {
4122 cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
4123 goto END;
4124 }
4125 if (!cpu->NirqSig) {
4126 if (!(cpu->Cpsr & 0x80)) {
4127 goto END;
4128 }
4129 }
4130
4131 /* if regular trap */
4132 cpu->Reg[15] += GET_INST_SIZE(cpu);
4133 /*uint32_t mode = cpu->Cpsr & 0x1f;
4134 if ((mode != cpu->Mode) && (!is_user_mode(core))) {
4135 switch_mode(cpu, mode);
4136 return 1;
4137 }*/
4138
4139 goto END;
4140 }
4141 //phys_addr = cpu->Reg[15];
4142 }
4143 else{
4144 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4145 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4146 else {
4147 /* check next instruction address is valid. */
4148 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4149 if (fault) {
4150 cpu->abortSig = true;
4151 cpu->Aborted = ARMul_PrefetchAbortV;
4152 cpu->AbortAddr = cpu->Reg[15];
4153 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4154 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4155 goto END;
4156 }
4157 last_logical_base = cpu->Reg[15] & 0xfffff000;
4158 last_physical_base = phys_addr & 0xfffff000;
4159 }
4160 }
4161#endif /* #if HYBRID_MODE */
4162#endif /* #if USER_MODE_OPT */
4163 if (true){//if(is_fast_interp_code(core, phys_addr)){
4164 if (find_bb(phys_addr, ptr) == -1)
4165 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4166 goto END;
4167 }
4168 else{
4169 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4170 goto END;
4171 }
4172#if PROFILE
4173 resume_timing();
4174#endif
4175 inst_base = (arm_inst *)&inst_buf[ptr];
4176 GOTO_NEXT_INST;
4177 }
4178 PROFILING:
4179 {
4180 goto DISPATCH;
4181 }
4182 ADC_INST:
4183 {
4184 INC_ICOUNTER;
4185 adc_inst *inst_cream = (adc_inst *)inst_base->component;
4186 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4187 lop = RN;
4188 unsigned int sht_op = SHIFTER_OPERAND;
4189 rop = SHIFTER_OPERAND + cpu->CFlag;
4190 RD = dst = lop + rop;
4191 if (inst_cream->S && (inst_cream->Rd == 15)) {
4192 /* cpsr = spsr */
4193 if (CurrentModeHasSPSR) {
4194 cpu->Cpsr = cpu->Spsr_copy;
4195 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4196 LOAD_NZCVT;
4197 }
4198 } else if (inst_cream->S) {
4199 UPDATE_NFLAG(dst);
4200 UPDATE_ZFLAG(dst);
4201 UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
4202 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4203 }
4204 if (inst_cream->Rd == 15) {
4205 INC_PC(sizeof(adc_inst));
4206 goto PROFILING;
4207 }
4208 }
4209 cpu->Reg[15] += GET_INST_SIZE(cpu);
4210 INC_PC(sizeof(adc_inst));
4211 FETCH_INST;
4212 GOTO_NEXT_INST;
4213 }
4214 ADD_INST:
4215 {
4216 INC_ICOUNTER;
4217 add_inst *inst_cream = (add_inst *)inst_base->component;
4218 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4219 lop = RN;
4220 if (inst_cream->Rn == 15) {
4221 lop += 2 * GET_INST_SIZE(cpu);
4222 }
4223 rop = SHIFTER_OPERAND;
4224 RD = dst = lop + rop;
4225 if (inst_cream->S && (inst_cream->Rd == 15)) {
4226 /* cpsr = spsr*/
4227 if (CurrentModeHasSPSR) {
4228 cpu->Cpsr = cpu->Spsr_copy;
4229 switch_mode(cpu, cpu->Cpsr & 0x1f);
4230 LOAD_NZCVT;
4231 }
4232 } else if (inst_cream->S) {
4233 UPDATE_NFLAG(dst);
4234 UPDATE_ZFLAG(dst);
4235 UPDATE_CFLAG(dst, lop, rop);
4236 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4237 }
4238 if (inst_cream->Rd == 15) {
4239 INC_PC(sizeof(add_inst));
4240 goto PROFILING;
4241 }
4242 }
4243 cpu->Reg[15] += GET_INST_SIZE(cpu);
4244 INC_PC(sizeof(add_inst));
4245 FETCH_INST;
4246 GOTO_NEXT_INST;
4247 }
4248 AND_INST:
4249 {
4250 INC_ICOUNTER;
4251 and_inst *inst_cream = (and_inst *)inst_base->component;
4252 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4253 lop = RN;
4254 rop = SHIFTER_OPERAND;
4255 RD = dst = lop & rop;
4256 if (inst_cream->S && (inst_cream->Rd == 15)) {
4257 /* cpsr = spsr*/
4258 if (CurrentModeHasSPSR) {
4259 cpu->Cpsr = cpu->Spsr_copy;
4260 switch_mode(cpu, cpu->Cpsr & 0x1f);
4261 LOAD_NZCVT;
4262 }
4263 } else if (inst_cream->S) {
4264 UPDATE_NFLAG(dst);
4265 UPDATE_ZFLAG(dst);
4266 UPDATE_CFLAG_WITH_SC;
4267 //UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4268 }
4269 if (inst_cream->Rd == 15) {
4270 INC_PC(sizeof(and_inst));
4271 goto PROFILING;
4272 }
4273 }
4274 cpu->Reg[15] += GET_INST_SIZE(cpu);
4275 INC_PC(sizeof(and_inst));
4276 FETCH_INST;
4277 GOTO_NEXT_INST;
4278 }
4279 BBL_INST:
4280 {
4281 INC_ICOUNTER;
4282 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4283 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
4284 if (inst_cream->L) {
4285 LINK_RTN_ADDR;
4286 }
4287 SET_PC;
4288 INC_PC(sizeof(bbl_inst));
4289 goto PROFILING;
4290 }
4291 cpu->Reg[15] += GET_INST_SIZE(cpu);
4292 INC_PC(sizeof(bbl_inst));
4293 goto PROFILING;
4294 }
4295 BIC_INST:
4296 {
4297 INC_ICOUNTER;
4298 bic_inst *inst_cream = (bic_inst *)inst_base->component;
4299 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4300 lop = RN;
4301 if (inst_cream->Rn == 15) {
4302 lop += 2 * GET_INST_SIZE(cpu);
4303 }
4304 rop = SHIFTER_OPERAND;
4305// RD = dst = lop & (rop ^ 0xffffffff);
4306 RD = dst = lop & (~rop);
4307 if ((inst_cream->S) && (inst_cream->Rd == 15)) {
4308 /* cpsr = spsr */
4309 if (CurrentModeHasSPSR) {
4310 cpu->Cpsr = cpu->Spsr_copy;
4311 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4312 LOAD_NZCVT;
4313 }
4314 } else if (inst_cream->S) {
4315 UPDATE_NFLAG(dst);
4316 UPDATE_ZFLAG(dst);
4317 UPDATE_CFLAG_WITH_SC;
4318 }
4319 if (inst_cream->Rd == 15) {
4320 INC_PC(sizeof(bic_inst));
4321 goto PROFILING;
4322 }
4323 }
4324 cpu->Reg[15] += GET_INST_SIZE(cpu);
4325 INC_PC(sizeof(bic_inst));
4326 FETCH_INST;
4327 GOTO_NEXT_INST;
4328 }
4329 BKPT_INST:
4330 BLX_INST:
4331 {
4332 INC_ICOUNTER;
4333 blx_inst *inst_cream = (blx_inst *)inst_base->component;
4334 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4335 unsigned int inst = inst_cream->inst;
4336 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
4337 //LINK_RTN_ADDR;
4338 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4339 if(cpu->TFlag)
4340 cpu->Reg[14] |= 0x1;
4341 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
4342 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
4343 //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe;
4344 //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1;
4345 } else {
4346 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4347 cpu->TFlag = 0x1;
4348 int signed_int = inst_cream->val.signed_immed_24;
4349 signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
4350 signed_int = signed_int << 2;
4351 // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu)
4352 cpu->Reg[15] = cpu->Reg[15] + 8
4353 + signed_int + (BIT(inst, 24) << 1);
4354 //DEBUG_MSG;
4355 }
4356 INC_PC(sizeof(blx_inst));
4357 goto PROFILING;
4358 }
4359 cpu->Reg[15] += GET_INST_SIZE(cpu);
4360// INC_PC(sizeof(bx_inst));
4361 INC_PC(sizeof(blx_inst));
4362 goto PROFILING;
4363 }
4364 BX_INST:
4365 {
4366 INC_ICOUNTER;
4367 bx_inst *inst_cream = (bx_inst *)inst_base->component;
4368 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4369 if (inst_cream->Rm == 15)
4370 DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]);
4371 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4372 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
4373// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4374 INC_PC(sizeof(bx_inst));
4375 goto PROFILING;
4376 }
4377 cpu->Reg[15] += GET_INST_SIZE(cpu);
4378// INC_PC(sizeof(bx_inst));
4379 INC_PC(sizeof(bx_inst));
4380 goto PROFILING;
4381 }
4382 BXJ_INST:
4383 CDP_INST:
4384 {
4385 INC_ICOUNTER;
4386 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
4387 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4388 /* FIXME, check if cp access allowed */
4389 #define CP_ACCESS_ALLOW 0
4390 if(CP_ACCESS_ALLOW){
4391 /* undefined instruction here */
4392 return;
4393 }
4394 ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
4395 unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
4396 if(cpab != ARMul_DONE){
4397 ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num);
4398 //CITRA_IGNORE_EXIT(-1);
4399 }
4400 }
4401 cpu->Reg[15] += GET_INST_SIZE(cpu);
4402 INC_PC(sizeof(cdp_inst));
4403 FETCH_INST;
4404 GOTO_NEXT_INST;
4405 }
4406
4407 CLREX_INST:
4408 {
4409 INC_ICOUNTER;
4410 remove_exclusive(cpu, 0);
4411 cpu->exclusive_state = 0;
4412
4413 cpu->Reg[15] += GET_INST_SIZE(cpu);
4414 INC_PC(sizeof(clrex_inst));
4415 FETCH_INST;
4416 GOTO_NEXT_INST;
4417 }
4418 CLZ_INST:
4419 {
4420 INC_ICOUNTER;
4421 clz_inst *inst_cream = (clz_inst *)inst_base->component;
4422 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4423 RD = clz(RM);
4424 }
4425 cpu->Reg[15] += GET_INST_SIZE(cpu);
4426 INC_PC(sizeof(clz_inst));
4427 FETCH_INST;
4428 GOTO_NEXT_INST;
4429 }
4430 CMN_INST:
4431 {
4432 INC_ICOUNTER;
4433 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
4434 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4435// DEBUG_LOG(ARM11, "RN is %x\n", RN);
4436 lop = RN;
4437 rop = SHIFTER_OPERAND;
4438 dst = lop + rop;
4439 UPDATE_NFLAG(dst);
4440 UPDATE_ZFLAG(dst);
4441 UPDATE_CFLAG(dst, lop, rop);
4442 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4443 }
4444 cpu->Reg[15] += GET_INST_SIZE(cpu);
4445 INC_PC(sizeof(cmn_inst));
4446 FETCH_INST;
4447 GOTO_NEXT_INST;
4448 }
4449 CMP_INST:
4450 {
4451// DEBUG_LOG(ARM11, "cmp inst\n");
4452// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
4453 INC_ICOUNTER;
4454 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4455// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]);
4456 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
4457 lop = RN;
4458 if (inst_cream->Rn == 15) {
4459 lop += 2 * GET_INST_SIZE(cpu);
4460 }
4461 rop = SHIFTER_OPERAND;
4462 dst = lop - rop;
4463
4464 UPDATE_NFLAG(dst);
4465 UPDATE_ZFLAG(dst);
4466// UPDATE_CFLAG(dst, lop, rop);
4467 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
4468// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4469 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
4470// UPDATE_VFLAG_WITH_NOT(dst, lop, rop);
4471 }
4472 cpu->Reg[15] += GET_INST_SIZE(cpu);
4473 INC_PC(sizeof(cmp_inst));
4474 FETCH_INST;
4475 GOTO_NEXT_INST;
4476 }
4477 CPS_INST:
4478 {
4479 INC_ICOUNTER;
4480 cps_inst *inst_cream = (cps_inst *)inst_base->component;
4481 uint32_t aif_val = 0;
4482 uint32_t aif_mask = 0;
4483 if (InAPrivilegedMode(cpu)) {
4484 /* isInAPrivilegedMode */
4485 if (inst_cream->imod1) {
4486 if (inst_cream->A) {
4487 aif_val |= (inst_cream->imod0 << 8);
4488 aif_mask |= 1 << 8;
4489 }
4490 if (inst_cream->I) {
4491 aif_val |= (inst_cream->imod0 << 7);
4492 aif_mask |= 1 << 7;
4493 }
4494 if (inst_cream->F) {
4495 aif_val |= (inst_cream->imod0 << 6);
4496 aif_mask |= 1 << 6;
4497 }
4498 aif_mask = ~aif_mask;
4499 cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
4500 }
4501 if (inst_cream->mmod) {
4502 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
4503 switch_mode(cpu, inst_cream->mode);
4504 }
4505 }
4506 cpu->Reg[15] += GET_INST_SIZE(cpu);
4507 INC_PC(sizeof(cps_inst));
4508 FETCH_INST;
4509 GOTO_NEXT_INST;
4510 }
4511 CPY_INST:
4512 {
4513 INC_ICOUNTER;
4514 mov_inst *inst_cream = (mov_inst *)inst_base->component;
4515// cpy_inst *inst_cream = (cpy_inst *)inst_base->component;
4516 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4517 RD = SHIFTER_OPERAND;
4518// RD = RM;
4519 if ((inst_cream->Rd == 15)) {
4520 INC_PC(sizeof(mov_inst));
4521 goto PROFILING;
4522 }
4523 }
4524// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]);
4525 cpu->Reg[15] += GET_INST_SIZE(cpu);
4526 INC_PC(sizeof(mov_inst));
4527 FETCH_INST;
4528 GOTO_NEXT_INST;
4529 }
4530 EOR_INST:
4531 {
4532 INC_ICOUNTER;
4533 eor_inst *inst_cream = (eor_inst *)inst_base->component;
4534 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4535 lop = RN;
4536 if (inst_cream->Rn == 15) {
4537 lop += 2 * GET_INST_SIZE(cpu);
4538 }
4539 rop = SHIFTER_OPERAND;
4540 RD = dst = lop ^ rop;
4541 if (inst_cream->S && (inst_cream->Rd == 15)) {
4542 /* cpsr = spsr*/
4543 if (CurrentModeHasSPSR) {
4544 cpu->Cpsr = cpu->Spsr_copy;
4545 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4546 LOAD_NZCVT;
4547 }
4548 } else if (inst_cream->S) {
4549 UPDATE_NFLAG(dst);
4550 UPDATE_ZFLAG(dst);
4551 UPDATE_CFLAG_WITH_SC;
4552// UPDATE_CFLAG(dst, lop, rop);
4553// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4554 }
4555 if (inst_cream->Rd == 15) {
4556 INC_PC(sizeof(eor_inst));
4557 goto PROFILING;
4558 }
4559 }
4560 cpu->Reg[15] += GET_INST_SIZE(cpu);
4561 INC_PC(sizeof(eor_inst));
4562 FETCH_INST;
4563 GOTO_NEXT_INST;
4564 }
4565 LDC_INST:
4566 {
4567 INC_ICOUNTER;
4568 /* NOT IMPL */
4569 cpu->Reg[15] += GET_INST_SIZE(cpu);
4570 INC_PC(sizeof(ldc_inst));
4571 FETCH_INST;
4572 GOTO_NEXT_INST;
4573 }
4574 LDM_INST:
4575 {
4576 INC_ICOUNTER;
4577 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4578 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4579 int i;
4580 unsigned int ret;
4581 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4582 if (fault) {
4583 goto MMU_EXCEPTION;
4584 }
4585 unsigned int inst = inst_cream->inst;
4586 if (BIT(inst, 22) && !BIT(inst, 15)) {
4587// DEBUG_MSG;
4588 #if 1
4589 /* LDM (2) user */
4590 for (i = 0; i < 13; i++) {
4591 if(BIT(inst, i)){
4592 #if 0
4593 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4594 if (fault) {
4595 goto MMU_EXCEPTION;
4596 }
4597 #endif
4598 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4599 //if (fault) goto MMU_EXCEPTION;
4600 cpu->Reg[i] = ret;
4601 addr += 4;
4602 if ((addr & 0xfff) == 0) {
4603 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4604 } else {
4605 phys_addr += 4;
4606 }
4607 }
4608 }
4609 if (BIT(inst, 13)) {
4610 #if 0
4611 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4612 if (fault) {
4613 goto MMU_EXCEPTION;
4614 }
4615 #endif
4616 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4617 //if (fault) goto MMU_EXCEPTION;
4618 if (cpu->Mode == USER32MODE)
4619 cpu->Reg[13] = ret;
4620 else
4621 cpu->Reg_usr[0] = ret;
4622 addr += 4;
4623 if ((addr & 0xfff) == 0) {
4624 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4625 } else {
4626 phys_addr += 4;
4627 }
4628 }
4629 if (BIT(inst, 14)) {
4630 #if 0
4631 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4632 if (fault) {
4633 goto MMU_EXCEPTION;
4634 }
4635 #endif
4636 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4637 //if (fault) goto MMU_EXCEPTION;
4638 if (cpu->Mode == USER32MODE)
4639 cpu->Reg[14] = ret;
4640 else
4641 cpu->Reg_usr[1] = ret;
4642 }
4643 #endif
4644 } else if (!BIT(inst, 22)) {
4645 for( i = 0; i < 16; i ++ ){
4646 if(BIT(inst, i)){
4647 //bus_read(32, addr, &ret);
4648 #if 0
4649 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4650 if (fault) {
4651 goto MMU_EXCEPTION;
4652 }
4653 #endif
4654 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4655 if (fault) goto MMU_EXCEPTION;
4656 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4657 if(i == 15){
4658 cpu->TFlag = ret & 0x1;
4659 ret &= 0xFFFFFFFE;
4660 //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
4661 }
4662
4663 cpu->Reg[i] = ret;
4664 addr += 4;
4665 if ((addr & 0xfff) == 0) {
4666 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4667 } else {
4668 phys_addr += 4;
4669 }
4670 }
4671 }
4672 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4673 for( i = 0; i < 15; i ++ ){
4674 if(BIT(inst, i)){
4675 #if 0
4676 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4677 if (fault) {
4678 goto MMU_EXCEPTION;
4679 }
4680 #endif
4681 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4682 //if (fault) goto MMU_EXCEPTION;
4683 cpu->Reg[i] = ret;
4684 addr += 4;
4685 if ((addr & 0xfff) == 0) {
4686 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4687 } else {
4688 phys_addr += 4;
4689 }
4690 }
4691 }
4692
4693 if (CurrentModeHasSPSR) {
4694 cpu->Cpsr = cpu->Spsr_copy;
4695 switch_mode(cpu, cpu->Cpsr & 0x1f);
4696 LOAD_NZCVT;
4697 }
4698 #if 0
4699 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4700 if (fault) {
4701 goto MMU_EXCEPTION;
4702 }
4703 #endif
4704 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4705 if (fault) {
4706 goto MMU_EXCEPTION;
4707 }
4708 cpu->Reg[15] = ret;
4709 #if 0
4710 addr += 4;
4711 phys_addr += 4;
4712 #endif
4713 }
4714 if (BIT(inst, 15)) {
4715 INC_PC(sizeof(ldst_inst));
4716 goto PROFILING;
4717 }
4718 }
4719 cpu->Reg[15] += GET_INST_SIZE(cpu);
4720 INC_PC(sizeof(ldst_inst));
4721 FETCH_INST;
4722 GOTO_NEXT_INST;
4723 }
4724 SXTH_INST:
4725 {
4726 INC_ICOUNTER;
4727 sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
4728 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4729 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
4730 if (BIT(operand2, 15)) {
4731 operand2 |= 0xffff0000;
4732 } else {
4733 operand2 &= 0xffff;
4734 }
4735 RD = operand2;
4736 }
4737 cpu->Reg[15] += GET_INST_SIZE(cpu);
4738 INC_PC(sizeof(sxth_inst));
4739 FETCH_INST;
4740 GOTO_NEXT_INST;
4741 }
4742 LDR_INST:
4743 {
4744 INC_ICOUNTER;
4745 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4746 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4747 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4748 if (fault) goto MMU_EXCEPTION;
4749 unsigned int value;
4750 //bus_read(32, addr, &value);
4751 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4752 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4753 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4754 else {
4755 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4756 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4757 }
4758 if (BITS(inst_cream->inst, 12, 15) == 15) {
4759 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4760 cpu->TFlag = value & 0x1;
4761 cpu->Reg[15] &= 0xFFFFFFFE;
4762 INC_PC(sizeof(ldst_inst));
4763 goto PROFILING;
4764 }
4765 //}
4766 cpu->Reg[15] += GET_INST_SIZE(cpu);
4767 INC_PC(sizeof(ldst_inst));
4768 FETCH_INST;
4769 GOTO_NEXT_INST;
4770 }
4771 LDRCOND_INST:
4772 {
4773 INC_ICOUNTER;
4774 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4775 if (CondPassed(cpu, inst_base->cond)) {
4776 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4777 if (fault) goto MMU_EXCEPTION;
4778 unsigned int value;
4779 //bus_read(32, addr, &value);
4780 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4781 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4782 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4783 else {
4784 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4785 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4786 }
4787
4788 if (BITS(inst_cream->inst, 12, 15) == 15) {
4789 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4790 cpu->TFlag = value & 0x1;
4791 cpu->Reg[15] &= 0xFFFFFFFE;
4792 INC_PC(sizeof(ldst_inst));
4793 goto PROFILING;
4794 }
4795 }
4796 cpu->Reg[15] += GET_INST_SIZE(cpu);
4797 INC_PC(sizeof(ldst_inst));
4798 FETCH_INST;
4799 GOTO_NEXT_INST;
4800 }
4801 UXTH_INST:
4802 {
4803 INC_ICOUNTER;
4804 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
4805 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4806 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4807 & 0xffff;
4808 RD = operand2;
4809 }
4810 cpu->Reg[15] += GET_INST_SIZE(cpu);
4811 INC_PC(sizeof(uxth_inst));
4812 FETCH_INST;
4813 GOTO_NEXT_INST;
4814 }
4815 UXTAH_INST:
4816 {
4817 INC_ICOUNTER;
4818 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
4819 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4820 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4821 & 0xffff;
4822 RD = RN + operand2;
4823 if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
4824 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
4825 CITRA_IGNORE_EXIT(-1);
4826 }
4827 }
4828 cpu->Reg[15] += GET_INST_SIZE(cpu);
4829 INC_PC(sizeof(uxtah_inst));
4830 FETCH_INST;
4831 GOTO_NEXT_INST;
4832 }
4833 LDRB_INST:
4834 {
4835 INC_ICOUNTER;
4836 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4837 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4838 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4839 if (fault) goto MMU_EXCEPTION;
4840 unsigned int value;
4841 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4842 if (fault) goto MMU_EXCEPTION;
4843 //bus_read(8, addr, &value);
4844 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4845 if (BITS(inst_cream->inst, 12, 15) == 15) {
4846 INC_PC(sizeof(ldst_inst));
4847 goto PROFILING;
4848 }
4849 }
4850 cpu->Reg[15] += GET_INST_SIZE(cpu);
4851 INC_PC(sizeof(ldst_inst));
4852 FETCH_INST;
4853 GOTO_NEXT_INST;
4854 }
4855 LDRBT_INST:
4856 {
4857 INC_ICOUNTER;
4858 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4859 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4860 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4861 if (fault) goto MMU_EXCEPTION;
4862 unsigned int value;
4863 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4864 if (fault) goto MMU_EXCEPTION;
4865 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4866 if (BITS(inst_cream->inst, 12, 15) == 15) {
4867 INC_PC(sizeof(ldst_inst));
4868 goto PROFILING;
4869 }
4870 }
4871 cpu->Reg[15] += GET_INST_SIZE(cpu);
4872 INC_PC(sizeof(ldst_inst));
4873 FETCH_INST;
4874 GOTO_NEXT_INST;
4875 }
4876 LDRD_INST:
4877 {
4878 INC_ICOUNTER;
4879 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4880 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4881 /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */
4882 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4883 if (fault) goto MMU_EXCEPTION;
4884 uint32_t rear_phys_addr;
4885 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
4886 if(fault){
4887 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
4888 CITRA_IGNORE_EXIT(-1);
4889 goto MMU_EXCEPTION;
4890 }
4891 unsigned int value;
4892 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4893 if (fault) goto MMU_EXCEPTION;
4894 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4895 fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
4896 if (fault) goto MMU_EXCEPTION;
4897 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
4898 /* No dispatch since this operation should not modify R15 */
4899 }
4900 cpu->Reg[15] += 4;
4901 INC_PC(sizeof(ldst_inst));
4902 FETCH_INST;
4903 GOTO_NEXT_INST;
4904 }
4905
4906 LDREX_INST:
4907 {
4908 INC_ICOUNTER;
4909 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4910 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4911 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4912 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4913 if (fault) goto MMU_EXCEPTION;
4914 unsigned int value;
4915 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4916 if (fault) goto MMU_EXCEPTION;
4917
4918 add_exclusive_addr(cpu, phys_addr);
4919 cpu->exclusive_state = 1;
4920
4921 //bus_read(32, addr, &value);
4922 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4923 if (BITS(inst_cream->inst, 12, 15) == 15) {
4924 INC_PC(sizeof(ldst_inst));
4925 goto PROFILING;
4926 }
4927 }
4928 cpu->Reg[15] += GET_INST_SIZE(cpu);
4929 INC_PC(sizeof(ldst_inst));
4930 FETCH_INST;
4931 GOTO_NEXT_INST;
4932 }
4933 LDREXB_INST:
4934 {
4935 INC_ICOUNTER;
4936 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4937 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4938 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4939 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4940 if (fault) goto MMU_EXCEPTION;
4941 unsigned int value;
4942 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4943 if (fault) goto MMU_EXCEPTION;
4944
4945 add_exclusive_addr(cpu, phys_addr);
4946 cpu->exclusive_state = 1;
4947
4948 //bus_read(8, addr, &value);
4949 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4950 if (BITS(inst_cream->inst, 12, 15) == 15) {
4951 INC_PC(sizeof(ldst_inst));
4952 goto PROFILING;
4953 }
4954 }
4955 cpu->Reg[15] += GET_INST_SIZE(cpu);
4956 INC_PC(sizeof(ldst_inst));
4957 FETCH_INST;
4958 GOTO_NEXT_INST;
4959 }
4960 LDRH_INST:
4961 {
4962 INC_ICOUNTER;
4963 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4964 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4965 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4966 if (fault) goto MMU_EXCEPTION;
4967 unsigned int value = 0;
4968 fault = interpreter_read_memory(addr, phys_addr, value, 16);
4969// fault = interpreter_read_memory(addr, value, 32);
4970 if (fault) goto MMU_EXCEPTION;
4971 //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) {
4972 // value = 0xffffffff;
4973 //}
4974 //bus_read(16, addr, &value);
4975// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff;
4976 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4977 if (BITS(inst_cream->inst, 12, 15) == 15) {
4978 INC_PC(sizeof(ldst_inst));
4979 goto PROFILING;
4980 }
4981 }
4982 cpu->Reg[15] += GET_INST_SIZE(cpu);
4983 INC_PC(sizeof(ldst_inst));
4984 FETCH_INST;
4985 GOTO_NEXT_INST;
4986 }
4987 LDRSB_INST:
4988 {
4989 INC_ICOUNTER;
4990 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4991 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4992 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4993 if (fault) goto MMU_EXCEPTION;
4994 unsigned int value;
4995// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr);
4996 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4997 if (fault) goto MMU_EXCEPTION;
4998 //bus_read(8, addr, &value);
4999 if (BIT(value, 7)) {
5000 value |= 0xffffff00;
5001 }
5002 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5003 if (BITS(inst_cream->inst, 12, 15) == 15) {
5004 INC_PC(sizeof(ldst_inst));
5005 goto PROFILING;
5006 }
5007 }
5008 cpu->Reg[15] += GET_INST_SIZE(cpu);
5009 INC_PC(sizeof(ldst_inst));
5010 FETCH_INST;
5011 GOTO_NEXT_INST;
5012 }
5013 LDRSH_INST:
5014 {
5015 INC_ICOUNTER;
5016 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5017 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5018 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5019 if (fault) goto MMU_EXCEPTION;
5020 unsigned int value;
5021 fault = interpreter_read_memory(addr, phys_addr, value, 16);
5022 if (fault) goto MMU_EXCEPTION;
5023 //bus_read(16, addr, &value);
5024 if (BIT(value, 15)) {
5025 value |= 0xffff0000;
5026 }
5027 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5028 if (BITS(inst_cream->inst, 12, 15) == 15) {
5029 INC_PC(sizeof(ldst_inst));
5030 goto PROFILING;
5031 }
5032 }
5033 cpu->Reg[15] += GET_INST_SIZE(cpu);
5034 INC_PC(sizeof(ldst_inst));
5035 FETCH_INST;
5036 GOTO_NEXT_INST;
5037 }
5038 LDRT_INST:
5039 {
5040 INC_ICOUNTER;
5041 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5042 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5043 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5044 if (fault) goto MMU_EXCEPTION;
5045 unsigned int value;
5046 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5047 if (fault) goto MMU_EXCEPTION;
5048 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5049
5050 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
5051 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5052 else
5053 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
5054
5055 if (BITS(inst_cream->inst, 12, 15) == 15) {
5056 INC_PC(sizeof(ldst_inst));
5057 goto PROFILING;
5058 }
5059 }
5060 cpu->Reg[15] += GET_INST_SIZE(cpu);
5061 INC_PC(sizeof(ldst_inst));
5062 FETCH_INST;
5063 GOTO_NEXT_INST;
5064 }
5065 MCR_INST:
5066 {
5067 INC_ICOUNTER;
5068 /* NOT IMPL */
5069 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
5070 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5071 unsigned int inst = inst_cream->inst;
5072 if (inst_cream->Rd == 15) {
5073 DEBUG_MSG;
5074 } else {
5075 if (inst_cream->cp_num == 15) {
5076 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5077 //LET(RD, CONST(0x0007b000));
5078 //LET(RD, CONST(0x410FB760));
5079 //LET(CP15_MAIN_ID, R(RD));
5080 CP15_REG(CP15_MAIN_ID) = RD;
5081 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5082 //LET(RD, R(CP15_CONTROL));
5083 CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
5084 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5085 //LET(RD, R(CP15_CONTROL));
5086 CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
5087 } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5088 //LET(CP15_CONTROL, R(RD));
5089 CP15_REG(CP15_CONTROL) = RD;
5090 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5091 //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD));
5092 CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
5093 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5094 //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD));
5095 CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
5096 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
5097 //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD));
5098 CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
5099 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
5100 //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD));
5101 CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
5102 } else if(CRn == MMU_CACHE_OPS){
5103 //SKYEYE_WARNING("cache operation have not implemented.\n");
5104 } else if(CRn == MMU_TLB_OPS){
5105 switch (CRm) {
5106 case 5: /* ITLB */
5107 switch(OPCODE_2){
5108 case 0: /* invalidate all */
5109 //invalidate_all_tlb(state);
5110 DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n");
5111 //remove_tlb(INSN_TLB);
5112 //erase_all(core, INSN_TLB);
5113 break;
5114 case 1: /* invalidate by MVA */
5115 //invalidate_by_mva(state, value);
5116 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n");
5117 //remove_tlb_by_mva(RD, INSN_TLB);
5118 //erase_by_mva(core, RD, INSN_TLB);
5119 break;
5120 case 2: /* invalidate by asid */
5121 //invalidate_by_asid(state, value);
5122 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n");
5123 //erase_by_asid(core, RD, INSN_TLB);
5124 break;
5125 default:
5126 break;
5127 }
5128
5129 break;
5130 case 6: /* DTLB */
5131 switch(OPCODE_2){
5132 case 0: /* invalidate all */
5133 //invalidate_all_tlb(state);
5134 //remove_tlb(DATA_TLB);
5135 //erase_all(core, DATA_TLB);
5136 DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n");
5137 break;
5138 case 1: /* invalidate by MVA */
5139 //invalidate_by_mva(state, value);
5140 //remove_tlb_by_mva(RD, DATA_TLB);
5141 //erase_by_mva(core, RD, DATA_TLB);
5142 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n");
5143 break;
5144 case 2: /* invalidate by asid */
5145 //invalidate_by_asid(state, value);
5146 //remove_tlb_by_asid(RD, DATA_TLB);
5147 //erase_by_asid(core, RD, DATA_TLB);
5148 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n");
5149 break;
5150 default:
5151 break;
5152 }
5153 break;
5154 case 7: /* UNIFILED TLB */
5155 switch(OPCODE_2){
5156 case 0: /* invalidate all */
5157 //invalidate_all_tlb(state);
5158 //erase_all(core, INSN_TLB);
5159 //erase_all(core, DATA_TLB);
5160 //remove_tlb(DATA_TLB);
5161 //remove_tlb(INSN_TLB);
5162 //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n");
5163 break;
5164 case 1: /* invalidate by MVA */
5165 //invalidate_by_mva(state, value);
5166 //erase_by_mva(core, RD, DATA_TLB);
5167 //erase_by_mva(core, RD, INSN_TLB);
5168 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n");
5169 break;
5170 case 2: /* invalidate by asid */
5171 //invalidate_by_asid(state, value);
5172 //erase_by_asid(core, RD, DATA_TLB);
5173 //erase_by_asid(core, RD, INSN_TLB);
5174 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n");
5175 break;
5176 default:
5177 break;
5178 }
5179 break;
5180 default:
5181 break;
5182 }
5183 } else if(CRn == MMU_PID){
5184 if(OPCODE_2 == 0)
5185 CP15_REG(CP15_PID) = RD;
5186 else if(OPCODE_2 == 1)
5187 CP15_REG(CP15_CONTEXT_ID) = RD;
5188 else if(OPCODE_2 == 3){
5189 CP15_REG(CP15_THREAD_URO) = RD;
5190 }
5191 else{
5192 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn);
5193 }
5194
5195 } else {
5196 DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5197 }
5198 }
5199 }
5200 }
5201 cpu->Reg[15] += GET_INST_SIZE(cpu);
5202 INC_PC(sizeof(mcr_inst));
5203 FETCH_INST;
5204 GOTO_NEXT_INST;
5205 }
5206 MCRR_INST:
5207 MLA_INST:
5208 {
5209 INC_ICOUNTER;
5210 mla_inst *inst_cream = (mla_inst *)inst_base->component;
5211 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5212 uint64_t rm = RM;
5213 uint64_t rs = RS;
5214 uint64_t rn = RN;
5215 if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
5216 DEBUG_LOG(ARM11, "in __line__\n", __LINE__);
5217 CITRA_IGNORE_EXIT(-1);
5218 }
5219// RD = dst = RM * RS + RN;
5220 RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
5221 if (inst_cream->S) {
5222 UPDATE_NFLAG(dst);
5223 UPDATE_ZFLAG(dst);
5224 }
5225 if (inst_cream->Rd == 15) {
5226 INC_PC(sizeof(mla_inst));
5227 goto PROFILING;
5228 }
5229 }
5230 cpu->Reg[15] += GET_INST_SIZE(cpu);
5231 INC_PC(sizeof(mla_inst));
5232 FETCH_INST;
5233 GOTO_NEXT_INST;
5234 }
5235 MOV_INST:
5236 {
5237// DEBUG_LOG(ARM11, "mov inst\n");
5238// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
5239// debug_function(cpu);
5240// cpu->icount ++;
5241 INC_ICOUNTER;
5242 mov_inst *inst_cream = (mov_inst *)inst_base->component;
5243 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5244 RD = dst = SHIFTER_OPERAND;
5245 if (inst_cream->S && (inst_cream->Rd == 15)) {
5246 /* cpsr = spsr */
5247 if (CurrentModeHasSPSR) {
5248 cpu->Cpsr = cpu->Spsr_copy;
5249 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5250 LOAD_NZCVT;
5251 }
5252 } else if (inst_cream->S) {
5253 UPDATE_NFLAG(dst);
5254 UPDATE_ZFLAG(dst);
5255 UPDATE_CFLAG_WITH_SC;
5256 }
5257 if (inst_cream->Rd == 15) {
5258 INC_PC(sizeof(mov_inst));
5259 goto PROFILING;
5260 }
5261// return;
5262 }
5263 cpu->Reg[15] += GET_INST_SIZE(cpu);
5264 INC_PC(sizeof(mov_inst));
5265 FETCH_INST;
5266 GOTO_NEXT_INST;
5267 }
5268 MRC_INST:
5269 {
5270 INC_ICOUNTER;
5271 /* NOT IMPL */
5272 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
5273 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5274 unsigned int inst = inst_cream->inst;
5275 if (inst_cream->Rd == 15) {
5276 DEBUG_MSG;
5277 }
5278 if (inst_cream->inst == 0xeef04a10) {
5279 /* undefined instruction fmrx */
5280 RD = 0x20000000;
5281 CITRA_IGNORE_EXIT(-1);
5282 goto END;
5283 } else {
5284 if (inst_cream->cp_num == 15) {
5285 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5286 //LET(RD, CONST(0x0007b000));
5287 //LET(RD, CONST(0x410FB760));
5288 //LET(RD, R(CP15_MAIN_ID));
5289 RD = cpu->CP15[CP15(CP15_MAIN_ID)];
5290 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5291 //LET(RD, R(CP15_CONTROL));
5292 RD = cpu->CP15[CP15(CP15_CONTROL)];
5293 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5294 //LET(RD, R(CP15_CONTROL));
5295 RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
5296 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5297 //LET(RD, R(CP15_CONTROL));
5298 RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
5299 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5300 //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL));
5301 RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
5302 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5303 //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0));
5304 RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
5305 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
5306 //LET(RD, R(CP15_FAULT_STATUS));
5307 RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
5308 } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
5309 //LET(RD, R(CP15_FAULT_ADDRESS));
5310 RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
5311 } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
5312 //LET(RD, R(CP15_CACHE_TYPE));
5313 RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
5314 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
5315 //LET(RD, R(CP15_INSTR_FAULT_STATUS));
5316 RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
5317 } else if (CRn == 13) {
5318 if(OPCODE_2 == 0)
5319 RD = CP15_REG(CP15_PID);
5320 else if(OPCODE_2 == 1)
5321 RD = CP15_REG(CP15_CONTEXT_ID);
5322 else if(OPCODE_2 == 3){
5323 RD = Memory::KERNEL_MEMORY_VADDR;
5324 }
5325 else{
5326 printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn);
5327 }
5328 }
5329 else {
5330 DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5331 }
5332 }
5333 //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5334 }
5335 }
5336 cpu->Reg[15] += GET_INST_SIZE(cpu);
5337 INC_PC(sizeof(mrc_inst));
5338 FETCH_INST;
5339 GOTO_NEXT_INST;
5340 }
5341 MRRC_INST:
5342 MRS_INST:
5343 {
5344 INC_ICOUNTER;
5345 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
5346 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5347 if (inst_cream->R) {
5348 RD = cpu->Spsr_copy;
5349 } else {
5350 SAVE_NZCVT;
5351 RD = cpu->Cpsr;
5352 }
5353 }
5354 cpu->Reg[15] += GET_INST_SIZE(cpu);
5355 INC_PC(sizeof(mrs_inst));
5356 FETCH_INST;
5357 GOTO_NEXT_INST;
5358 }
5359 MSR_INST:
5360 {
5361 INC_ICOUNTER;
5362 msr_inst *inst_cream = (msr_inst *)inst_base->component;
5363 const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
5364 unsigned int inst = inst_cream->inst;
5365 unsigned int operand;
5366
5367 if (BIT(inst, 25)) {
5368 int rot_imm = BITS(inst, 8, 11) * 2;
5369 //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm));
5370 operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
5371 } else {
5372 //operand = R(RM);
5373 operand = cpu->Reg[BITS(inst, 0, 3)];
5374 }
5375 uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
5376 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
5377 uint32_t mask;
5378 if (!inst_cream->R) {
5379 if (InAPrivilegedMode(cpu)) {
5380 if ((operand & StateMask) != 0) {
5381 /* UNPREDICTABLE */
5382 DEBUG_MSG;
5383 } else
5384 mask = byte_mask & (UserMask | PrivMask);
5385 } else {
5386 mask = byte_mask & UserMask;
5387 }
5388 //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5389 SAVE_NZCVT;
5390
5391 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
5392 switch_mode(cpu, cpu->Cpsr & 0x1f);
5393 LOAD_NZCVT;
5394 } else {
5395 if (CurrentModeHasSPSR) {
5396 mask = byte_mask & (UserMask | PrivMask | StateMask);
5397 //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5398 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
5399 }
5400 }
5401 cpu->Reg[15] += GET_INST_SIZE(cpu);
5402 INC_PC(sizeof(msr_inst));
5403 FETCH_INST;
5404 GOTO_NEXT_INST;
5405 }
5406 MUL_INST:
5407 {
5408 INC_ICOUNTER;
5409 mul_inst *inst_cream = (mul_inst *)inst_base->component;
5410 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5411// RD = dst = SHIFTER_OPERAND;
5412 uint64_t rm = RM;
5413 uint64_t rs = RS;
5414 RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
5415 if (inst_cream->S) {
5416 UPDATE_NFLAG(dst);
5417 UPDATE_ZFLAG(dst);
5418 }
5419 if (inst_cream->Rd == 15) {
5420 INC_PC(sizeof(mul_inst));
5421 goto PROFILING;
5422 }
5423 }
5424 cpu->Reg[15] += GET_INST_SIZE(cpu);
5425 INC_PC(sizeof(mul_inst));
5426 FETCH_INST;
5427 GOTO_NEXT_INST;
5428 }
5429 MVN_INST:
5430 {
5431 INC_ICOUNTER;
5432 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
5433 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5434// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff);
5435 RD = dst = ~SHIFTER_OPERAND;
5436 if (inst_cream->S && (inst_cream->Rd == 15)) {
5437 /* cpsr = spsr */
5438 if (CurrentModeHasSPSR) {
5439 cpu->Cpsr = cpu->Spsr_copy;
5440 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5441 LOAD_NZCVT;
5442 }
5443 } else if (inst_cream->S) {
5444 UPDATE_NFLAG(dst);
5445 UPDATE_ZFLAG(dst);
5446 UPDATE_CFLAG_WITH_SC;
5447 }
5448 if (inst_cream->Rd == 15) {
5449 INC_PC(sizeof(mvn_inst));
5450 goto PROFILING;
5451 }
5452 }
5453 cpu->Reg[15] += GET_INST_SIZE(cpu);
5454 INC_PC(sizeof(mvn_inst));
5455 FETCH_INST;
5456 GOTO_NEXT_INST;
5457 }
5458 ORR_INST:
5459 {
5460 INC_ICOUNTER;
5461 orr_inst *inst_cream = (orr_inst *)inst_base->component;
5462 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5463 lop = RN;
5464 rop = SHIFTER_OPERAND;
5465// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]);
5466 RD = dst = lop | rop;
5467 if (inst_cream->S && (inst_cream->Rd == 15)) {
5468 /* cpsr = spsr*/
5469 if (CurrentModeHasSPSR) {
5470 cpu->Cpsr = cpu->Spsr_copy;
5471 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5472 LOAD_NZCVT;
5473 }
5474 } else if (inst_cream->S) {
5475 UPDATE_NFLAG(dst);
5476 UPDATE_ZFLAG(dst);
5477 UPDATE_CFLAG_WITH_SC;
5478// UPDATE_CFLAG(dst, lop, rop);
5479 }
5480 if (inst_cream->Rd == 15) {
5481 INC_PC(sizeof(orr_inst));
5482 goto PROFILING;
5483 }
5484 }
5485 cpu->Reg[15] += GET_INST_SIZE(cpu);
5486 INC_PC(sizeof(orr_inst));
5487 FETCH_INST;
5488 GOTO_NEXT_INST;
5489 }
5490 PKHBT_INST:
5491 PKHTB_INST:
5492 PLD_INST:
5493 {
5494 INC_ICOUNTER;
5495 /* NOT IMPL */
5496 cpu->Reg[15] += GET_INST_SIZE(cpu);
5497 INC_PC(sizeof(stc_inst));
5498 FETCH_INST;
5499 GOTO_NEXT_INST;
5500 }
5501 QADD_INST:
5502 QADD16_INST:
5503 QADD8_INST:
5504 QADDSUBX_INST:
5505 QDADD_INST:
5506 QDSUB_INST:
5507 QSUB_INST:
5508 QSUB16_INST:
5509 QSUB8_INST:
5510 QSUBADDX_INST:
5511 REV_INST:
5512 {
5513 INC_ICOUNTER;
5514 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5515 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5516 RD = ((RM & 0xff) << 24) |
5517 (((RM >> 8) & 0xff) << 16) |
5518 (((RM >> 16) & 0xff) << 8) |
5519 ((RM >> 24) & 0xff);
5520 if (inst_cream->Rm == 15) {
5521 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
5522 CITRA_IGNORE_EXIT(-1);
5523 }
5524 }
5525 cpu->Reg[15] += GET_INST_SIZE(cpu);
5526 INC_PC(sizeof(rev_inst));
5527 FETCH_INST;
5528 GOTO_NEXT_INST;
5529 }
5530 REV16_INST:
5531 {
5532 INC_ICOUNTER;
5533 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5534 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5535 RD = (BITS(RM, 0, 7) << 8) |
5536 BITS(RM, 8, 15) |
5537 (BITS(RM, 16, 23) << 24) |
5538 (BITS(RM, 24, 31) << 16);
5539 }
5540 cpu->Reg[15] += GET_INST_SIZE(cpu);
5541 INC_PC(sizeof(rev_inst));
5542 FETCH_INST;
5543 GOTO_NEXT_INST;
5544 }
5545 REVSH_INST:
5546 RFE_INST:
5547 RSB_INST:
5548 {
5549 INC_ICOUNTER;
5550 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
5551 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5552 rop = RN;
5553 lop = SHIFTER_OPERAND;
5554 if (inst_cream->Rn == 15) {
5555 rop += 2 * GET_INST_SIZE(cpu);;
5556 }
5557 RD = dst = lop - rop;
5558 if (inst_cream->S && (inst_cream->Rd == 15)) {
5559 /* cpsr = spsr */
5560 if (CurrentModeHasSPSR) {
5561 cpu->Cpsr = cpu->Spsr_copy;
5562 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5563 LOAD_NZCVT;
5564 }
5565 } else if (inst_cream->S) {
5566 UPDATE_NFLAG(dst);
5567 UPDATE_ZFLAG(dst);
5568 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
5569// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
5570 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
5571 }
5572 if (inst_cream->Rd == 15) {
5573 INC_PC(sizeof(rsb_inst));
5574 goto PROFILING;
5575 }
5576 }
5577 cpu->Reg[15] += GET_INST_SIZE(cpu);
5578 INC_PC(sizeof(rsb_inst));
5579 FETCH_INST;
5580 GOTO_NEXT_INST;
5581 }
5582 RSC_INST:
5583 {
5584 INC_ICOUNTER;
5585 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
5586 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5587 //lop = RN + !cpu->CFlag;
5588 //rop = SHIFTER_OPERAND;
5589 //RD = dst = rop - lop;
5590 lop = RN;
5591 rop = SHIFTER_OPERAND;
5592 RD = dst = rop - lop - !cpu->CFlag;
5593 if (inst_cream->S && (inst_cream->Rd == 15)) {
5594 /* cpsr = spsr */
5595 if (CurrentModeHasSPSR) {
5596 cpu->Cpsr = cpu->Spsr_copy;
5597 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5598 LOAD_NZCVT;
5599 }
5600 } else if (inst_cream->S) {
5601 UPDATE_NFLAG(dst);
5602 UPDATE_ZFLAG(dst);
5603// UPDATE_CFLAG(dst, lop, rop);
5604// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5605 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
5606// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5607 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
5608 }
5609 if (inst_cream->Rd == 15) {
5610 INC_PC(sizeof(rsc_inst));
5611 goto PROFILING;
5612 }
5613 }
5614 cpu->Reg[15] += GET_INST_SIZE(cpu);
5615 INC_PC(sizeof(rsc_inst));
5616 FETCH_INST;
5617 GOTO_NEXT_INST;
5618 }
5619 SADD16_INST:
5620 SADD8_INST:
5621 SADDSUBX_INST:
5622 SBC_INST:
5623 {
5624 INC_ICOUNTER;
5625 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
5626 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5627 lop = SHIFTER_OPERAND + !cpu->CFlag;
5628 rop = RN;
5629 RD = dst = rop - lop;
5630 if (inst_cream->S && (inst_cream->Rd == 15)) {
5631 /* cpsr = spsr */
5632 if (CurrentModeHasSPSR) {
5633 cpu->Cpsr = cpu->Spsr_copy;
5634 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5635 LOAD_NZCVT;
5636 }
5637 } else if (inst_cream->S) {
5638 UPDATE_NFLAG(dst);
5639 UPDATE_ZFLAG(dst);
5640// UPDATE_CFLAG(dst, lop, rop);
5641 //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5642 //rop = rop - !cpu->CFlag;
5643 if(rop >= !cpu->CFlag)
5644 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
5645 else
5646 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
5647// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5648 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
5649 }
5650 if (inst_cream->Rd == 15) {
5651 INC_PC(sizeof(sbc_inst));
5652 goto PROFILING;
5653 }
5654 }
5655 cpu->Reg[15] += GET_INST_SIZE(cpu);
5656 INC_PC(sizeof(sbc_inst));
5657 FETCH_INST;
5658 GOTO_NEXT_INST;
5659 }
5660 SEL_INST:
5661 SETEND_INST:
5662 SHADD16_INST:
5663 SHADD8_INST:
5664 SHADDSUBX_INST:
5665 SHSUB16_INST:
5666 SHSUB8_INST:
5667 SHSUBADDX_INST:
5668 SMLA_INST:
5669 {
5670 INC_ICOUNTER;
5671 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5672 smla_inst *inst_cream = (smla_inst *)inst_base->component;
5673 int32_t operand1, operand2;
5674 if (inst_cream->x == 0)
5675 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5676 else
5677 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5678
5679 if (inst_cream->y == 0)
5680 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5681 else
5682 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5683 RD = operand1 * operand2 + RN;
5684 //FIXME: UPDATE Q FLAGS
5685 }
5686 cpu->Reg[15] += GET_INST_SIZE(cpu);
5687 INC_PC(sizeof(smla_inst));
5688 FETCH_INST;
5689 GOTO_NEXT_INST;
5690 }
5691 SMLAD_INST:
5692 {
5693 INC_ICOUNTER;
5694 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5695 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5696 long long int rm = cpu->Reg[inst_cream->Rm];
5697 long long int rn = cpu->Reg[inst_cream->Rn];
5698 long long int ra = cpu->Reg[inst_cream->Ra];
5699 /* see SMUAD */
5700 if(inst_cream->Ra == 15)
5701 CITRA_IGNORE_EXIT(-1);
5702 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
5703
5704 int half_rn, half_operand2;
5705 half_rn = rn & 0xFFFF;
5706 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5707
5708 half_operand2 = operand2 & 0xFFFF;
5709 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5710
5711 long long int product1 = half_rn * half_operand2;
5712
5713 half_rn = (rn & 0xFFFF0000) >> 16;
5714 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5715
5716 half_operand2 = (operand2 & 0xFFFF0000) >> 16;
5717 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5718
5719 long long int product2 = half_rn * half_operand2;
5720
5721 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
5722 long long int result = product1 + product2 + signed_ra;
5723 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
5724 /* FIXME , should check Signed overflow */
5725 }
5726 cpu->Reg[15] += GET_INST_SIZE(cpu);
5727 INC_PC(sizeof(umlal_inst));
5728 FETCH_INST;
5729 GOTO_NEXT_INST;
5730 }
5731
5732 SMLAL_INST:
5733 {
5734 INC_ICOUNTER;
5735 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5736 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
5737 long long int rm = RM;
5738 long long int rs = RS;
5739 if (BIT(rm, 31)) {
5740 rm |= 0xffffffff00000000LL;
5741 }
5742 if (BIT(rs, 31)) {
5743 rs |= 0xffffffff00000000LL;
5744 }
5745 long long int rst = rm * rs;
5746 long long int rdhi32 = RDHI;
5747 long long int hilo = (rdhi32 << 32) + RDLO;
5748 rst += hilo;
5749 RDLO = BITS(rst, 0, 31);
5750 RDHI = BITS(rst, 32, 63);
5751 if (inst_cream->S) {
5752 cpu->NFlag = BIT(RDHI, 31);
5753 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5754 }
5755 }
5756 cpu->Reg[15] += GET_INST_SIZE(cpu);
5757 INC_PC(sizeof(umlal_inst));
5758 FETCH_INST;
5759 GOTO_NEXT_INST;
5760 }
5761 SMLALXY_INST:
5762 SMLALD_INST:
5763 SMLAW_INST:
5764 SMLSD_INST:
5765 SMLSLD_INST:
5766 SMMLA_INST:
5767 SMMLS_INST:
5768 SMMUL_INST:
5769 SMUAD_INST:
5770 SMUL_INST:
5771 {
5772 INC_ICOUNTER;
5773 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5774 smul_inst *inst_cream = (smul_inst *)inst_base->component;
5775 uint32_t operand1, operand2;
5776 if (inst_cream->x == 0)
5777 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5778 else
5779 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5780
5781 if (inst_cream->y == 0)
5782 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5783 else
5784 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5785 RD = operand1 * operand2;
5786 }
5787 cpu->Reg[15] += GET_INST_SIZE(cpu);
5788 INC_PC(sizeof(smul_inst));
5789 FETCH_INST;
5790 GOTO_NEXT_INST;
5791 }
5792 SMULL_INST:
5793 {
5794 INC_ICOUNTER;
5795 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5796 umull_inst *inst_cream = (umull_inst *)inst_base->component;
5797// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5798 int64_t rm = RM;
5799 int64_t rs = RS;
5800 if (BIT(rm, 31)) {
5801 rm |= 0xffffffff00000000LL;
5802 }
5803 if (BIT(rs, 31)) {
5804 rs |= 0xffffffff00000000LL;
5805 }
5806 int64_t rst = rm * rs;
5807 RDHI = BITS(rst, 32, 63);
5808 RDLO = BITS(rst, 0, 31);
5809
5810
5811 if (inst_cream->S) {
5812 cpu->NFlag = BIT(RDHI, 31);
5813 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5814 }
5815 }
5816 cpu->Reg[15] += GET_INST_SIZE(cpu);
5817 INC_PC(sizeof(umull_inst));
5818 FETCH_INST;
5819 GOTO_NEXT_INST;
5820 }
5821 SMULW_INST:
5822 INC_ICOUNTER;
5823 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5824 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5825// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5826 int64_t rm = RM;
5827 int64_t rn = RN;
5828 if (inst_cream->m)
5829 rm = BITS(rm,16 , 31);
5830 else
5831 rm = BITS(rm,0 , 15);
5832 int64_t rst = rm * rn;
5833 RD = BITS(rst, 16, 47);
5834 }
5835 cpu->Reg[15] += GET_INST_SIZE(cpu);
5836 INC_PC(sizeof(smlad_inst));
5837 FETCH_INST;
5838 GOTO_NEXT_INST;
5839
5840 SMUSD_INST:
5841 SRS_INST:
5842 SSAT_INST:
5843 SSAT16_INST:
5844 SSUB16_INST:
5845 SSUB8_INST:
5846 SSUBADDX_INST:
5847 STC_INST:
5848 {
5849 INC_ICOUNTER;
5850 /* NOT IMPL */
5851 cpu->Reg[15] += GET_INST_SIZE(cpu);
5852 INC_PC(sizeof(stc_inst));
5853 FETCH_INST;
5854 GOTO_NEXT_INST;
5855 }
5856 STM_INST:
5857 {
5858 INC_ICOUNTER;
5859 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5860 unsigned int inst = inst_cream->inst;
5861 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5862 int i;
5863 unsigned int Rn = BITS(inst, 16, 19);
5864 unsigned int old_RN = cpu->Reg[Rn];
5865
5866 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5867 if (fault) goto MMU_EXCEPTION;
5868 if (BIT(inst_cream->inst, 22) == 1) {
5869// DEBUG_MSG;
5870 #if 1
5871 for (i = 0; i < 13; i++) {
5872 if(BIT(inst_cream->inst, i)){
5873 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5874 if (fault) {
5875 goto MMU_EXCEPTION;
5876 }
5877 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5878 if (fault) goto MMU_EXCEPTION;
5879 addr += 4;
5880 phys_addr += 4;
5881 }
5882 }
5883 if (BIT(inst_cream->inst, 13)) {
5884 if (cpu->Mode == USER32MODE) {
5885 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5886 if (fault) {
5887 goto MMU_EXCEPTION;
5888 }
5889 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5890 if (fault) goto MMU_EXCEPTION;
5891 addr += 4;
5892 phys_addr += 4;
5893 } else {
5894 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
5895 if (fault) goto MMU_EXCEPTION;
5896 addr += 4;
5897 phys_addr += 4;
5898 }
5899 }
5900 if (BIT(inst_cream->inst, 14)) {
5901 if (cpu->Mode == USER32MODE) {
5902 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5903 if (fault) {
5904 goto MMU_EXCEPTION;
5905 }
5906 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5907 if (fault) goto MMU_EXCEPTION;
5908 addr += 4;
5909 phys_addr += 4;
5910 } else {
5911 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5912 if (fault) {
5913 goto MMU_EXCEPTION;
5914 }
5915 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
5916 if (fault) goto MMU_EXCEPTION;
5917 addr += 4;
5918 phys_addr += 4;
5919 }
5920 }
5921 if (BIT(inst_cream->inst, 15)) {
5922 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5923 if (fault) {
5924 goto MMU_EXCEPTION;
5925 }
5926 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5927 if (fault) goto MMU_EXCEPTION;
5928 }
5929 #endif
5930 } else {
5931 for( i = 0; i < 15; i ++ ){
5932 if(BIT(inst_cream->inst, i)){
5933 //arch_write_memory(cpu, bb, Addr, R(i), 32);
5934 //bus_write(32, addr, cpu->Reg[i]);
5935 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5936 if (fault) {
5937 goto MMU_EXCEPTION;
5938 }
5939 if(i == Rn)
5940 fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
5941 else
5942 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5943 if (fault) goto MMU_EXCEPTION;
5944 addr += 4;
5945 phys_addr += 4;
5946 //Addr = ADD(Addr, CONST(4));
5947 }
5948 }
5949
5950 /* check pc reg*/
5951 if(BIT(inst_cream->inst, i)){
5952 //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32);
5953 //bus_write(32, addr, cpu->Reg[i] + 8);
5954 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5955 if (fault) {
5956 goto MMU_EXCEPTION;
5957 }
5958 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5959 if (fault) goto MMU_EXCEPTION;
5960 }
5961 }
5962 }
5963 cpu->Reg[15] += GET_INST_SIZE(cpu);
5964 INC_PC(sizeof(ldst_inst));
5965 FETCH_INST;
5966 GOTO_NEXT_INST;
5967 }
5968 SXTB_INST:
5969 {
5970 INC_ICOUNTER;
5971 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
5972 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5973 if (inst_cream->Rm == 15) {
5974 DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
5975 CITRA_IGNORE_EXIT(-1);
5976 }
5977 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
5978 if (BIT(operand2, 7)) {
5979 operand2 |= 0xffffff00;
5980 } else
5981 operand2 &= 0xff;
5982 RD = operand2;
5983 }
5984 cpu->Reg[15] += GET_INST_SIZE(cpu);
5985 INC_PC(sizeof(sxtb_inst));
5986 FETCH_INST;
5987 GOTO_NEXT_INST;
5988 }
5989 STR_INST:
5990 {
5991 INC_ICOUNTER;
5992 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5993 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5994 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5995 if (fault) goto MMU_EXCEPTION;
5996 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
5997 //bus_write(32, addr, value);
5998 fault = interpreter_write_memory(addr, phys_addr, value, 32);
5999 if (fault) goto MMU_EXCEPTION;
6000 }
6001 cpu->Reg[15] += GET_INST_SIZE(cpu);
6002 INC_PC(sizeof(ldst_inst));
6003 FETCH_INST;
6004 GOTO_NEXT_INST;
6005 }
6006 UXTB_INST:
6007 {
6008 INC_ICOUNTER;
6009 uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
6010 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6011 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6012 & 0xff;
6013 RD = operand2;
6014 }
6015 cpu->Reg[15] += GET_INST_SIZE(cpu);
6016 INC_PC(sizeof(uxtb_inst));
6017 FETCH_INST;
6018 GOTO_NEXT_INST;
6019 }
6020 UXTAB_INST:
6021 {
6022 INC_ICOUNTER;
6023 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
6024 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6025 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6026 & 0xff;
6027 RD = RN + operand2;
6028 }
6029 cpu->Reg[15] += GET_INST_SIZE(cpu);
6030 INC_PC(sizeof(uxtab_inst));
6031 FETCH_INST;
6032 GOTO_NEXT_INST;
6033 }
6034 STRB_INST:
6035 {
6036 INC_ICOUNTER;
6037 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6038 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6039 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6040 if (fault) goto MMU_EXCEPTION;
6041 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6042 //bus_write(8, addr, value);
6043 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6044 if (fault) goto MMU_EXCEPTION;
6045 }
6046 cpu->Reg[15] += GET_INST_SIZE(cpu);
6047 INC_PC(sizeof(ldst_inst));
6048 FETCH_INST;
6049 GOTO_NEXT_INST;
6050 }
6051 STRBT_INST:
6052 {
6053 INC_ICOUNTER;
6054 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6055 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6056 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6057 if (fault) goto MMU_EXCEPTION;
6058 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6059 //bus_write(8, addr, value);
6060 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6061 if (fault) goto MMU_EXCEPTION;
6062 }
6063 cpu->Reg[15] += GET_INST_SIZE(cpu);
6064 //if (BITS(inst_cream->inst, 12, 15) == 15)
6065 // goto PROFILING;
6066 INC_PC(sizeof(ldst_inst));
6067 FETCH_INST;
6068 GOTO_NEXT_INST;
6069 }
6070 STRD_INST:
6071 {
6072 INC_ICOUNTER;
6073 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6074 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6075 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6076 if (fault) goto MMU_EXCEPTION;
6077 uint32_t rear_phys_addr;
6078 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
6079 if (fault){
6080 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
6081 CITRA_IGNORE_EXIT(-1);
6082 goto MMU_EXCEPTION;
6083 }
6084
6085 //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0);
6086 //if (fault) goto MMU_EXCEPTION;
6087
6088 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6089 //bus_write(32, addr, value);
6090 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6091 if (fault) goto MMU_EXCEPTION;
6092 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
6093 //bus_write(32, addr, value);
6094 fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
6095 if (fault) goto MMU_EXCEPTION;
6096 }
6097 cpu->Reg[15] += GET_INST_SIZE(cpu);
6098 INC_PC(sizeof(ldst_inst));
6099 FETCH_INST;
6100 GOTO_NEXT_INST;
6101 }
6102 STREX_INST:
6103 {
6104 INC_ICOUNTER;
6105 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6106 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6107 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6108 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
6109 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6110 if (fault) goto MMU_EXCEPTION;
6111
6112 int dest_reg = BITS(inst_cream->inst, 12, 15);
6113 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6114 remove_exclusive(cpu, phys_addr);
6115 cpu->Reg[dest_reg] = 0;
6116 cpu->exclusive_state = 0;
6117
6118 // bus_write(32, addr, value);
6119 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6120 if (fault) goto MMU_EXCEPTION;
6121 }
6122 else{
6123 /* Failed to write due to mutex access */
6124 cpu->Reg[dest_reg] = 1;
6125 }
6126 }
6127 cpu->Reg[15] += GET_INST_SIZE(cpu);
6128 INC_PC(sizeof(ldst_inst));
6129 FETCH_INST;
6130 GOTO_NEXT_INST;
6131 }
6132 STREXB_INST:
6133 {
6134 INC_ICOUNTER;
6135 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6136 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6137 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6138 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
6139 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6140 if (fault) goto MMU_EXCEPTION;
6141 //bus_write(8, addr, value);
6142 int dest_reg = BITS(inst_cream->inst, 12, 15);
6143 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6144 remove_exclusive(cpu, phys_addr);
6145 cpu->Reg[dest_reg] = 0;
6146 cpu->exclusive_state = 0;
6147 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6148 if (fault) goto MMU_EXCEPTION;
6149
6150 }
6151 else{
6152 cpu->Reg[dest_reg] = 1;
6153 }
6154 }
6155 cpu->Reg[15] += GET_INST_SIZE(cpu);
6156 INC_PC(sizeof(ldst_inst));
6157 FETCH_INST;
6158 GOTO_NEXT_INST;
6159 }
6160 STRH_INST:
6161 {
6162 INC_ICOUNTER;
6163 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6164 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6165 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6166 if (fault) goto MMU_EXCEPTION;
6167 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6168 //bus_write(16, addr, value);
6169 fault = interpreter_write_memory(addr, phys_addr, value, 16);
6170 if (fault) goto MMU_EXCEPTION;
6171 }
6172 cpu->Reg[15] += GET_INST_SIZE(cpu);
6173 //if (BITS(inst_cream->inst, 12, 15) == 15)
6174 // goto PROFILING;
6175 INC_PC(sizeof(ldst_inst));
6176 FETCH_INST;
6177 GOTO_NEXT_INST;
6178 }
6179 STRT_INST:
6180 {
6181 INC_ICOUNTER;
6182 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6183 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6184 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6185 if (fault) goto MMU_EXCEPTION;
6186 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6187 //bus_write(16, addr, value);
6188 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6189 if (fault) goto MMU_EXCEPTION;
6190 }
6191 cpu->Reg[15] += GET_INST_SIZE(cpu);
6192 INC_PC(sizeof(ldst_inst));
6193 FETCH_INST;
6194 GOTO_NEXT_INST;
6195 }
6196 SUB_INST:
6197 {
6198 INC_ICOUNTER;
6199 sub_inst *inst_cream = (sub_inst *)inst_base->component;
6200 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6201 lop = RN;
6202 if (inst_cream->Rn == 15) {
6203 lop += 8;
6204 }
6205 rop = SHIFTER_OPERAND;
6206 RD = dst = lop - rop;
6207 if (inst_cream->S && (inst_cream->Rd == 15)) {
6208 /* cpsr = spsr */
6209 if (CurrentModeHasSPSR) {
6210 cpu->Cpsr = cpu->Spsr_copy;
6211 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
6212 LOAD_NZCVT;
6213 }
6214 } else if (inst_cream->S) {
6215 UPDATE_NFLAG(dst);
6216 UPDATE_ZFLAG(dst);
6217// UPDATE_CFLAG(dst, lop, rop);
6218 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
6219 // UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
6220 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
6221 }
6222 if (inst_cream->Rd == 15) {
6223 INC_PC(sizeof(sub_inst));
6224 goto PROFILING;
6225 }
6226 }
6227 cpu->Reg[15] += GET_INST_SIZE(cpu);
6228 INC_PC(sizeof(sub_inst));
6229 FETCH_INST;
6230 GOTO_NEXT_INST;
6231 }
6232 SWI_INST:
6233 {
6234 INC_ICOUNTER;
6235 swi_inst *inst_cream = (swi_inst *)inst_base->component;
6236 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6237 if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode
6238 //arm_dyncom_SWI(cpu, inst_cream->num);
6239 HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
6240 } else {
6241 cpu->syscallSig = 1;
6242 goto END;
6243 }
6244 }
6245 cpu->Reg[15] += GET_INST_SIZE(cpu);
6246 INC_PC(sizeof(swi_inst));
6247 FETCH_INST;
6248 GOTO_NEXT_INST;
6249 }
6250 SWP_INST:
6251 {
6252 INC_ICOUNTER;
6253 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6254 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6255 addr = RN;
6256 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6257 if (fault) goto MMU_EXCEPTION;
6258 unsigned int value;
6259 fault = interpreter_read_memory(addr, phys_addr, value, 32);
6260 if (fault) goto MMU_EXCEPTION;
6261 fault = interpreter_write_memory(addr, phys_addr, RM, 32);
6262 if (fault) goto MMU_EXCEPTION;
6263
6264 /* ROR(data, 8*UInt(address<1:0>)); */
6265 assert((phys_addr & 0x3) == 0);
6266 RD = value;
6267 }
6268 cpu->Reg[15] += GET_INST_SIZE(cpu);
6269 INC_PC(sizeof(swp_inst));
6270 FETCH_INST;
6271 GOTO_NEXT_INST;
6272 }
6273 SWPB_INST:
6274 {
6275 INC_ICOUNTER;
6276 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6277 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6278 addr = RN;
6279 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6280 if (fault) goto MMU_EXCEPTION;
6281 unsigned int value;
6282 fault = interpreter_read_memory(addr, phys_addr, value, 8);
6283 if (fault) goto MMU_EXCEPTION;
6284 fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
6285 if (fault) goto MMU_EXCEPTION;
6286
6287 /* FIXME */
6288 #if 0
6289 if Shared(address) then
6290 /* ARMv6 */
6291 physical_address = TLB(address)
6292 ClearExclusiveByAddress(physical_address,processor_id,1)
6293 /* See Summary of operation on page A2-49 */
6294 #endif
6295 }
6296 cpu->Reg[15] += GET_INST_SIZE(cpu);
6297 INC_PC(sizeof(swp_inst));
6298 FETCH_INST;
6299 GOTO_NEXT_INST;
6300 }
6301 SXTAB_INST:
6302 {
6303 INC_ICOUNTER;
6304 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
6305 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6306 /* R15 should be check */
6307 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6308 CITRA_IGNORE_EXIT(-1);
6309 }
6310 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6311 & 0xff;
6312 /* sign extend for byte */
6313 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
6314 RD = RN + operand2;
6315 }
6316 cpu->Reg[15] += GET_INST_SIZE(cpu);
6317 INC_PC(sizeof(uxtab_inst));
6318 FETCH_INST;
6319 GOTO_NEXT_INST;
6320 }
6321 SXTAB16_INST:
6322 SXTAH_INST:
6323 {
6324 INC_ICOUNTER;
6325 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
6326 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6327 /* R15 should be check */
6328 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6329 CITRA_IGNORE_EXIT(-1);
6330 }
6331 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
6332 /* sign extend for half */
6333 operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2;
6334 RD = RN + operand2;
6335 }
6336 cpu->Reg[15] += GET_INST_SIZE(cpu);
6337 INC_PC(sizeof(sxtah_inst));
6338 FETCH_INST;
6339 GOTO_NEXT_INST;
6340 }
6341 SXTB16_INST:
6342 TEQ_INST:
6343 {
6344 INC_ICOUNTER;
6345 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6346 teq_inst *inst_cream = (teq_inst *)inst_base->component;
6347 lop = RN;
6348 if (inst_cream->Rn == 15)
6349 lop += GET_INST_SIZE(cpu) * 2;
6350
6351 rop = SHIFTER_OPERAND;
6352 dst = lop ^ rop;
6353
6354 UPDATE_NFLAG(dst);
6355 UPDATE_ZFLAG(dst);
6356 UPDATE_CFLAG_WITH_SC;
6357 }
6358 cpu->Reg[15] += GET_INST_SIZE(cpu);
6359 INC_PC(sizeof(teq_inst));
6360 FETCH_INST;
6361 GOTO_NEXT_INST;
6362 }
6363 TST_INST:
6364 {
6365 INC_ICOUNTER;
6366 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6367 tst_inst *inst_cream = (tst_inst *)inst_base->component;
6368 lop = RN;
6369 if (inst_cream->Rn == 15)
6370 lop += GET_INST_SIZE(cpu) * 2;
6371 rop = SHIFTER_OPERAND;
6372 dst = lop & rop;
6373
6374 UPDATE_NFLAG(dst);
6375 UPDATE_ZFLAG(dst);
6376 UPDATE_CFLAG_WITH_SC;
6377 }
6378 cpu->Reg[15] += GET_INST_SIZE(cpu);
6379 INC_PC(sizeof(tst_inst));
6380 FETCH_INST;
6381 GOTO_NEXT_INST;
6382 }
6383 UADD16_INST:
6384 UADD8_INST:
6385 UADDSUBX_INST:
6386 UHADD16_INST:
6387 UHADD8_INST:
6388 UHADDSUBX_INST:
6389 UHSUB16_INST:
6390 UHSUB8_INST:
6391 UHSUBADDX_INST:
6392 UMAAL_INST:
6393 UMLAL_INST:
6394 {
6395 INC_ICOUNTER;
6396 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6397 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
6398 unsigned long long int rm = RM;
6399 unsigned long long int rs = RS;
6400 unsigned long long int rst = rm * rs;
6401 unsigned long long int add = ((unsigned long long) RDHI)<<32;
6402 add += RDLO;
6403 //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add);
6404 rst += add;
6405 RDLO = BITS(rst, 0, 31);
6406 RDHI = BITS(rst, 32, 63);
6407
6408 if (inst_cream->S)
6409 {
6410 cpu->NFlag = BIT(RDHI, 31);
6411 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6412 }
6413 }
6414 cpu->Reg[15] += GET_INST_SIZE(cpu);
6415 INC_PC(sizeof(umlal_inst));
6416 FETCH_INST;
6417 GOTO_NEXT_INST;
6418 }
6419 UMULL_INST:
6420 {
6421 INC_ICOUNTER;
6422 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6423 umull_inst *inst_cream = (umull_inst *)inst_base->component;
6424 unsigned long long int rm = RM;
6425 unsigned long long int rs = RS;
6426 unsigned long long int rst = rm * rs;
6427// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
6428 RDHI = BITS(rst, 32, 63);
6429 RDLO = BITS(rst, 0, 31);
6430
6431 if (inst_cream->S) {
6432 cpu->NFlag = BIT(RDHI, 31);
6433 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6434 }
6435 }
6436 cpu->Reg[15] += GET_INST_SIZE(cpu);
6437 INC_PC(sizeof(umull_inst));
6438 FETCH_INST;
6439 GOTO_NEXT_INST;
6440 }
6441 B_2_THUMB:
6442 {
6443 INC_ICOUNTER;
6444 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
6445 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6446 //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]);
6447 INC_PC(sizeof(b_2_thumb));
6448 goto PROFILING;
6449 }
6450 B_COND_THUMB:
6451 {
6452 INC_ICOUNTER;
6453 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
6454 if(CondPassed(cpu, inst_cream->cond))
6455 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6456 else
6457 cpu->Reg[15] += 2;
6458 //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]);
6459 INC_PC(sizeof(b_cond_thumb));
6460 goto PROFILING;
6461 }
6462 BL_1_THUMB:
6463 {
6464 INC_ICOUNTER;
6465 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
6466 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
6467 //cpu->Reg[15] += 2;
6468 //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]);
6469
6470 cpu->Reg[15] += GET_INST_SIZE(cpu);
6471 INC_PC(sizeof(bl_1_thumb));
6472 FETCH_INST;
6473 GOTO_NEXT_INST;
6474
6475 }
6476 BL_2_THUMB:
6477 {
6478 INC_ICOUNTER;
6479 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
6480 int tmp = ((cpu->Reg[15] + 2) | 1);
6481 cpu->Reg[15] =
6482 (cpu->Reg[14] + inst_cream->imm);
6483 cpu->Reg[14] = tmp;
6484 //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]);
6485 INC_PC(sizeof(bl_2_thumb));
6486 goto PROFILING;
6487 }
6488 BLX_1_THUMB:
6489 {
6490 /* BLX 1 for armv5t and above */
6491 INC_ICOUNTER;
6492 uint32 tmp = cpu->Reg[15];
6493 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
6494 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
6495 //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);
6496 cpu->Reg[14] = ((tmp + 2) | 1);
6497 //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
6498 /* switch to arm state from thumb state */
6499 cpu->TFlag = 0;
6500 //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]);
6501 INC_PC(sizeof(blx_1_thumb));
6502 goto PROFILING;
6503 }
6504
6505 UQADD16_INST:
6506 UQADD8_INST:
6507 UQADDSUBX_INST:
6508 UQSUB16_INST:
6509 UQSUB8_INST:
6510 UQSUBADDX_INST:
6511 USAD8_INST:
6512 USADA8_INST:
6513 USAT_INST:
6514 USAT16_INST:
6515 USUB16_INST:
6516 USUB8_INST:
6517 USUBADDX_INST:
6518 UXTAB16_INST:
6519 UXTB16_INST:
6520 #define VFP_INTERPRETER_IMPL
6521 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
6522 #undef VFP_INTERPRETER_IMPL
6523 MMU_EXCEPTION:
6524 {
6525 SAVE_NZCVT;
6526 cpu->abortSig = true;
6527 cpu->Aborted = ARMul_DataAbortV;
6528 cpu->AbortAddr = addr;
6529 cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
6530 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
6531 return;
6532 }
6533 END:
6534 {
6535 SAVE_NZCVT;
6536 return;
6537 }
6538 INIT_INST_LENGTH:
6539 {
6540#if 0
6541 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6542 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6543 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6544 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6545#endif
6546#ifdef __GNUC__
6547 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
6548#endif
6549#if 0
6550 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6551 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6552 DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
6553 DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
6554 DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
6555#endif
6556 return;
6557 }
6558}
6559
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
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 64760500c..49ae01a0c 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -10,7 +10,7 @@
10#include "core/arm/skyeye_common/armdefs.h" 10#include "core/arm/skyeye_common/armdefs.h"
11#include "core/arm/skyeye_common/armemu.h" 11#include "core/arm/skyeye_common/armemu.h"
12 12
13class ARM_Interpreter : virtual public ARM_Interface { 13class ARM_Interpreter final : virtual public ARM_Interface {
14public: 14public:
15 15
16 ARM_Interpreter(); 16 ARM_Interpreter();
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 3d3545c65..2568b93ef 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -15,18 +15,11 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18//#include <util.h> 18#include "core/arm/skyeye_common/armdefs.h"
19 19#include "core/arm/skyeye_common/armemu.h"
20#include <string>
21#include "core/arm/interpreter/armdefs.h"
22#include "core/arm/interpreter/armemu.h"
23#include "core/hle/coprocessor.h"
24#include "core/arm/disassembler/arm_disasm.h" 20#include "core/arm/disassembler/arm_disasm.h"
21#include "core/mem_map.h"
25 22
26//#include "ansidecl.h"
27//#include "skyeye.h"
28//extern int skyeye_instr_debug;
29/* Definitions for the support routines. */
30 23
31static ARMword ModeToBank (ARMword); 24static ARMword ModeToBank (ARMword);
32static void EnvokeList (ARMul_State *, unsigned int, unsigned int); 25static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
@@ -751,7 +744,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
751 int cpopc = BITS(21, 23) & 0x7; 744 int cpopc = BITS(21, 23) & 0x7;
752 745
753 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer 746 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
754 ARMword result = HLE::CallMRC(instr); 747 ARMword result = Memory::KERNEL_MEMORY_VADDR;
755 748
756 if (result != -1) { 749 if (result != -1) {
757 return result; 750 return result;
diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h
index 0ca62780b..4dac1a8bf 100644
--- a/src/core/arm/skyeye_common/arm_regformat.h
+++ b/src/core/arm/skyeye_common/arm_regformat.h
@@ -99,5 +99,7 @@ enum arm_regno{
99 MAX_REG_NUM, 99 MAX_REG_NUM,
100}; 100};
101 101
102#define VFP_OFFSET(x) (x - VFP_BASE) 102#define CP15(idx) (idx - CP15_BASE)
103#define VFP_OFFSET(x) (x - VFP_BASE)
104
103#endif 105#endif
diff --git a/src/core/arm/skyeye_common/armcpu.h b/src/core/arm/skyeye_common/armcpu.h
index 6b5ea8566..3a029f0e7 100644
--- a/src/core/arm/skyeye_common/armcpu.h
+++ b/src/core/arm/skyeye_common/armcpu.h
@@ -20,16 +20,13 @@
20 20
21#ifndef __ARM_CPU_H__ 21#ifndef __ARM_CPU_H__
22#define __ARM_CPU_H__ 22#define __ARM_CPU_H__
23//#include <skyeye_thread.h>
24//#include <skyeye_obj.h>
25//#include <skyeye_mach.h>
26//#include <skyeye_exec.h>
27 23
28#include <stddef.h> 24#include <stddef.h>
29#include <stdio.h> 25#include <stdio.h>
30 26
31#include "common/thread.h" 27#include "common/thread.h"
32 28
29#include "core/arm/skyeye_common/armdefs.h"
33 30
34typedef struct ARM_CPU_State_s { 31typedef struct ARM_CPU_State_s {
35 ARMul_State * core; 32 ARMul_State * core;
diff --git a/src/core/arm/skyeye_common/armos.h b/src/core/arm/skyeye_common/armos.h
index 4b58801ad..ffdadcd1c 100644
--- a/src/core/arm/skyeye_common/armos.h
+++ b/src/core/arm/skyeye_common/armos.h
@@ -15,14 +15,7 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18//#include "bank_defs.h" 18#include <stdint.h>
19//#include "dyncom/defines.h"
20
21//typedef struct mmap_area{
22// mem_bank_t bank;
23// void *mmap_addr;
24// struct mmap_area *next;
25//}mmap_area_t;
26 19
27#if FAST_MEMORY 20#if FAST_MEMORY
28/* in user mode, mmap_base will be on initial brk, 21/* in user mode, mmap_base will be on initial brk,
diff --git a/src/core/arm/skyeye_common/skyeye_defs.h b/src/core/arm/skyeye_common/skyeye_defs.h
index b6713ebad..d4088383f 100644
--- a/src/core/arm/skyeye_common/skyeye_defs.h
+++ b/src/core/arm/skyeye_common/skyeye_defs.h
@@ -108,4 +108,6 @@ typedef struct generic_arch_s
108 align_t alignment; 108 align_t alignment;
109} generic_arch_t; 109} generic_arch_t;
110 110
111#endif \ No newline at end of file 111typedef u32 addr_t;
112
113#endif
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
new file mode 100644
index 000000000..e7f022f19
--- /dev/null
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -0,0 +1,55 @@
1/*
2 skyeye_types.h - some data types definition for skyeye debugger
3 Copyright (C) 2003 Skyeye Develop Group
4 for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20*/
21/*
22 * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com>
23 */
24
25#ifndef __SKYEYE_TYPES_H
26#define __SKYEYE_TYPES_H
27
28#include <stdint.h>
29
30/*default machine word length */
31
32#ifndef __BEOS__
33/* To avoid the type conflict with the qemu */
34#ifndef QEMU
35typedef uint8_t uint8;
36typedef uint16_t uint16;
37typedef uint32_t uint32;
38typedef uint64_t uint64;
39
40typedef int8_t sint8;
41typedef int16_t sint16;
42typedef int32_t sint32;
43typedef int64_t sint64;
44#endif
45
46typedef uint32_t address_t;
47typedef uint32_t uinteger_t;
48typedef int32_t integer_t;
49
50typedef uint32_t physical_address_t;
51typedef uint32_t generic_address_t;
52
53#endif
54
55#endif
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index a57047911..45208fb13 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -3709,7 +3709,7 @@ VFPLABEL_INST:
3709 { 3709 {
3710 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3710 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3711 if (fault) goto MMU_EXCEPTION; 3711 if (fault) goto MMU_EXCEPTION;
3712 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); 3712 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
3713 if (fault) goto MMU_EXCEPTION; 3713 if (fault) goto MMU_EXCEPTION;
3714 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]); 3714 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]);
3715 } 3715 }
@@ -3719,13 +3719,13 @@ VFPLABEL_INST:
3719 if (fault) goto MMU_EXCEPTION; 3719 if (fault) goto MMU_EXCEPTION;
3720 3720
3721 /* Check endianness */ 3721 /* Check endianness */
3722 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32); 3722 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32);
3723 if (fault) goto MMU_EXCEPTION; 3723 if (fault) goto MMU_EXCEPTION;
3724 3724
3725 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 3725 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
3726 if (fault) goto MMU_EXCEPTION; 3726 if (fault) goto MMU_EXCEPTION;
3727 3727
3728 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32); 3728 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32);
3729 if (fault) goto MMU_EXCEPTION; 3729 if (fault) goto MMU_EXCEPTION;
3730 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]); 3730 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]);
3731 } 3731 }
@@ -3926,7 +3926,7 @@ VFPLABEL_INST:
3926 { 3926 {
3927 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3927 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3928 if (fault) goto MMU_EXCEPTION; 3928 if (fault) goto MMU_EXCEPTION;
3929 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 3929 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
3930 if (fault) goto MMU_EXCEPTION; 3930 if (fault) goto MMU_EXCEPTION;
3931 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 3931 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
3932 addr += 4; 3932 addr += 4;
@@ -3936,12 +3936,12 @@ VFPLABEL_INST:
3936 /* Careful of endianness, little by default */ 3936 /* Careful of endianness, little by default */
3937 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3937 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3938 if (fault) goto MMU_EXCEPTION; 3938 if (fault) goto MMU_EXCEPTION;
3939 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 3939 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
3940 if (fault) goto MMU_EXCEPTION; 3940 if (fault) goto MMU_EXCEPTION;
3941 3941
3942 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 3942 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
3943 if (fault) goto MMU_EXCEPTION; 3943 if (fault) goto MMU_EXCEPTION;
3944 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 3944 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
3945 if (fault) goto MMU_EXCEPTION; 3945 if (fault) goto MMU_EXCEPTION;
3946 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 3946 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3947 addr += 8; 3947 addr += 8;
@@ -4048,7 +4048,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4048 { 4048 {
4049 if (single) 4049 if (single)
4050 { 4050 {
4051 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4051 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4052 #if 0 4052 #if 0
4053 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4053 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
4054 bb = cpu->dyncom_engine->bb; 4054 bb = cpu->dyncom_engine->bb;
@@ -4166,7 +4166,7 @@ VFPLABEL_INST: /* encoding 1 */
4166 fault = check_address_validity(cpu, addr, &phys_addr, 0); 4166 fault = check_address_validity(cpu, addr, &phys_addr, 0);
4167 if (fault) goto MMU_EXCEPTION; 4167 if (fault) goto MMU_EXCEPTION;
4168 4168
4169 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4169 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4170 if (fault) goto MMU_EXCEPTION; 4170 if (fault) goto MMU_EXCEPTION;
4171 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 4171 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
4172 addr += 4; 4172 addr += 4;
@@ -4177,13 +4177,13 @@ VFPLABEL_INST: /* encoding 1 */
4177 fault = check_address_validity(cpu, addr, &phys_addr, 0); 4177 fault = check_address_validity(cpu, addr, &phys_addr, 0);
4178 if (fault) goto MMU_EXCEPTION; 4178 if (fault) goto MMU_EXCEPTION;
4179 4179
4180 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4180 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4181 if (fault) goto MMU_EXCEPTION; 4181 if (fault) goto MMU_EXCEPTION;
4182 4182
4183 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 4183 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
4184 if (fault) goto MMU_EXCEPTION; 4184 if (fault) goto MMU_EXCEPTION;
4185 4185
4186 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4186 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4187 if (fault) goto MMU_EXCEPTION; 4187 if (fault) goto MMU_EXCEPTION;
4188 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 4188 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
4189 addr += 8; 4189 addr += 8;
@@ -4304,7 +4304,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4304 if (single) 4304 if (single)
4305 { 4305 {
4306 4306
4307 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4307 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4308 /* if R(i) is R15? */ 4308 /* if R(i) is R15? */
4309 #if 0 4309 #if 0
4310 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4310 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
@@ -4321,7 +4321,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4321 else 4321 else
4322 { 4322 {
4323 4323
4324 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4324 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4325 #if 0 4325 #if 0
4326 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4326 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
4327 bb = cpu->dyncom_engine->bb; 4327 bb = cpu->dyncom_engine->bb;
@@ -4332,7 +4332,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4332 bb = cpu->dyncom_engine->bb; 4332 bb = cpu->dyncom_engine->bb;
4333 //if (fault) goto MMU_EXCEPTION; 4333 //if (fault) goto MMU_EXCEPTION;
4334 4334
4335 //fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4335 //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4336 #if 0 4336 #if 0
4337 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); 4337 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
4338 bb = cpu->dyncom_engine->bb; 4338 bb = cpu->dyncom_engine->bb;
@@ -4431,7 +4431,7 @@ VFPLABEL_INST:
4431 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4431 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4432 if (fault) goto MMU_EXCEPTION; 4432 if (fault) goto MMU_EXCEPTION;
4433 4433
4434 fault = interpreter_read_memory(core, addr, phys_addr, value1, 32); 4434 fault = interpreter_read_memory(addr, phys_addr, value1, 32);
4435 if (fault) goto MMU_EXCEPTION; 4435 if (fault) goto MMU_EXCEPTION;
4436 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr); 4436 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr);
4437 cpu->ExtReg[inst_cream->d+i] = value1; 4437 cpu->ExtReg[inst_cream->d+i] = value1;
@@ -4443,13 +4443,13 @@ VFPLABEL_INST:
4443 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4443 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4444 if (fault) goto MMU_EXCEPTION; 4444 if (fault) goto MMU_EXCEPTION;
4445 4445
4446 fault = interpreter_read_memory(core, addr, phys_addr, value1, 32); 4446 fault = interpreter_read_memory(addr, phys_addr, value1, 32);
4447 if (fault) goto MMU_EXCEPTION; 4447 if (fault) goto MMU_EXCEPTION;
4448 4448
4449 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4449 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4450 if (fault) goto MMU_EXCEPTION; 4450 if (fault) goto MMU_EXCEPTION;
4451 4451
4452 fault = interpreter_read_memory(core, addr + 4, phys_addr, value2, 32); 4452 fault = interpreter_read_memory(addr + 4, phys_addr, value2, 32);
4453 if (fault) goto MMU_EXCEPTION; 4453 if (fault) goto MMU_EXCEPTION;
4454 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr); 4454 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr);
4455 cpu->ExtReg[(inst_cream->d+i)*2] = value1; 4455 cpu->ExtReg[(inst_cream->d+i)*2] = value1;
@@ -4682,7 +4682,7 @@ VFPLABEL_INST:
4682 { 4682 {
4683 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4683 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4684 if (fault) goto MMU_EXCEPTION; 4684 if (fault) goto MMU_EXCEPTION;
4685 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); 4685 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
4686 if (fault) goto MMU_EXCEPTION; 4686 if (fault) goto MMU_EXCEPTION;
4687 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr); 4687 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr);
4688 } 4688 }
@@ -4691,12 +4691,12 @@ VFPLABEL_INST:
4691 unsigned int word1, word2; 4691 unsigned int word1, word2;
4692 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4692 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4693 if (fault) goto MMU_EXCEPTION; 4693 if (fault) goto MMU_EXCEPTION;
4694 fault = interpreter_read_memory(core, addr, phys_addr, word1, 32); 4694 fault = interpreter_read_memory(addr, phys_addr, word1, 32);
4695 if (fault) goto MMU_EXCEPTION; 4695 if (fault) goto MMU_EXCEPTION;
4696 4696
4697 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4697 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4698 if (fault) goto MMU_EXCEPTION; 4698 if (fault) goto MMU_EXCEPTION;
4699 fault = interpreter_read_memory(core, addr + 4, phys_addr, word2, 32); 4699 fault = interpreter_read_memory(addr + 4, phys_addr, word2, 32);
4700 if (fault) goto MMU_EXCEPTION; 4700 if (fault) goto MMU_EXCEPTION;
4701 /* Check endianness */ 4701 /* Check endianness */
4702 cpu->ExtReg[inst_cream->d*2] = word1; 4702 cpu->ExtReg[inst_cream->d*2] = word1;
@@ -4923,7 +4923,7 @@ VFPLABEL_INST:
4923 { 4923 {
4924 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4924 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4925 if (fault) goto MMU_EXCEPTION; 4925 if (fault) goto MMU_EXCEPTION;
4926 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4926 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4927 if (fault) goto MMU_EXCEPTION; 4927 if (fault) goto MMU_EXCEPTION;
4928 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr); 4928 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr);
4929 addr += 4; 4929 addr += 4;
@@ -4933,12 +4933,12 @@ VFPLABEL_INST:
4933 /* Careful of endianness, little by default */ 4933 /* Careful of endianness, little by default */
4934 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4934 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4935 if (fault) goto MMU_EXCEPTION; 4935 if (fault) goto MMU_EXCEPTION;
4936 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4936 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4937 if (fault) goto MMU_EXCEPTION; 4937 if (fault) goto MMU_EXCEPTION;
4938 4938
4939 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4939 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4940 if (fault) goto MMU_EXCEPTION; 4940 if (fault) goto MMU_EXCEPTION;
4941 fault = interpreter_read_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4941 fault = interpreter_read_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4942 if (fault) goto MMU_EXCEPTION; 4942 if (fault) goto MMU_EXCEPTION;
4943 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr); 4943 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr);
4944 addr += 8; 4944 addr += 8;
@@ -5058,7 +5058,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5058 if (single) 5058 if (single)
5059 { 5059 {
5060 5060
5061 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 5061 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
5062 /* if R(i) is R15? */ 5062 /* if R(i) is R15? */
5063 #if 0 5063 #if 0
5064 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 5064 phys_addr = get_phys_addr(cpu, bb, Addr, 1);
@@ -5095,7 +5095,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5095 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 5095 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
5096 LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); 5096 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
5097 5097
5098 //fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 5098 //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
5099 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 5099 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
5100 //addr += 8; 5100 //addr += 8;
5101 Addr = ADD(Addr, CONST(8)); 5101 Addr = ADD(Addr, CONST(8));