summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Lioncash2015-01-31 20:34:26 -0500
committerGravatar Lioncash2015-01-31 20:43:03 -0500
commitf44781fd7b0c5f99573e917ccdd92716a99a9b0d (patch)
treead31575f5653316488371cd654d961ce803e2c01 /src/core
parentMerge pull request #512 from lioncash/assignment (diff)
downloadyuzu-f44781fd7b0c5f99573e917ccdd92716a99a9b0d.tar.gz
yuzu-f44781fd7b0c5f99573e917ccdd92716a99a9b0d.tar.xz
yuzu-f44781fd7b0c5f99573e917ccdd92716a99a9b0d.zip
arm: Adios armemu
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt5
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp4
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp114
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h96
-rw-r--r--src/core/arm/interpreter/armcopro.cpp254
-rw-r--r--src/core/arm/interpreter/armemu.cpp5648
-rw-r--r--src/core/arm/interpreter/arminit.cpp136
-rw-r--r--src/core/arm/interpreter/armsupp.cpp881
-rw-r--r--src/core/arm/interpreter/armvirt.cpp165
-rw-r--r--src/core/arm/interpreter/thumbemu.cpp513
-rw-r--r--src/core/arm/skyeye_common/armdefs.h161
-rw-r--r--src/core/arm/skyeye_common/armemu.h538
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp230
-rw-r--r--src/core/core.cpp14
-rw-r--r--src/core/core.h5
-rw-r--r--src/core/settings.h1
16 files changed, 166 insertions, 8599 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2168d9959..ac173c486 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -6,13 +6,9 @@ set(SRCS
6 arm/dyncom/arm_dyncom_interpreter.cpp 6 arm/dyncom/arm_dyncom_interpreter.cpp
7 arm/dyncom/arm_dyncom_run.cpp 7 arm/dyncom/arm_dyncom_run.cpp
8 arm/dyncom/arm_dyncom_thumb.cpp 8 arm/dyncom/arm_dyncom_thumb.cpp
9 arm/interpreter/arm_interpreter.cpp
10 arm/interpreter/armcopro.cpp 9 arm/interpreter/armcopro.cpp
11 arm/interpreter/armemu.cpp
12 arm/interpreter/arminit.cpp 10 arm/interpreter/arminit.cpp
13 arm/interpreter/armsupp.cpp 11 arm/interpreter/armsupp.cpp
14 arm/interpreter/armvirt.cpp
15 arm/interpreter/thumbemu.cpp
16 arm/skyeye_common/vfp/vfp.cpp 12 arm/skyeye_common/vfp/vfp.cpp
17 arm/skyeye_common/vfp/vfpdouble.cpp 13 arm/skyeye_common/vfp/vfpdouble.cpp
18 arm/skyeye_common/vfp/vfpinstr.cpp 14 arm/skyeye_common/vfp/vfpinstr.cpp
@@ -108,7 +104,6 @@ set(HEADERS
108 arm/dyncom/arm_dyncom_interpreter.h 104 arm/dyncom/arm_dyncom_interpreter.h
109 arm/dyncom/arm_dyncom_run.h 105 arm/dyncom/arm_dyncom_run.h
110 arm/dyncom/arm_dyncom_thumb.h 106 arm/dyncom/arm_dyncom_thumb.h
111 arm/interpreter/arm_interpreter.h
112 arm/skyeye_common/arm_regformat.h 107 arm/skyeye_common/arm_regformat.h
113 arm/skyeye_common/armdefs.h 108 arm/skyeye_common/armdefs.h
114 arm/skyeye_common/armemu.h 109 arm/skyeye_common/armemu.h
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 4e569fd9a..96d71cd50 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -34,10 +34,6 @@ enum {
34 THUMB = (1 << 7) 34 THUMB = (1 << 7)
35}; 35};
36 36
37#undef BITS
38#undef BIT
39#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
40#define BIT(s, n) ((s >> (n)) & 1)
41#define RM BITS(sht_oper, 0, 3) 37#define RM BITS(sht_oper, 0, 3)
42#define RS BITS(sht_oper, 8, 11) 38#define RS BITS(sht_oper, 8, 11)
43 39
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
deleted file mode 100644
index c76d371a2..000000000
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/arm/interpreter/arm_interpreter.h"
6
7#include "core/core.h"
8
9const static cpu_config_t arm11_cpu_info = {
10 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
11};
12
13ARM_Interpreter::ARM_Interpreter() {
14 state = new ARMul_State;
15
16 ARMul_EmulateInit();
17 memset(state, 0, sizeof(ARMul_State));
18
19 ARMul_NewState(state);
20
21 state->abort_model = 0;
22 state->cpu = (cpu_config_t*)&arm11_cpu_info;
23 state->bigendSig = LOW;
24
25 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
26 state->lateabtSig = LOW;
27
28 // Reset the core to initial state
29 ARMul_CoProInit(state);
30 ARMul_Reset(state);
31 state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
32 state->Emulate = 3;
33
34 state->pc = state->Reg[15] = 0x00000000;
35 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
36 state->servaddr = 0xFFFF0000;
37}
38
39ARM_Interpreter::~ARM_Interpreter() {
40 delete state;
41}
42
43void ARM_Interpreter::SetPC(u32 pc) {
44 state->pc = state->Reg[15] = pc;
45}
46
47u32 ARM_Interpreter::GetPC() const {
48 return state->pc;
49}
50
51u32 ARM_Interpreter::GetReg(int index) const {
52 return state->Reg[index];
53}
54
55void ARM_Interpreter::SetReg(int index, u32 value) {
56 state->Reg[index] = value;
57}
58
59u32 ARM_Interpreter::GetCPSR() const {
60 return state->Cpsr;
61}
62
63void ARM_Interpreter::SetCPSR(u32 cpsr) {
64 state->Cpsr = cpsr;
65}
66
67u64 ARM_Interpreter::GetTicks() const {
68 return state->NumInstrs;
69}
70
71void ARM_Interpreter::AddTicks(u64 ticks) {
72 state->NumInstrs += ticks;
73}
74
75void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
76 state->NumInstrsToExecute = num_instructions - 1;
77 ARMul_Emulate32(state);
78}
79
80void ARM_Interpreter::SaveContext(Core::ThreadContext& ctx) {
81 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
82 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
83
84 ctx.sp = state->Reg[13];
85 ctx.lr = state->Reg[14];
86 ctx.pc = state->pc;
87 ctx.cpsr = state->Cpsr;
88
89 ctx.fpscr = state->VFP[1];
90 ctx.fpexc = state->VFP[2];
91
92 ctx.reg_15 = state->Reg[15];
93 ctx.mode = state->NextInstr;
94}
95
96void ARM_Interpreter::LoadContext(const Core::ThreadContext& ctx) {
97 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
98 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
99
100 state->Reg[13] = ctx.sp;
101 state->Reg[14] = ctx.lr;
102 state->pc = ctx.pc;
103 state->Cpsr = ctx.cpsr;
104
105 state->VFP[1] = ctx.fpscr;
106 state->VFP[2] = ctx.fpexc;
107
108 state->Reg[15] = ctx.reg_15;
109 state->NextInstr = ctx.mode;
110}
111
112void ARM_Interpreter::PrepareReschedule() {
113 state->NumInstrsToExecute = 0;
114}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
deleted file mode 100644
index e5ecc69c2..000000000
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ /dev/null
@@ -1,96 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common.h"
8
9#include "core/arm/arm_interface.h"
10#include "core/arm/skyeye_common/armdefs.h"
11#include "core/arm/skyeye_common/armemu.h"
12
13class ARM_Interpreter final : virtual public ARM_Interface {
14public:
15
16 ARM_Interpreter();
17 ~ARM_Interpreter();
18
19 /**
20 * Set the Program Counter to an address
21 * @param pc Address to set PC to
22 */
23 void SetPC(u32 pc) override;
24
25 /*
26 * Get the current Program Counter
27 * @return Returns current PC
28 */
29 u32 GetPC() const override;
30
31 /**
32 * Get an ARM register
33 * @param index Register index (0-15)
34 * @return Returns the value in the register
35 */
36 u32 GetReg(int index) const override;
37
38 /**
39 * Set an ARM register
40 * @param index Register index (0-15)
41 * @param value Value to set register to
42 */
43 void SetReg(int index, u32 value) override;
44
45 /**
46 * Get the current CPSR register
47 * @return Returns the value of the CPSR register
48 */
49 u32 GetCPSR() const override;
50
51 /**
52 * Set the current CPSR register
53 * @param cpsr Value to set CPSR to
54 */
55 void SetCPSR(u32 cpsr) override;
56
57 /**
58 * Returns the number of clock ticks since the last reset
59 * @return Returns number of clock ticks
60 */
61 u64 GetTicks() const override;
62
63 /**
64 * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
65 * @param ticks Number of ticks to advance the CPU core
66 */
67 void AddTicks(u64 ticks) override;
68
69 /**
70 * Saves the current CPU context
71 * @param ctx Thread context to save
72 */
73 void SaveContext(Core::ThreadContext& ctx) override;
74
75 /**
76 * Loads a CPU context
77 * @param ctx Thread context to load
78 */
79 void LoadContext(const Core::ThreadContext& ctx) override;
80
81 /// Prepare core for thread reschedule (if needed to correctly handle state)
82 void PrepareReschedule() override;
83
84protected:
85
86 /**
87 * Executes the given number of instructions
88 * @param num_instructions Number of instructions to executes
89 */
90 void ExecuteInstructions(int num_instructions) override;
91
92private:
93
94 ARMul_State* state;
95
96};
diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp
index b4ddc3d96..bb9ca98fe 100644
--- a/src/core/arm/interpreter/armcopro.cpp
+++ b/src/core/arm/interpreter/armcopro.cpp
@@ -19,213 +19,45 @@
19#include "core/arm/skyeye_common/armemu.h" 19#include "core/arm/skyeye_common/armemu.h"
20#include "core/arm/skyeye_common/vfp/vfp.h" 20#include "core/arm/skyeye_common/vfp/vfp.h"
21 21
22//chy 2005-07-08 22// Dummy Co-processors.
23//#include "ansidecl.h"
24//chy -------
25//#include "iwmmxt.h"
26 23
27/* Dummy Co-processors. */ 24static unsigned int NoCoPro3R(ARMul_State* state, unsigned int a, ARMword b)
28
29static unsigned
30NoCoPro3R(ARMul_State * state,
31unsigned a, ARMword b)
32{ 25{
33 return ARMul_CANT; 26 return ARMul_CANT;
34} 27}
35 28
36static unsigned 29static unsigned int NoCoPro4R(ARMul_State* state, unsigned int a, ARMword b, ARMword c)
37NoCoPro4R(ARMul_State * state,
38unsigned a,
39ARMword b, ARMword c)
40{ 30{
41 return ARMul_CANT; 31 return ARMul_CANT;
42} 32}
43 33
44static unsigned 34static unsigned int NoCoPro4W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c)
45NoCoPro4W(ARMul_State * state,
46unsigned a,
47ARMword b, ARMword * c)
48{ 35{
49 return ARMul_CANT; 36 return ARMul_CANT;
50} 37}
51 38
52static unsigned 39static unsigned int NoCoPro5R(ARMul_State* state, unsigned int a, ARMword b, ARMword c, ARMword d)
53NoCoPro5R(ARMul_State * state,
54unsigned a,
55ARMword b,
56ARMword c, ARMword d)
57{ 40{
58 return ARMul_CANT; 41 return ARMul_CANT;
59} 42}
60 43
61static unsigned 44static unsigned int NoCoPro5W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c, ARMword* d)
62NoCoPro5W(ARMul_State * state,
63unsigned a,
64ARMword b,
65ARMword * c, ARMword * d)
66{ 45{
67 return ARMul_CANT; 46 return ARMul_CANT;
68} 47}
69 48
70/* The XScale Co-processors. */ 49// Install co-processor instruction handlers in this routine.
71 50unsigned int ARMul_CoProInit(ARMul_State* state)
72/* Coprocessor 15: System Control. */
73static void write_cp14_reg(unsigned, ARMword);
74static ARMword read_cp14_reg(unsigned);
75
76/* Check an access to a register. */
77
78static unsigned
79check_cp15_access(ARMul_State * state,
80unsigned reg,
81unsigned CRm, unsigned opcode_1, unsigned opcode_2)
82{
83 /* Do not allow access to these register in USER mode. */
84 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
85 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
86 return ARMul_CANT;
87
88 /* Opcode_1should be zero. */
89 if (opcode_1 != 0)
90 return ARMul_CANT;
91
92 /* Different register have different access requirements. */
93 switch (reg) {
94 case 0:
95 case 1:
96 /* CRm must be 0. Opcode_2 can be anything. */
97 if (CRm != 0)
98 return ARMul_CANT;
99 break;
100 case 2:
101 case 3:
102 /* CRm must be 0. Opcode_2 must be zero. */
103 if ((CRm != 0) || (opcode_2 != 0))
104 return ARMul_CANT;
105 break;
106 case 4:
107 /* Access not allowed. */
108 return ARMul_CANT;
109 case 5:
110 case 6:
111 /* Opcode_2 must be zero. CRm must be 0. */
112 if ((CRm != 0) || (opcode_2 != 0))
113 return ARMul_CANT;
114 break;
115 case 7:
116 /* Permissable combinations:
117 Opcode_2 CRm
118 0 5
119 0 6
120 0 7
121 1 5
122 1 6
123 1 10
124 4 10
125 5 2
126 6 5 */
127 switch (opcode_2) {
128 default:
129 return ARMul_CANT;
130 case 6:
131 if (CRm != 5)
132 return ARMul_CANT;
133 break;
134 case 5:
135 if (CRm != 2)
136 return ARMul_CANT;
137 break;
138 case 4:
139 if (CRm != 10)
140 return ARMul_CANT;
141 break;
142 case 1:
143 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
144 return ARMul_CANT;
145 break;
146 case 0:
147 if ((CRm < 5) || (CRm > 7))
148 return ARMul_CANT;
149 break;
150 }
151 break;
152
153 case 8:
154 /* Permissable combinations:
155 Opcode_2 CRm
156 0 5
157 0 6
158 0 7
159 1 5
160 1 6 */
161 if (opcode_2 > 1)
162 return ARMul_CANT;
163 if ((CRm < 5) || (CRm > 7))
164 return ARMul_CANT;
165 if (opcode_2 == 1 && CRm == 7)
166 return ARMul_CANT;
167 break;
168 case 9:
169 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
170 if (((CRm != 0) && (CRm != 1))
171 || ((opcode_2 != 1) && (opcode_2 != 2)))
172 return ARMul_CANT;
173 break;
174 case 10:
175 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
176 if (((CRm != 0) && (CRm != 1))
177 || ((opcode_2 != 4) && (opcode_2 != 8)))
178 return ARMul_CANT;
179 break;
180 case 11:
181 /* Access not allowed. */
182 return ARMul_CANT;
183 case 12:
184 /* Access not allowed. */
185 return ARMul_CANT;
186 case 13:
187 /* Opcode_2 must be zero. CRm must be 0. */
188 if ((CRm != 0) || (opcode_2 != 0))
189 return ARMul_CANT;
190 break;
191 case 14:
192 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
193 if (opcode_2 != 0)
194 return ARMul_CANT;
195
196 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
197 && (CRm != 9))
198 return ARMul_CANT;
199 break;
200 case 15:
201 /* Opcode_2 must be zero. CRm must be 1. */
202 if ((CRm != 1) || (opcode_2 != 0))
203 return ARMul_CANT;
204 break;
205 default:
206 /* Should never happen. */
207 return ARMul_CANT;
208 }
209
210 return ARMul_DONE;
211}
212
213/* Install co-processor instruction handlers in this routine. */
214
215unsigned
216ARMul_CoProInit(ARMul_State * state)
217{ 51{
218 unsigned int i; 52 // Initialise tham all first.
219 53 for (unsigned int i = 0; i < 16; i++)
220 /* Initialise tham all first. */
221 for (i = 0; i < 16; i++)
222 ARMul_CoProDetach(state, i); 54 ARMul_CoProDetach(state, i);
223 55
224 /* Install CoPro Instruction handlers here. 56 // Install CoPro Instruction handlers here.
225 The format is: 57 // The format is:
226 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine 58 // ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
227 LDC routine, STC routine, MRC routine, MCR routine, 59 // LDC routine, STC routine, MRC routine, MCR routine,
228 CDP routine, Read Reg routine, Write Reg routine). */ 60 // CDP routine, Read Reg routine, Write Reg routine).
229 if (state->is_v6) { 61 if (state->is_v6) {
230 ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC, 62 ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
231 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); 63 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
@@ -235,57 +67,44 @@ ARMul_CoProInit(ARMul_State * state)
235 /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, 67 /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
236 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/ 68 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/
237 } 69 }
238 //chy 2003-09-03 do it in future!!!!????
239#if 0
240 if (state->is_iWMMXt) {
241 ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
242 NULL, NULL, IwmmxtCDP, NULL, NULL);
243 70
244 ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL, 71 // No handlers below here.
245 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL,
246 NULL);
247 }
248#endif
249 /* No handlers below here. */
250 72
251 /* Call all the initialisation routines. */ 73 // Call all the initialisation routines.
252 for (i = 0; i < 16; i++) 74 for (unsigned int i = 0; i < 16; i++)
253 if (state->CPInit[i]) 75 if (state->CPInit[i])
254 (state->CPInit[i]) (state); 76 (state->CPInit[i]) (state);
255 77
256 return TRUE; 78 return TRUE;
257} 79}
258 80
259/* Install co-processor finalisation routines in this routine. */ 81// Install co-processor finalisation routines in this routine.
260 82void ARMul_CoProExit(ARMul_State * state)
261void
262ARMul_CoProExit(ARMul_State * state)
263{ 83{
264 register unsigned i; 84 for (unsigned int i = 0; i < 16; i++)
265
266 for (i = 0; i < 16; i++)
267 if (state->CPExit[i]) 85 if (state->CPExit[i])
268 (state->CPExit[i]) (state); 86 (state->CPExit[i]) (state);
269 87
270 for (i = 0; i < 16; i++) /* Detach all handlers. */ 88 // Detach all handlers.
89 for (unsigned int i = 0; i < 16; i++)
271 ARMul_CoProDetach(state, i); 90 ARMul_CoProDetach(state, i);
272} 91}
273 92
274/* Routines to hook Co-processors into ARMulator. */ 93// Routines to hook Co-processors into ARMulator.
275 94
276void 95void
277ARMul_CoProAttach(ARMul_State * state, 96ARMul_CoProAttach(ARMul_State* state,
278unsigned number, 97unsigned number,
279ARMul_CPInits * init, 98ARMul_CPInits* init,
280ARMul_CPExits * exit, 99ARMul_CPExits* exit,
281ARMul_LDCs * ldc, 100ARMul_LDCs* ldc,
282ARMul_STCs * stc, 101ARMul_STCs* stc,
283ARMul_MRCs * mrc, 102ARMul_MRCs* mrc,
284ARMul_MCRs * mcr, 103ARMul_MCRs* mcr,
285ARMul_MRRCs * mrrc, 104ARMul_MRRCs* mrrc,
286ARMul_MCRRs * mcrr, 105ARMul_MCRRs* mcrr,
287ARMul_CDPs * cdp, 106ARMul_CDPs* cdp,
288ARMul_CPReads * read, ARMul_CPWrites * write) 107ARMul_CPReads* read, ARMul_CPWrites* write)
289{ 108{
290 if (init != NULL) 109 if (init != NULL)
291 state->CPInit[number] = init; 110 state->CPInit[number] = init;
@@ -311,8 +130,7 @@ ARMul_CPReads * read, ARMul_CPWrites * write)
311 state->CPWrite[number] = write; 130 state->CPWrite[number] = write;
312} 131}
313 132
314void 133void ARMul_CoProDetach(ARMul_State* state, unsigned number)
315ARMul_CoProDetach(ARMul_State * state, unsigned number)
316{ 134{
317 ARMul_CoProAttach(state, number, NULL, NULL, 135 ARMul_CoProAttach(state, number, NULL, NULL,
318 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, 136 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
deleted file mode 100644
index 7114313d6..000000000
--- a/src/core/arm/interpreter/armemu.cpp
+++ /dev/null
@@ -1,5648 +0,0 @@
1/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3 Modifications to add arch. v4 support by <jsmith@cygnus.com>.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19#include "core/arm/skyeye_common/arm_regformat.h"
20#include "core/arm/skyeye_common/armdefs.h"
21#include "core/arm/skyeye_common/armemu.h"
22#include "core/hle/hle.h"
23
24static ARMword GetDPRegRHS (ARMul_State *, ARMword);
25static ARMword GetDPSRegRHS (ARMul_State *, ARMword);
26static void WriteR15 (ARMul_State *, ARMword);
27static void WriteSR15 (ARMul_State *, ARMword);
28static void WriteR15Branch (ARMul_State *, ARMword);
29static ARMword GetLSRegRHS (ARMul_State *, ARMword);
30static ARMword GetLS7RHS (ARMul_State *, ARMword);
31static unsigned LoadWord (ARMul_State *, ARMword, ARMword);
32static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int);
33static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int);
34static unsigned StoreWord (ARMul_State *, ARMword, ARMword);
35static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword);
36static unsigned StoreByte (ARMul_State *, ARMword, ARMword);
37static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword);
38static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword);
39static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword);
40static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword);
41static unsigned Multiply64 (ARMul_State *, ARMword, int, int);
42static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int);
43static void Handle_Load_Double (ARMul_State *, ARMword);
44static void Handle_Store_Double (ARMul_State *, ARMword);
45
46static int handle_v6_insn (ARMul_State * state, ARMword instr);
47
48#define LUNSIGNED (0) /* unsigned operation */
49#define LSIGNED (1) /* signed operation */
50#define LDEFAULT (0) /* default : do nothing */
51#define LSCC (1) /* set condition codes on result */
52
53/* Short-hand macros for LDR/STR. */
54
55/* Store post decrement writeback. */
56#define SHDOWNWB() \
57 lhs = LHS ; \
58 if (StoreHalfWord (state, instr, lhs)) \
59 LSBase = lhs - GetLS7RHS (state, instr);
60
61/* Store post increment writeback. */
62#define SHUPWB() \
63 lhs = LHS ; \
64 if (StoreHalfWord (state, instr, lhs)) \
65 LSBase = lhs + GetLS7RHS (state, instr);
66
67/* Store pre decrement. */
68#define SHPREDOWN() \
69 (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
70
71/* Store pre decrement writeback. */
72#define SHPREDOWNWB() \
73 temp = LHS - GetLS7RHS (state, instr); \
74 if (StoreHalfWord (state, instr, temp)) \
75 LSBase = temp;
76
77/* Store pre increment. */
78#define SHPREUP() \
79 (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
80
81/* Store pre increment writeback. */
82#define SHPREUPWB() \
83 temp = LHS + GetLS7RHS (state, instr); \
84 if (StoreHalfWord (state, instr, temp)) \
85 LSBase = temp;
86
87/* Load post decrement writeback. */
88#define LHPOSTDOWN() \
89{ \
90 int done = 1; \
91 lhs = LHS; \
92 temp = lhs - GetLS7RHS (state, instr); \
93 \
94 switch (BITS (5, 6)) \
95 { \
96 case 1: /* H */ \
97 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
98 LSBase = temp; \
99 break; \
100 case 2: /* SB */ \
101 if (LoadByte (state, instr, lhs, LSIGNED)) \
102 LSBase = temp; \
103 break; \
104 case 3: /* SH */ \
105 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
106 LSBase = temp; \
107 break; \
108 case 0: /* SWP handled elsewhere. */ \
109 default: \
110 done = 0; \
111 break; \
112 } \
113 if (done) \
114 break; \
115}
116
117/* Load post increment writeback. */
118#define LHPOSTUP() \
119{ \
120 int done = 1; \
121 lhs = LHS; \
122 temp = lhs + GetLS7RHS (state, instr); \
123 \
124 switch (BITS (5, 6)) \
125 { \
126 case 1: /* H */ \
127 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
128 LSBase = temp; \
129 break; \
130 case 2: /* SB */ \
131 if (LoadByte (state, instr, lhs, LSIGNED)) \
132 LSBase = temp; \
133 break; \
134 case 3: /* SH */ \
135 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
136 LSBase = temp; \
137 break; \
138 case 0: /* SWP handled elsewhere. */ \
139 default: \
140 done = 0; \
141 break; \
142 } \
143 if (done) \
144 break; \
145}
146
147/* Load pre decrement. */
148#define LHPREDOWN() \
149{ \
150 int done = 1; \
151 \
152 temp = LHS - GetLS7RHS (state, instr); \
153 switch (BITS (5, 6)) \
154 { \
155 case 1: /* H */ \
156 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
157 break; \
158 case 2: /* SB */ \
159 (void) LoadByte (state, instr, temp, LSIGNED); \
160 break; \
161 case 3: /* SH */ \
162 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
163 break; \
164 case 0: \
165 /* SWP handled elsewhere. */ \
166 default: \
167 done = 0; \
168 break; \
169 } \
170 if (done) \
171 break; \
172}
173
174/* Load pre decrement writeback. */
175#define LHPREDOWNWB() \
176{ \
177 int done = 1; \
178 \
179 temp = LHS - GetLS7RHS (state, instr); \
180 switch (BITS (5, 6)) \
181 { \
182 case 1: /* H */ \
183 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
184 LSBase = temp; \
185 break; \
186 case 2: /* SB */ \
187 if (LoadByte (state, instr, temp, LSIGNED)) \
188 LSBase = temp; \
189 break; \
190 case 3: /* SH */ \
191 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
192 LSBase = temp; \
193 break; \
194 case 0: \
195 /* SWP handled elsewhere. */ \
196 default: \
197 done = 0; \
198 break; \
199 } \
200 if (done) \
201 break; \
202}
203
204/* Load pre increment. */
205#define LHPREUP() \
206{ \
207 int done = 1; \
208 \
209 temp = LHS + GetLS7RHS (state, instr); \
210 switch (BITS (5, 6)) \
211 { \
212 case 1: /* H */ \
213 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
214 break; \
215 case 2: /* SB */ \
216 (void) LoadByte (state, instr, temp, LSIGNED); \
217 break; \
218 case 3: /* SH */ \
219 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
220 break; \
221 case 0: \
222 /* SWP handled elsewhere. */ \
223 default: \
224 done = 0; \
225 break; \
226 } \
227 if (done) \
228 break; \
229}
230
231/* Load pre increment writeback. */
232#define LHPREUPWB() \
233{ \
234 int done = 1; \
235 \
236 temp = LHS + GetLS7RHS (state, instr); \
237 switch (BITS (5, 6)) \
238 { \
239 case 1: /* H */ \
240 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
241 LSBase = temp; \
242 break; \
243 case 2: /* SB */ \
244 if (LoadByte (state, instr, temp, LSIGNED)) \
245 LSBase = temp; \
246 break; \
247 case 3: /* SH */ \
248 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
249 LSBase = temp; \
250 break; \
251 case 0: \
252 /* SWP handled elsewhere. */ \
253 default: \
254 done = 0; \
255 break; \
256 } \
257 if (done) \
258 break; \
259}
260
261/* EMULATION of ARM6. */
262
263int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr);
264#ifdef MODE32
265//chy 2006-04-12, for ICE debug
266int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr)
267{
268 return 0;
269}
270
271ARMword ARMul_Debug(ARMul_State * state, ARMword pc, ARMword instr)
272{
273 return 0;
274}
275
276ARMword ARMul_Emulate32(ARMul_State* state)
277#else
278ARMword ARMul_Emulate26(ARMul_State* state)
279#endif
280{
281 /* The PC pipeline value depends on whether ARM
282 or Thumb instructions are being
283 d. */
284 ARMword isize;
285 ARMword instr; /* The current instruction. */
286 ARMword dest = 0; /* Almost the DestBus. */
287 ARMword temp; /* Ubiquitous third hand. */
288 ARMword pc = 0; /* The address of the current instruction. */
289 ARMword lhs; /* Almost the ABus and BBus. */
290 ARMword rhs;
291 ARMword decoded = 0; /* Instruction pipeline. */
292 ARMword loaded = 0;
293 ARMword decoded_addr=0;
294 ARMword loaded_addr=0;
295 ARMword have_bp=0;
296
297 /* Execute the next instruction. */
298 if (state->NextInstr < PRIMEPIPE) {
299 decoded = state->decoded;
300 loaded = state->loaded;
301 pc = state->pc;
302 //chy 2006-04-12, for ICE debug
303 decoded_addr=state->decoded_addr;
304 loaded_addr=state->loaded_addr;
305 }
306
307 do {
308 //print_func_name(state->pc);
309 /* Just keep going. */
310 isize = INSN_SIZE;
311
312 switch (state->NextInstr) {
313 case SEQ:
314 /* Advance the pipeline, and an S cycle. */
315 state->Reg[15] += isize;
316 pc += isize;
317 instr = decoded;
318 //chy 2006-04-12, for ICE debug
319 have_bp = ARMul_ICE_debug(state,instr,decoded_addr);
320 decoded = loaded;
321 decoded_addr=loaded_addr;
322 //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
323 // isize);
324 loaded_addr=pc + (isize * 2);
325 if (have_bp) goto TEST_EMULATE;
326 break;
327
328 case NONSEQ:
329 /* Advance the pipeline, and an N cycle. */
330 state->Reg[15] += isize;
331 pc += isize;
332 instr = decoded;
333 //chy 2006-04-12, for ICE debug
334 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
335 decoded = loaded;
336 decoded_addr=loaded_addr;
337 //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
338 // isize);
339 loaded_addr=pc + (isize * 2);
340 NORMALCYCLE;
341 if (have_bp) goto TEST_EMULATE;
342 break;
343
344 case PCINCEDSEQ:
345 /* Program counter advanced, and an S cycle. */
346 pc += isize;
347 instr = decoded;
348 //chy 2006-04-12, for ICE debug
349 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
350 decoded = loaded;
351 decoded_addr=loaded_addr;
352 //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
353 // isize);
354 loaded_addr=pc + (isize * 2);
355 NORMALCYCLE;
356 if (have_bp) goto TEST_EMULATE;
357 break;
358
359 case PCINCEDNONSEQ:
360 /* Program counter advanced, and an N cycle. */
361 pc += isize;
362 instr = decoded;
363 //chy 2006-04-12, for ICE debug
364 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
365 decoded = loaded;
366 decoded_addr=loaded_addr;
367 //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
368 // isize);
369 loaded_addr=pc + (isize * 2);
370 NORMALCYCLE;
371 if (have_bp) goto TEST_EMULATE;
372 break;
373
374 case RESUME:
375 /* The program counter has been changed. */
376 pc = state->Reg[15];
377#ifndef MODE32
378 pc = pc & R15PCBITS;
379#endif
380 state->Reg[15] = pc + (isize * 2);
381 state->Aborted = 0;
382 //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
383 state->AbortAddr = 1;
384
385 instr = ARMul_LoadInstrN (state, pc, isize);
386 //instr = ARMul_ReLoadInstr (state, pc, isize);
387 //chy 2006-04-12, for ICE debug
388 have_bp=ARMul_ICE_debug(state,instr,pc);
389 //decoded =
390 // ARMul_ReLoadInstr (state, pc + isize, isize);
391 decoded_addr=pc+isize;
392 //loaded = ARMul_ReLoadInstr (state, pc + isize * 2,
393 // isize);
394 loaded_addr=pc + isize * 2;
395 NORMALCYCLE;
396 if (have_bp) goto TEST_EMULATE;
397 break;
398
399 default:
400 /* The program counter has been changed. */
401 pc = state->Reg[15];
402#ifndef MODE32
403 pc = pc & R15PCBITS;
404#endif
405 state->Reg[15] = pc + (isize * 2);
406 state->Aborted = 0;
407 //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
408 state->AbortAddr = 1;
409
410 instr = ARMul_LoadInstrN (state, pc, isize);
411
412 //chy 2006-04-12, for ICE debug
413 have_bp=ARMul_ICE_debug(state,instr,pc);
414
415 decoded_addr=pc+isize;
416
417 loaded_addr=pc + isize * 2;
418 NORMALCYCLE;
419 if (have_bp) goto TEST_EMULATE;
420 break;
421 }
422
423 instr = ARMul_LoadInstrN (state, pc, isize);
424 state->last_instr = state->CurrInstr;
425 state->CurrInstr = instr;
426 ARMul_Debug(state, pc, instr);
427
428 /* Any exceptions ? */
429 if (state->NresetSig == LOW) {
430 ARMul_Abort (state, ARMul_ResetV);
431 break;
432 } else if (!state->NfiqSig && !FFLAG) {
433 ARMul_Abort (state, ARMul_FIQV);
434 break;
435 } else if (!state->NirqSig && !IFLAG) {
436 ARMul_Abort (state, ARMul_IRQV);
437 break;
438 }
439
440 if (state->Emulate < ONCE) {
441 state->NextInstr = RESUME;
442 break;
443 }
444
445 state->NumInstrs++;
446
447#ifdef MODET
448 /* Provide Thumb instruction decoding. If the processor is in Thumb
449 mode, then we can simply decode the Thumb instruction, and map it
450 to the corresponding ARM instruction (by directly loading the
451 instr variable, and letting the normal ARM simulator
452 execute). There are some caveats to ensure that the correct
453 pipelined PC value is used when executing Thumb code, and also for
454 dealing with the BL instruction. */
455 if (TFLAG) {
456 ARMword armOp = 0;
457 /* Check if in Thumb mode. */
458 switch (ARMul_ThumbDecode(state, pc, instr, &armOp)) {
459 case t_undefined:
460 /* This is a Thumb instruction. */
461 ARMul_UndefInstr (state, instr);
462 goto donext;
463
464 case t_branch:
465 /* Already processed. */
466 //pc = state->Reg[15] - 2;
467 //state->pc = state->Reg[15] - 2; //ichfly why do I need that
468 goto donext;
469
470 case t_decoded:
471 /* ARM instruction available. */
472 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp);
473
474 if (armOp == 0xDEADC0DE) {
475 LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc);
476 }
477
478 instr = armOp;
479
480 /* So continue instruction decoding. */
481 break;
482 default:
483 break;
484 }
485 }
486#endif
487 /* Check the condition codes. */
488 if ((temp = TOPBITS (28)) == AL) {
489 /* Vile deed in the need for speed. */
490 goto mainswitch;
491 }
492
493 /* Check the condition code. */
494 switch ((int) TOPBITS (28)) {
495 case AL:
496 temp = TRUE;
497 break;
498 case NV:
499
500 /* shenoubang add for armv7 instr dmb 2012-3-11 */
501 if (state->is_v7) {
502 if ((instr & 0x0fffff00) == 0x057ff000) {
503 switch((instr >> 4) & 0xf) {
504 case 4: /* dsb */
505 case 5: /* dmb */
506 case 6: /* isb */
507 // TODO: do no implemented thes instr
508 goto donext;
509 }
510 }
511 }
512 /* dyf add for armv6 instruct CPS 2010.9.17 */
513 if (state->is_v6) {
514 /* clrex do nothing here temporary */
515 if (instr == 0xf57ff01f) {
516 //printf("clrex \n");
517 /* shenoubang 2012-3-14 refer the dyncom_interpreter */
518 state->exclusive_tag_array[0] = 0xFFFFFFFF;
519 state->exclusive_access_state = 0;
520 goto donext;
521 }
522
523 if (BITS(20, 27) == 0x10) {
524 if (BIT(19)) {
525 if (BIT(8)) {
526 if (BIT(18))
527 state->Cpsr |= 1<<8;
528 else
529 state->Cpsr &= ~(1<<8);
530 }
531 if (BIT(7)) {
532 if (BIT(18))
533 state->Cpsr |= 1<<7;
534 else
535 state->Cpsr &= ~(1<<7);
536 ASSIGNINT (state->Cpsr & INTBITS);
537 }
538 if (BIT(6)) {
539 if (BIT(18))
540 state->Cpsr |= 1<<6;
541 else
542 state->Cpsr &= ~(1<<6);
543 ASSIGNINT (state->Cpsr & INTBITS);
544 }
545 }
546 if (BIT(17)) {
547 state->Cpsr |= BITS(0, 4);
548 printf("skyeye test state->Mode\n");
549 if (state->Mode != (state->Cpsr & MODEBITS)) {
550 state->Mode = ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS);
551 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
552 }
553 }
554 goto donext;
555 }
556 }
557 if (state->is_v5) {
558 if (BITS (25, 27) == 5) { /* BLX(1) */
559 ARMword dest;
560
561 state->Reg[14] = pc + 4;
562
563 /* Force entry into Thumb mode. */
564 dest = pc + 8 + 1;
565 if (BIT (23))
566 dest += (NEGBRANCH +
567 (BIT (24) << 1));
568 else
569 dest += POSBRANCH +
570 (BIT (24) << 1);
571
572 WriteR15Branch (state, dest);
573 goto donext;
574 } else if ((instr & 0xFC70F000) == 0xF450F000) {
575 /* The PLD instruction. Ignored. */
576 goto donext;
577 } else if (((instr & 0xfe500f00) == 0xfc100100)
578 || ((instr & 0xfe500f00) ==
579 0xfc000100)) {
580 /* wldrw and wstrw are unconditional. */
581 goto mainswitch;
582 } else {
583 /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
584 ARMul_UndefInstr (state, instr);
585 }
586 }
587 temp = FALSE;
588 break;
589 case EQ:
590 temp = ZFLAG;
591 break;
592 case NE:
593 temp = !ZFLAG;
594 break;
595 case VS:
596 temp = VFLAG;
597 break;
598 case VC:
599 temp = !VFLAG;
600 break;
601 case MI:
602 temp = NFLAG;
603 break;
604 case PL:
605 temp = !NFLAG;
606 break;
607 case CS:
608 temp = CFLAG;
609 break;
610 case CC:
611 temp = !CFLAG;
612 break;
613 case HI:
614 temp = (CFLAG && !ZFLAG);
615 break;
616 case LS:
617 temp = (!CFLAG || ZFLAG);
618 break;
619 case GE:
620 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
621 break;
622 case LT:
623 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
624 break;
625 case GT:
626 temp = ((!NFLAG && !VFLAG && !ZFLAG)
627 || (NFLAG && VFLAG && !ZFLAG));
628 break;
629 case LE:
630 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
631 || ZFLAG;
632 break;
633 } /* cc check */
634
635//chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it...
636
637 /* Actual execution of instructions begins here. */
638 /* If the condition codes don't match, stop here. */
639 if (temp) {
640mainswitch:
641
642 /* shenoubang sbfx and ubfx instr 2012-3-16 */
643 if (state->is_v6) {
644 unsigned int m, lsb, width, Rd, Rn, data;
645 Rd = Rn = lsb = width = data = m = 0;
646
647 //printf("helloworld\n");
648 if ((((int) BITS (21, 27)) == 0x3f) && (((int) BITS (4, 6)) == 0x5)) {
649 m = (unsigned)BITS(7, 11);
650 width = (unsigned)BITS(16, 20);
651 Rd = (unsigned)BITS(12, 15);
652 Rn = (unsigned)BITS(0, 3);
653 if ((Rd == 15) || (Rn == 15)) {
654 ARMul_UndefInstr (state, instr);
655 } else if ((m + width) < 32) {
656 data = state->Reg[Rn];
657 state->Reg[Rd] ^= state->Reg[Rd];
658 state->Reg[Rd] = ((ARMword)(data << (31 -(m + width))) >> ((31 - (m + width)) + (m)));
659 //SKYEYE_LOG_IN_CLR(RED, "UBFX: In %s, line = %d, Reg_src[%d] = 0x%x, Reg_d[%d] = 0x%x, m = %d, width = %d, Rd = %d, Rn = %d\n",
660 // __FUNCTION__, __LINE__, Rn, data, Rd, state->Reg[Rd], m, width + 1, Rd, Rn);
661 goto donext;
662 }
663 } // ubfx instr
664 else if ((((int) BITS (21, 27)) == 0x3d) && (((int) BITS (4, 6)) == 0x5)) {
665 int tmp = 0;
666 Rd = BITS(12, 15);
667 Rn = BITS(0, 3);
668 lsb = BITS(7, 11);
669 width = BITS(16, 20);
670 if ((Rd == 15) || (Rn == 15)) {
671 ARMul_UndefInstr (state, instr);
672 } else if ((lsb + width) < 32) {
673 state->Reg[Rd] ^= state->Reg[Rd];
674 data = state->Reg[Rn];
675 tmp = (data << (32 - (lsb + width + 1)));
676 state->Reg[Rd] = (tmp >> (32 - (lsb + width + 1)));
677 //SKYEYE_LOG_IN_CLR(RED, "sbfx: In %s, line = %d, pc = 0x%x, instr = 0x%x,Rd = 0x%x, Rn = 0x%x, lsb = %d, width = %d, Rs[%d] = 0x%x, Rd[%d] = 0x%x\n",
678 // __func__, __LINE__, pc, instr, Rd, Rn, lsb, width + 1, Rn, state->Reg[Rn], Rd, state->Reg[Rd]);
679 goto donext;
680 }
681 } // sbfx instr
682 else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
683 //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
684 unsigned msb ,tmp_rn, tmp_rd, dst;
685 tmp_rd = tmp_rn = dst = 0;
686 Rd = BITS(12, 15);
687 Rn = BITS(0, 3);
688 lsb = BITS(7, 11);
689 msb = BITS(16, 20); //-V519
690 if (Rd == 15) {
691 ARMul_UndefInstr (state, instr);
692 } else if (Rn == 15) {
693 data = state->Reg[Rd];
694 tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
695 dst = ((data >> msb) << (msb - lsb));
696 dst = (dst << lsb) | tmp_rd;
697 goto donext;
698 } // bfc instr
699 else if (((msb >= lsb) && (msb < 32))) {
700 data = state->Reg[Rn];
701 tmp_rn = ((ARMword)(data << (31 - (msb - lsb))) >> (31 - (msb - lsb)));
702 data = state->Reg[Rd];
703 tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
704 dst = ((data >> msb) << (msb - lsb)) | tmp_rn;
705 dst = (dst << lsb) | tmp_rd;
706 goto donext;
707 } // bfi instr
708 }
709 }
710
711 switch ((int) BITS (20, 27)) {
712 /* Data Processing Register RHS Instructions. */
713
714 case 0x00: /* AND reg and MUL */
715#ifdef MODET
716 if (BITS (4, 11) == 0xB) {
717 /* STRH register offset, no write-back, down, post indexed. */
718 SHDOWNWB ();
719 break;
720 }
721 if (BITS (4, 7) == 0xD) {
722 Handle_Load_Double (state, instr);
723 break;
724 }
725 if (BITS (4, 7) == 0xF) {
726 Handle_Store_Double (state, instr);
727 break;
728 }
729#endif
730 if (BITS (4, 7) == 9) {
731 /* MUL */
732 rhs = state->Reg[MULRHSReg];
733 //if (MULLHSReg == MULDESTReg) {
734 if(0) { /* For armv6, the restriction is removed */
735 UNDEF_MULDestEQOp1;
736 state->Reg[MULDESTReg] = 0;
737 } else if (MULDESTReg != 15)
738 state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
739 else
740 UNDEF_MULPCDest;
741
742 for (dest = 0, temp = 0; dest < 32;
743 dest++)
744 if (rhs & (1L << dest))
745 temp = dest;
746
747 /* Mult takes this many/2 I cycles. */
748 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
749 } else {
750 /* AND reg. */
751 rhs = DPRegRHS;
752 dest = LHS & rhs;
753 WRITEDEST (dest);
754 }
755 break;
756
757 case 0x01: /* ANDS reg and MULS */
758#ifdef MODET
759 if ((BITS (4, 11) & 0xF9) == 0x9)
760 /* LDR register offset, no write-back, down, post indexed. */
761 LHPOSTDOWN ();
762 /* Fall through to rest of decoding. */
763#endif
764 if (BITS (4, 7) == 9) {
765 /* MULS */
766 rhs = state->Reg[MULRHSReg];
767
768 //if (MULLHSReg == MULDESTReg) {
769 if(0) {
770 printf("Something in %d line\n", __LINE__);
771 UNDEF_WARNING;
772 UNDEF_MULDestEQOp1;
773 state->Reg[MULDESTReg] = 0;
774 CLEARN;
775 SETZ;
776 } else if (MULDESTReg != 15) {
777 dest = state->Reg[MULLHSReg] * rhs;
778 ARMul_NegZero (state, dest);
779 state->Reg[MULDESTReg] = dest;
780 } else
781 UNDEF_MULPCDest;
782
783 for (dest = 0, temp = 0; dest < 32;
784 dest++)
785 if (rhs & (1L << dest))
786 temp = dest;
787
788 /* Mult takes this many/2 I cycles. */
789 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
790 } else {
791 /* ANDS reg. */
792 rhs = DPSRegRHS;
793 dest = LHS & rhs;
794 WRITESDEST (dest);
795 }
796 break;
797
798 case 0x02: /* EOR reg and MLA */
799#ifdef MODET
800 if (BITS (4, 11) == 0xB) {
801 /* STRH register offset, write-back, down, post indexed. */
802 SHDOWNWB ();
803 break;
804 }
805#endif
806 if (BITS (4, 7) == 9) { /* MLA */
807 rhs = state->Reg[MULRHSReg];
808#if 0
809 if (MULLHSReg == MULDESTReg) {
810 UNDEF_MULDestEQOp1;
811 state->Reg[MULDESTReg] = state->Reg[MULACCReg];
812 } else if (MULDESTReg != 15) {
813#endif
814 if (MULDESTReg != 15) {
815 state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
816 } else
817 UNDEF_MULPCDest;
818
819 for (dest = 0, temp = 0; dest < 32;
820 dest++)
821 if (rhs & (1L << dest))
822 temp = dest;
823
824 /* Mult takes this many/2 I cycles. */
825 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
826 } else {
827 rhs = DPRegRHS;
828 dest = LHS ^ rhs;
829 WRITEDEST (dest);
830 }
831 break;
832
833 case 0x03: /* EORS reg and MLAS */
834#ifdef MODET
835 if ((BITS (4, 11) & 0xF9) == 0x9)
836 /* LDR register offset, write-back, down, post-indexed. */
837 LHPOSTDOWN ();
838 /* Fall through to rest of the decoding. */
839#endif
840 if (BITS (4, 7) == 9) {
841 /* MLAS */
842 rhs = state->Reg[MULRHSReg];
843 //if (MULLHSReg == MULDESTReg) {
844 if (0) {
845 UNDEF_MULDestEQOp1;
846 dest = state->Reg[MULACCReg];
847 ARMul_NegZero (state, dest);
848 state->Reg[MULDESTReg] = dest;
849 } else if (MULDESTReg != 15) {
850 dest = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
851 ARMul_NegZero (state, dest);
852 state->Reg[MULDESTReg] = dest;
853 } else
854 UNDEF_MULPCDest;
855
856 for (dest = 0, temp = 0; dest < 32;
857 dest++)
858 if (rhs & (1L << dest))
859 temp = dest;
860
861 /* Mult takes this many/2 I cycles. */
862 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
863 } else {
864 /* EORS Reg. */
865 rhs = DPSRegRHS;
866 dest = LHS ^ rhs;
867 WRITESDEST (dest);
868 }
869 break;
870
871 case 0x04: /* SUB reg */
872 // Signifies UMAAL
873 if (state->is_v6 && BITS(4, 7) == 0x09) {
874 if (handle_v6_insn(state, instr))
875 break;
876 }
877
878#ifdef MODET
879 if (BITS (4, 7) == 0xB) {
880 /* STRH immediate offset, no write-back, down, post indexed. */
881 SHDOWNWB ();
882 break;
883 }
884 if (BITS (4, 7) == 0xD) {
885 Handle_Load_Double (state, instr);
886 break;
887 }
888 if (BITS (4, 7) == 0xF) {
889 Handle_Store_Double (state, instr);
890 break;
891 }
892#endif
893 rhs = DPRegRHS;
894 dest = LHS - rhs;
895 WRITEDEST (dest);
896 break;
897
898 case 0x05: /* SUBS reg */
899#ifdef MODET
900 if ((BITS (4, 7) & 0x9) == 0x9)
901 /* LDR immediate offset, no write-back, down, post indexed. */
902 LHPOSTDOWN ();
903 /* Fall through to the rest of the instruction decoding. */
904#endif
905 lhs = LHS;
906 rhs = DPRegRHS;
907 dest = lhs - rhs;
908
909 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
910 ARMul_SubCarry (state, lhs, rhs, dest);
911 ARMul_SubOverflow (state, lhs, rhs, dest);
912 } else {
913 CLEARC;
914 CLEARV;
915 }
916 WRITESDEST (dest);
917 break;
918
919 case 0x06: /* RSB reg */
920#ifdef MODET
921 if (BITS (4, 7) == 0xB) {
922 /* STRH immediate offset, write-back, down, post indexed. */
923 SHDOWNWB ();
924 break;
925 }
926#endif
927 rhs = DPRegRHS;
928 dest = rhs - LHS;
929 WRITEDEST (dest);
930 break;
931
932 case 0x07: /* RSBS reg */
933#ifdef MODET
934 if ((BITS (4, 7) & 0x9) == 0x9)
935 /* LDR immediate offset, write-back, down, post indexed. */
936 LHPOSTDOWN ();
937 /* Fall through to remainder of instruction decoding. */
938#endif
939 lhs = LHS;
940 rhs = DPRegRHS;
941 dest = rhs - lhs;
942
943 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
944 ARMul_SubCarry (state, rhs, lhs, dest);
945 ARMul_SubOverflow (state, rhs, lhs, dest);
946 } else {
947 CLEARC;
948 CLEARV;
949 }
950 WRITESDEST (dest);
951 break;
952
953 case 0x08: /* ADD reg */
954#ifdef MODET
955 if (BITS (4, 11) == 0xB) {
956 /* STRH register offset, no write-back, up, post indexed. */
957 SHUPWB ();
958 break;
959 }
960 if (BITS (4, 7) == 0xD) {
961 Handle_Load_Double (state, instr);
962 break;
963 }
964 if (BITS (4, 7) == 0xF) {
965 Handle_Store_Double (state, instr);
966 break;
967 }
968#endif
969#ifdef MODET
970 if (BITS (4, 7) == 0x9) {
971 /* MULL */
972 /* 32x32 = 64 */
973 ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LDEFAULT), 0L);
974 break;
975 }
976#endif
977 rhs = DPRegRHS;
978 dest = LHS + rhs;
979 WRITEDEST (dest);
980 break;
981
982 case 0x09: /* ADDS reg */
983#ifdef MODET
984 if ((BITS (4, 11) & 0xF9) == 0x9)
985 /* LDR register offset, no write-back, up, post indexed. */
986 LHPOSTUP ();
987 /* Fall through to remaining instruction decoding. */
988#endif
989#ifdef MODET
990 if (BITS (4, 7) == 0x9) {
991 /* MULL */
992 /* 32x32=64 */
993 ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LSCC), 0L);
994 break;
995 }
996#endif
997 lhs = LHS;
998 rhs = DPRegRHS;
999 dest = lhs + rhs;
1000 ASSIGNZ (dest == 0);
1001 if ((lhs | rhs) >> 30) {
1002 /* Possible C,V,N to set. */
1003 ASSIGNN (NEG (dest));
1004 ARMul_AddCarry (state, lhs, rhs, dest);
1005 ARMul_AddOverflow (state, lhs, rhs, dest);
1006 } else {
1007 CLEARN;
1008 CLEARC;
1009 CLEARV;
1010 }
1011 WRITESDEST (dest);
1012 break;
1013
1014 case 0x0a: /* ADC reg */
1015#ifdef MODET
1016 if (BITS (4, 11) == 0xB) {
1017 /* STRH register offset, write-back, up, post-indexed. */
1018 SHUPWB ();
1019 break;
1020 }
1021 if (BITS (4, 7) == 0x9) {
1022 /* MULL */
1023 /* 32x32=64 */
1024 ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LDEFAULT), 0L);
1025 break;
1026 }
1027#endif
1028 rhs = DPRegRHS;
1029 dest = LHS + rhs + CFLAG;
1030 WRITEDEST (dest);
1031 break;
1032
1033 case 0x0b: /* ADCS reg */
1034#ifdef MODET
1035 if ((BITS (4, 11) & 0xF9) == 0x9)
1036 /* LDR register offset, write-back, up, post indexed. */
1037 LHPOSTUP ();
1038 /* Fall through to remaining instruction decoding. */
1039 if (BITS (4, 7) == 0x9) {
1040 /* MULL */
1041 /* 32x32=64 */
1042 ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LSCC), 0L);
1043 break;
1044 }
1045#endif
1046 lhs = LHS;
1047 rhs = DPRegRHS;
1048 dest = lhs + rhs + CFLAG;
1049 ASSIGNZ (dest == 0);
1050 if ((lhs | rhs) >> 30) {
1051 /* Possible C,V,N to set. */
1052 ASSIGNN (NEG (dest));
1053 ARMul_AddCarry (state, lhs, rhs, dest);
1054 ARMul_AddOverflow (state, lhs, rhs, dest);
1055 } else {
1056 CLEARN;
1057 CLEARC;
1058 CLEARV;
1059 }
1060 WRITESDEST (dest);
1061 break;
1062
1063 case 0x0c: /* SBC reg */
1064#ifdef MODET
1065 if (BITS (4, 7) == 0xB) {
1066 /* STRH immediate offset, no write-back, up post indexed. */
1067 SHUPWB ();
1068 break;
1069 }
1070 if (BITS (4, 7) == 0xD) {
1071 Handle_Load_Double (state, instr);
1072 break;
1073 }
1074 if (BITS (4, 7) == 0xF) {
1075 Handle_Store_Double (state, instr);
1076 break;
1077 }
1078 if (BITS (4, 7) == 0x9) {
1079 /* MULL */
1080 /* 32x32=64 */
1081 ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LDEFAULT), 0L);
1082 break;
1083 }
1084#endif
1085 rhs = DPRegRHS;
1086 dest = LHS - rhs - !CFLAG;
1087 WRITEDEST (dest);
1088 break;
1089
1090 case 0x0d: /* SBCS reg */
1091#ifdef MODET
1092 if ((BITS (4, 7) & 0x9) == 0x9)
1093 /* LDR immediate offset, no write-back, up, post indexed. */
1094 LHPOSTUP ();
1095
1096 if (BITS (4, 7) == 0x9) {
1097 /* MULL */
1098 /* 32x32=64 */
1099 ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LSCC), 0L);
1100 break;
1101 }
1102#endif
1103 lhs = LHS;
1104 rhs = DPRegRHS;
1105 dest = lhs - rhs - !CFLAG;
1106 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
1107 ARMul_SubCarry (state, lhs, rhs, dest);
1108 ARMul_SubOverflow (state, lhs, rhs, dest);
1109 } else {
1110 CLEARC;
1111 CLEARV;
1112 }
1113 WRITESDEST (dest);
1114 break;
1115
1116 case 0x0e: /* RSC reg */
1117#ifdef MODET
1118 if (BITS (4, 7) == 0xB) {
1119 /* STRH immediate offset, write-back, up, post indexed. */
1120 SHUPWB ();
1121 break;
1122 }
1123
1124 if (BITS (4, 7) == 0x9) {
1125 /* MULL */
1126 /* 32x32=64 */
1127 ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LDEFAULT), 0L);
1128 break;
1129 }
1130#endif
1131 rhs = DPRegRHS;
1132 dest = rhs - LHS - !CFLAG;
1133 WRITEDEST (dest);
1134 break;
1135
1136 case 0x0f: /* RSCS reg */
1137#ifdef MODET
1138 if ((BITS (4, 7) & 0x9) == 0x9)
1139 /* LDR immediate offset, write-back, up, post indexed. */
1140 LHPOSTUP ();
1141 /* Fall through to remaining instruction decoding. */
1142
1143 if (BITS (4, 7) == 0x9) {
1144 /* MULL */
1145 /* 32x32=64 */
1146 ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LSCC), 0L);
1147 break;
1148 }
1149#endif
1150 lhs = LHS;
1151 rhs = DPRegRHS;
1152 dest = rhs - lhs - !CFLAG;
1153
1154 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
1155 ARMul_SubCarry (state, rhs, lhs, dest);
1156 ARMul_SubOverflow (state, rhs, lhs, dest);
1157 } else {
1158 CLEARC;
1159 CLEARV;
1160 }
1161 WRITESDEST (dest);
1162 break;
1163
1164 case 0x10: /* TST reg and MRS CPSR and SWP word. */
1165 if (state->is_v5e) {
1166 if (BIT (4) == 0 && BIT (7) == 1) {
1167 /* ElSegundo SMLAxy insn. */
1168 ARMword op1 = state->Reg[BITS (0, 3)];
1169 ARMword op2 = state->Reg[BITS (8, 11)];
1170 ARMword Rn = state->Reg[BITS (12, 15)];
1171
1172 if (BIT (5))
1173 op1 >>= 16;
1174 if (BIT (6))
1175 op2 >>= 16;
1176 op1 &= 0xFFFF;
1177 op2 &= 0xFFFF;
1178 if (op1 & 0x8000)
1179 op1 -= 65536;
1180 if (op2 & 0x8000)
1181 op2 -= 65536;
1182 op1 *= op2;
1183 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn);
1184 if (AddOverflow(op1, Rn, op1 + Rn))
1185 SETQ;
1186 state->Reg[BITS (16, 19)] = op1 + Rn;
1187 break;
1188 }
1189
1190 if (BITS (4, 11) == 5) {
1191 /* ElSegundo QADD insn. */
1192 ARMword op1 = state->Reg[BITS (0, 3)];
1193 ARMword op2 = state->Reg[BITS (16, 19)];
1194 ARMword result = op1 + op2;
1195 if (AddOverflow(op1, op2, result)) {
1196 result = POS (result) ? 0x80000000 : 0x7fffffff;
1197 SETQ;
1198 }
1199 state->Reg[BITS (12, 15)] = result;
1200 break;
1201 }
1202 }
1203#ifdef MODET
1204 if (BITS (4, 11) == 0xB) {
1205 /* STRH register offset, no write-back, down, pre indexed. */
1206 SHPREDOWN ();
1207 break;
1208 }
1209 if (BITS (4, 7) == 0xD) {
1210 Handle_Load_Double (state, instr);
1211 break;
1212 }
1213 if (BITS (4, 7) == 0xF) {
1214 Handle_Store_Double (state, instr);
1215 break;
1216 }
1217#endif
1218 if (BITS (4, 11) == 9) {
1219 /* SWP */
1220 UNDEF_SWPPC;
1221 temp = LHS;
1222 BUSUSEDINCPCS;
1223#ifndef MODE32
1224 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) {
1225 INTERNALABORT (temp);
1226 (void) ARMul_LoadWordN (state, temp);
1227 (void) ARMul_LoadWordN (state, temp);
1228 } else
1229#endif
1230 dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
1231 if (temp & 3)
1232 DEST = ARMul_Align (state, temp, dest);
1233 else
1234 DEST = dest;
1235 if (state->abortSig || state->Aborted)
1236 TAKEABORT;
1237 } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */
1238 UNDEF_MRSPC;
1239 DEST = ARMul_GetCPSR(state);
1240 } else {
1241 UNDEF_Test;
1242 }
1243 break;
1244
1245 case 0x11: /* TSTP reg */
1246#ifdef MODET
1247 if ((BITS (4, 11) & 0xF9) == 0x9)
1248 /* LDR register offset, no write-back, down, pre indexed. */
1249 LHPREDOWN ();
1250 /* Continue with remaining instruction decode. */
1251#endif
1252 if (DESTReg == 15) {
1253 /* TSTP reg */
1254#ifdef MODE32
1255 //chy 2006-02-15 if in user mode, can not set cpsr 0:23
1256 //from p165 of ARMARM book
1257 state->Cpsr = GETSPSR (state->Bank);
1258 ARMul_CPSRAltered (state);
1259#else
1260 rhs = DPRegRHS;
1261 temp = LHS & rhs;
1262 SETR15PSR (temp);
1263#endif
1264 } else {
1265 /* TST reg */
1266 rhs = DPSRegRHS;
1267 dest = LHS & rhs;
1268 ARMul_NegZero (state, dest);
1269 }
1270 break;
1271
1272 case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */
1273
1274 if (state->is_v5) {
1275 if (BITS (4, 7) == 3) {
1276 /* BLX(2) */
1277 ARMword temp;
1278
1279 if (TFLAG)
1280 temp = (pc + 2) | 1;
1281 else
1282 temp = pc + 4;
1283
1284 WriteR15Branch (state, state->Reg[RHSReg]);
1285 state->Reg[14] = temp;
1286 break;
1287 }
1288 }
1289
1290 if (state->is_v5e) {
1291 if (BIT (4) == 0 && BIT (7) == 1 && (BIT (5) == 0 || BITS (12, 15) == 0)) {
1292 /* ElSegundo SMLAWy/SMULWy insn. */
1293 unsigned long long op1 = state->Reg[BITS (0, 3)];
1294 unsigned long long op2 = state->Reg[BITS (8, 11)];
1295 unsigned long long result;
1296
1297 if (BIT (6))
1298 op2 >>= 16;
1299 if (op1 & 0x80000000)
1300 op1 -= 1ULL << 32;
1301 op2 &= 0xFFFF;
1302 if (op2 & 0x8000)
1303 op2 -= 65536;
1304 result = (op1 * op2) >> 16;
1305
1306 if (BIT (5) == 0) {
1307 ARMword Rn = state->Reg[BITS(12, 15)];
1308
1309 if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn)))
1310 SETQ;
1311 result += Rn;
1312 }
1313 state->Reg[BITS (16, 19)] = (ARMword)result;
1314 break;
1315 }
1316
1317 if (BITS (4, 11) == 5) {
1318 /* ElSegundo QSUB insn. */
1319 ARMword op1 = state->Reg[BITS (0, 3)];
1320 ARMword op2 = state->Reg[BITS (16, 19)];
1321 ARMword result = op1 - op2;
1322
1323 if (SubOverflow
1324 (op1, op2, result)) {
1325 result = POS (result) ? 0x80000000 : 0x7fffffff;
1326 SETQ;
1327 }
1328
1329 state->Reg[BITS (12, 15)] = result;
1330 break;
1331 }
1332 }
1333#ifdef MODET
1334 if (BITS (4, 11) == 0xB) {
1335 /* STRH register offset, write-back, down, pre indexed. */
1336 SHPREDOWNWB ();
1337 break;
1338 }
1339 if (BITS (4, 27) == 0x12FFF1) {
1340 /* BX */
1341 WriteR15Branch (state, state->Reg[RHSReg]);
1342 break;
1343 }
1344 if (BITS (4, 7) == 0xD) {
1345 Handle_Load_Double (state, instr);
1346 break;
1347 }
1348 if (BITS (4, 7) == 0xF) {
1349 Handle_Store_Double (state, instr);
1350 break;
1351 }
1352#endif
1353 if (state->is_v5) {
1354 if (BITS (4, 7) == 0x7) {
1355 //ARMword value;
1356 //extern int SWI_vector_installed;
1357
1358 /* Hardware is allowed to optionally override this
1359 instruction and treat it as a breakpoint. Since
1360 this is a simulator not hardware, we take the position
1361 that if a SWI vector was not installed, then an Abort
1362 vector was probably not installed either, and so
1363 normally this instruction would be ignored, even if an
1364 Abort is generated. This is a bad thing, since GDB
1365 uses this instruction for its breakpoints (at least in
1366 Thumb mode it does). So intercept the instruction here
1367 and generate a breakpoint SWI instead. */
1368 /* Force the next instruction to be refetched. */
1369 state->NextInstr = RESUME;
1370 break;
1371 }
1372 }
1373 if (DESTReg == 15) {
1374 /* MSR reg to CPSR. */
1375 UNDEF_MSRPC;
1376 temp = DPRegRHS;
1377#ifdef MODET
1378 /* Don't allow TBIT to be set by MSR. */
1379 temp &= ~TBIT;
1380#endif
1381 ARMul_FixCPSR (state, instr, temp);
1382 } else
1383 UNDEF_Test;
1384
1385 break;
1386
1387 case 0x13: /* TEQP reg */
1388#ifdef MODET
1389 if ((BITS (4, 11) & 0xF9) == 0x9)
1390 /* LDR register offset, write-back, down, pre indexed. */
1391 LHPREDOWNWB ();
1392 /* Continue with remaining instruction decode. */
1393#endif
1394 if (DESTReg == 15) {
1395 /* TEQP reg */
1396#ifdef MODE32
1397 state->Cpsr = GETSPSR (state->Bank);
1398 ARMul_CPSRAltered (state);
1399#else
1400 rhs = DPRegRHS;
1401 temp = LHS ^ rhs;
1402 SETR15PSR (temp);
1403#endif
1404 } else {
1405 /* TEQ Reg. */
1406 rhs = DPSRegRHS;
1407 dest = LHS ^ rhs;
1408 ARMul_NegZero (state, dest);
1409 }
1410 break;
1411
1412 case 0x14: /* CMP reg and MRS SPSR and SWP byte. */
1413 if (state->is_v5e) {
1414 if (BIT (4) == 0 && BIT (7) == 1) {
1415 /* ElSegundo SMLALxy insn. */
1416 unsigned long long op1 = state->Reg[BITS (0, 3)];
1417 unsigned long long op2 = state->Reg[BITS (8, 11)];
1418 unsigned long long dest;
1419 //unsigned long long result;
1420
1421 if (BIT (5))
1422 op1 >>= 16;
1423 if (BIT (6))
1424 op2 >>= 16;
1425 op1 &= 0xFFFF;
1426 if (op1 & 0x8000)
1427 op1 -= 65536;
1428 op2 &= 0xFFFF;
1429 if (op2 & 0x8000)
1430 op2 -= 65536;
1431
1432 dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32;
1433 dest |= state->Reg[BITS (12, 15)];
1434 dest += op1 * op2;
1435 state->Reg[BITS(12, 15)] = (ARMword)dest;
1436 state->Reg[BITS(16, 19)] = (ARMword)(dest >> 32);
1437 break;
1438 }
1439
1440 if (BITS (4, 11) == 5) {
1441 /* ElSegundo QDADD insn. */
1442 ARMword op1 = state->Reg[BITS (0, 3)];
1443 ARMword op2 = state->Reg[BITS (16, 19)];
1444 ARMword op2d = op2 + op2;
1445 ARMword result;
1446
1447 if (AddOverflow
1448 (op2, op2, op2d)) {
1449 SETQ;
1450 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1451 }
1452
1453 result = op1 + op2d;
1454 if (AddOverflow(op1, op2d, result)) {
1455 SETQ;
1456 result = POS (result) ? 0x80000000 : 0x7fffffff;
1457 }
1458
1459 state->Reg[BITS (12, 15)] = result;
1460 break;
1461 }
1462 }
1463#ifdef MODET
1464 if (BITS (4, 7) == 0xB) {
1465 /* STRH immediate offset, no write-back, down, pre indexed. */
1466 SHPREDOWN ();
1467 break;
1468 }
1469 if (BITS (4, 7) == 0xD) {
1470 Handle_Load_Double (state, instr);
1471 break;
1472 }
1473 if (BITS (4, 7) == 0xF) {
1474 Handle_Store_Double (state, instr);
1475 break;
1476 }
1477#endif
1478 if (BITS (4, 11) == 9) {
1479 /* SWP */
1480 UNDEF_SWPPC;
1481 temp = LHS;
1482 BUSUSEDINCPCS;
1483#ifndef MODE32
1484 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) {
1485 INTERNALABORT (temp);
1486 (void) ARMul_LoadByte (state, temp);
1487 (void) ARMul_LoadByte (state, temp);
1488 } else
1489#endif
1490 DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
1491 if (state->abortSig || state->Aborted)
1492 TAKEABORT;
1493 } else if ((BITS (0, 11) == 0)
1494 && (LHSReg == 15)) {
1495 /* MRS SPSR */
1496 UNDEF_MRSPC;
1497 DEST = GETSPSR (state->Bank);
1498 } else
1499 UNDEF_Test;
1500
1501 break;
1502
1503 case 0x15: /* CMPP reg. */
1504#ifdef MODET
1505 if ((BITS (4, 7) & 0x9) == 0x9)
1506 /* LDR immediate offset, no write-back, down, pre indexed. */
1507 LHPREDOWN ();
1508 /* Continue with remaining instruction decode. */
1509#endif
1510 if (DESTReg == 15) {
1511 /* CMPP reg. */
1512#ifdef MODE32
1513 state->Cpsr = GETSPSR (state->Bank);
1514 ARMul_CPSRAltered (state);
1515#else
1516 rhs = DPRegRHS;
1517 temp = LHS - rhs;
1518 SETR15PSR (temp);
1519#endif
1520 } else {
1521 /* CMP reg. */
1522 lhs = LHS;
1523 rhs = DPRegRHS;
1524 dest = lhs - rhs;
1525 ARMul_NegZero (state, dest);
1526 if ((lhs >= rhs)
1527 || ((rhs | lhs) >> 31)) {
1528 ARMul_SubCarry (state, lhs, rhs, dest);
1529 ARMul_SubOverflow (state, lhs, rhs, dest);
1530 } else {
1531 CLEARC;
1532 CLEARV;
1533 }
1534 }
1535 break;
1536
1537 case 0x16: /* CMN reg and MSR reg to SPSR */
1538 if (state->is_v5e) {
1539 if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) {
1540 /* ElSegundo SMULxy insn. */
1541 ARMword op1 = state->Reg[BITS (0, 3)];
1542 ARMword op2 = state->Reg[BITS (8, 11)];
1543 ARMword Rn = state->Reg[BITS (12, 15)];
1544
1545 if (BIT (5))
1546 op1 >>= 16;
1547 if (BIT (6))
1548 op2 >>= 16;
1549 op1 &= 0xFFFF;
1550 op2 &= 0xFFFF;
1551 if (op1 & 0x8000)
1552 op1 -= 65536;
1553 if (op2 & 0x8000)
1554 op2 -= 65536;
1555
1556 state->Reg[BITS (16, 19)] = op1 * op2;
1557 break;
1558 }
1559
1560 if (BITS (4, 11) == 5) {
1561 /* ElSegundo QDSUB insn. */
1562 ARMword op1 = state->Reg[BITS (0, 3)];
1563 ARMword op2 = state->Reg[BITS (16, 19)];
1564 ARMword op2d = op2 + op2;
1565 ARMword result;
1566
1567 if (AddOverflow(op2, op2, op2d)) {
1568 SETQ;
1569 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1570 }
1571
1572 result = op1 - op2d;
1573 if (SubOverflow(op1, op2d, result)) {
1574 SETQ;
1575 result = POS (result) ? 0x80000000 : 0x7fffffff;
1576 }
1577
1578 state->Reg[BITS (12, 15)] = result;
1579 break;
1580 }
1581 }
1582
1583 if (state->is_v5) {
1584 if (BITS (4, 11) == 0xF1
1585 && BITS (16, 19) == 0xF) {
1586 /* ARM5 CLZ insn. */
1587 ARMword op1 = state->Reg[BITS (0, 3)];
1588 int result = 32;
1589
1590 if (op1)
1591 for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
1592 result++;
1593 state->Reg[BITS (12, 15)] = result;
1594 break;
1595 }
1596 }
1597
1598#ifdef MODET
1599 if (BITS (4, 7) == 0xB) {
1600 /* STRH immediate offset, write-back, down, pre indexed. */
1601 SHPREDOWNWB ();
1602 break;
1603 }
1604 if (BITS (4, 7) == 0xD) {
1605 Handle_Load_Double (state, instr);
1606 break;
1607 }
1608 if (BITS (4, 7) == 0xF) {
1609 Handle_Store_Double (state, instr);
1610 break;
1611 }
1612#endif
1613 if (DESTReg == 15) {
1614 /* MSR */
1615 UNDEF_MSRPC;
1616 /*ARMul_FixSPSR (state, instr,
1617 DPRegRHS);*/
1618 } else {
1619 UNDEF_Test;
1620 }
1621 break;
1622
1623 case 0x17: /* CMNP reg */
1624#ifdef MODET
1625 if ((BITS (4, 7) & 0x9) == 0x9)
1626 /* LDR immediate offset, write-back, down, pre indexed. */
1627 LHPREDOWNWB ();
1628 /* Continue with remaining instruction decoding. */
1629#endif
1630 if (DESTReg == 15) {
1631#ifdef MODE32
1632 state->Cpsr = GETSPSR (state->Bank);
1633 ARMul_CPSRAltered (state);
1634#else
1635 rhs = DPRegRHS;
1636 temp = LHS + rhs;
1637 SETR15PSR (temp);
1638#endif
1639 break;
1640 } else {
1641 /* CMN reg. */
1642 lhs = LHS;
1643 rhs = DPRegRHS;
1644 dest = lhs + rhs;
1645 ASSIGNZ (dest == 0);
1646 if ((lhs | rhs) >> 30) {
1647 /* Possible C,V,N to set. */
1648 ASSIGNN (NEG (dest));
1649 ARMul_AddCarry (state, lhs, rhs, dest);
1650 ARMul_AddOverflow (state, lhs, rhs, dest);
1651 } else {
1652 CLEARN;
1653 CLEARC;
1654 CLEARV;
1655 }
1656 }
1657 break;
1658
1659 case 0x18: /* ORR reg */
1660#ifdef MODET
1661 /* dyf add armv6 instr strex 2010.9.17 */
1662 if (state->is_v6) {
1663 if (BITS (4, 7) == 0x9)
1664 if (handle_v6_insn (state, instr))
1665 break;
1666 }
1667
1668 if (BITS (4, 11) == 0xB) {
1669 /* STRH register offset, no write-back, up, pre indexed. */
1670 SHPREUP ();
1671 break;
1672 }
1673 if (BITS (4, 7) == 0xD) {
1674 Handle_Load_Double (state, instr);
1675 break;
1676 }
1677 if (BITS (4, 7) == 0xF) {
1678 Handle_Store_Double (state, instr);
1679 break;
1680 }
1681#endif
1682 rhs = DPRegRHS;
1683 dest = LHS | rhs;
1684 WRITEDEST (dest);
1685 break;
1686
1687 case 0x19: /* ORRS reg */
1688#ifdef MODET
1689 /* dyf add armv6 instr ldrex */
1690 if (state->is_v6) {
1691 if (BITS (4, 7) == 0x9) {
1692 if (handle_v6_insn (state, instr))
1693 break;
1694 }
1695 }
1696 if ((BITS (4, 11) & 0xF9) == 0x9)
1697 /* LDR register offset, no write-back, up, pre indexed. */
1698 LHPREUP ();
1699 /* Continue with remaining instruction decoding. */
1700#endif
1701 rhs = DPSRegRHS;
1702 dest = LHS | rhs;
1703 WRITESDEST (dest);
1704 break;
1705
1706 case 0x1a: /* MOV reg */
1707#ifdef MODET
1708 if (BITS (4, 11) == 0xB) {
1709 /* STRH register offset, write-back, up, pre indexed. */
1710 SHPREUPWB ();
1711 break;
1712 }
1713 if (BITS (4, 7) == 0xD) {
1714 Handle_Load_Double (state, instr);
1715 break;
1716 }
1717 if (BITS (4, 7) == 0xF) {
1718 Handle_Store_Double (state, instr);
1719 break;
1720 }
1721 if (BITS(4, 11) == 0xF9) { //strexd
1722 u32 l = LHSReg;
1723
1724 bool enter = false;
1725
1726 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&&
1727 state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4))
1728 enter = true;
1729
1730 //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html
1731
1732 if (enter) {
1733 ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]);
1734 ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]);
1735 state->Reg[DESTReg] = 0;
1736 } else {
1737 state->Reg[DESTReg] = 1;
1738 }
1739
1740 break;
1741 }
1742#endif
1743 dest = DPRegRHS;
1744 WRITEDEST (dest);
1745 break;
1746
1747 case 0x1B: /* MOVS reg */
1748#ifdef MODET
1749 /* ldrexd ichfly */
1750 if (BITS(0, 11) == 0xF9F) { //strexd
1751 lhs = LHS;
1752
1753 state->currentexaddr = lhs;
1754 state->currentexval = (u32)ARMul_ReadWord(state, lhs);
1755 state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4);
1756
1757 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs);
1758 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4);
1759 break;
1760 }
1761
1762 if ((BITS (4, 11) & 0xF9) == 0x9)
1763 /* LDR register offset, write-back, up, pre indexed. */
1764 LHPREUPWB ();
1765 /* Continue with remaining instruction decoding. */
1766
1767#endif
1768 dest = DPSRegRHS;
1769 WRITESDEST (dest);
1770 break;
1771
1772 case 0x1c: /* BIC reg */
1773#ifdef MODET
1774 /* dyf add for STREXB */
1775 if (state->is_v6) {
1776 if (BITS (4, 7) == 0x9) {
1777 if (handle_v6_insn (state, instr))
1778 break;
1779 }
1780 }
1781 if (BITS (4, 7) == 0xB) {
1782 /* STRH immediate offset, no write-back, up, pre indexed. */
1783 SHPREUP ();
1784 break;
1785 }
1786 if (BITS (4, 7) == 0xD) {
1787 Handle_Load_Double (state, instr);
1788 break;
1789 } else if (BITS (4, 7) == 0xF) {
1790 Handle_Store_Double (state, instr);
1791 break;
1792 }
1793#endif
1794 rhs = DPRegRHS;
1795 dest = LHS & ~rhs;
1796 WRITEDEST (dest);
1797 break;
1798
1799 case 0x1d: /* BICS reg */
1800#ifdef MODET
1801 /* ladsh P=1 U=1 W=0 L=1 S=1 H=1 */
1802 if (BITS(4, 7) == 0xF) {
1803 temp = LHS + GetLS7RHS (state, instr);
1804 LoadHalfWord (state, instr, temp, LSIGNED);
1805 break;
1806 }
1807 if (BITS (4, 7) == 0xb) {
1808 /* LDRH immediate offset, no write-back, up, pre indexed. */
1809 temp = LHS + GetLS7RHS (state, instr);
1810 LoadHalfWord (state, instr, temp, LUNSIGNED);
1811 break;
1812 }
1813 if (BITS (4, 7) == 0xd) {
1814 // alex-ykl fix: 2011-07-20 missing ldrsb instruction
1815 temp = LHS + GetLS7RHS (state, instr);
1816 LoadByte (state, instr, temp, LSIGNED);
1817 break;
1818 }
1819
1820 /* Continue with instruction decoding. */
1821 /*if ((BITS (4, 7) & 0x9) == 0x9) */
1822 if ((BITS (4, 7)) == 0x9) {
1823 /* ldrexb */
1824 if (state->is_v6) {
1825 if (handle_v6_insn (state, instr))
1826 break;
1827 }
1828 /* LDR immediate offset, no write-back, up, pre indexed. */
1829 LHPREUP ();
1830 }
1831
1832#endif
1833 rhs = DPSRegRHS;
1834 dest = LHS & ~rhs;
1835 WRITESDEST (dest);
1836 break;
1837
1838 case 0x1e: /* MVN reg */
1839#ifdef MODET
1840 if ((instr & 0x00000FF0) == 0x00000F90) { //if ((instr & 0x0FF00FF0) == 0x01e00f90) { //todo make that better ichfly
1841 /* strexh ichfly */
1842 u32 l = LHSReg;
1843 u32 r = RHSReg;
1844 lhs = LHS;
1845
1846 bool enter = false;
1847
1848 if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
1849
1850 //StoreWord(state, lhs, RHS)
1851 if (state->Aborted) {
1852 TAKEABORT;
1853 }
1854 if (enter) {
1855 ARMul_StoreHalfWord(state, lhs, RHS);
1856 state->Reg[DESTReg] = 0;
1857 } else {
1858 state->Reg[DESTReg] = 1;
1859 }
1860 break;
1861 }
1862 if (BITS (4, 7) == 0xB) {
1863 /* STRH immediate offset, write-back, up, pre indexed. */
1864 SHPREUPWB ();
1865 break;
1866 }
1867 if (BITS (4, 7) == 0xD) {
1868 Handle_Load_Double (state, instr);
1869 break;
1870 }
1871 if (BITS (4, 7) == 0xF) {
1872 Handle_Store_Double (state, instr);
1873 break;
1874 }
1875#endif
1876 dest = ~DPRegRHS;
1877 WRITEDEST (dest);
1878 break;
1879
1880 case 0x1f: /* MVNS reg */
1881#ifdef MODET
1882
1883 if ((instr & 0x00000FF0) == 0x00000F90) { //(instr & 0x0FF00FF0) == 0x01f00f90)//if ((instr & 0x0FF00FF0) == 0x01f00f90) {
1884 /* ldrexh ichfly */
1885 lhs = LHS;
1886
1887 state->currentexaddr = lhs;
1888 state->currentexval = (u32)ARMul_LoadHalfWord(state, lhs);
1889
1890 LoadHalfWord(state, instr, lhs,0);
1891 break;
1892 }
1893
1894 if ((BITS (4, 7) & 0x9) == 0x9)
1895 /* LDR immediate offset, write-back, up, pre indexed. */
1896 LHPREUPWB ();
1897 /* Continue instruction decoding. */
1898#endif
1899 dest = ~DPSRegRHS;
1900 WRITESDEST (dest);
1901 break;
1902
1903 /* Data Processing Immediate RHS Instructions. */
1904
1905 case 0x20: /* AND immed */
1906 dest = LHS & DPImmRHS;
1907 WRITEDEST (dest);
1908 break;
1909
1910 case 0x21: /* ANDS immed */
1911 DPSImmRHS;
1912 dest = LHS & rhs;
1913 WRITESDEST (dest);
1914 break;
1915
1916 case 0x22: /* EOR immed */
1917 dest = LHS ^ DPImmRHS;
1918 WRITEDEST (dest);
1919 break;
1920
1921 case 0x23: /* EORS immed */
1922 DPSImmRHS;
1923 dest = LHS ^ rhs;
1924 WRITESDEST (dest);
1925 break;
1926
1927 case 0x24: /* SUB immed */
1928 dest = LHS - DPImmRHS;
1929 WRITEDEST (dest);
1930 break;
1931
1932 case 0x25: /* SUBS immed */
1933 lhs = LHS;
1934 rhs = DPImmRHS;
1935 dest = lhs - rhs;
1936
1937 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
1938 ARMul_SubCarry (state, lhs, rhs, dest);
1939 ARMul_SubOverflow (state, lhs, rhs, dest);
1940 } else {
1941 CLEARC;
1942 CLEARV;
1943 }
1944 WRITESDEST (dest);
1945 break;
1946
1947 case 0x26: /* RSB immed */
1948 dest = DPImmRHS - LHS;
1949 WRITEDEST (dest);
1950 break;
1951
1952 case 0x27: /* RSBS immed */
1953 lhs = LHS;
1954 rhs = DPImmRHS;
1955 dest = rhs - lhs;
1956
1957 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
1958 ARMul_SubCarry (state, rhs, lhs, dest);
1959 ARMul_SubOverflow (state, rhs, lhs, dest);
1960 } else {
1961 CLEARC;
1962 CLEARV;
1963 }
1964 WRITESDEST (dest);
1965 break;
1966
1967 case 0x28: /* ADD immed */
1968 dest = LHS + DPImmRHS;
1969 WRITEDEST (dest);
1970 break;
1971
1972 case 0x29: /* ADDS immed */
1973 lhs = LHS;
1974 rhs = DPImmRHS;
1975 dest = lhs + rhs;
1976 ASSIGNZ (dest == 0);
1977
1978 if ((lhs | rhs) >> 30) {
1979 /* Possible C,V,N to set. */
1980 ASSIGNN (NEG (dest));
1981 ARMul_AddCarry (state, lhs, rhs, dest);
1982 ARMul_AddOverflow (state, lhs, rhs, dest);
1983 } else {
1984 CLEARN;
1985 CLEARC;
1986 CLEARV;
1987 }
1988 WRITESDEST (dest);
1989 break;
1990
1991 case 0x2a: /* ADC immed */
1992 dest = LHS + DPImmRHS + CFLAG;
1993 WRITEDEST (dest);
1994 break;
1995
1996 case 0x2b: /* ADCS immed */
1997 lhs = LHS;
1998 rhs = DPImmRHS;
1999 dest = lhs + rhs + CFLAG;
2000 ASSIGNZ (dest == 0);
2001 if ((lhs | rhs) >> 30) {
2002 /* Possible C,V,N to set. */
2003 ASSIGNN (NEG (dest));
2004 ARMul_AddCarry (state, lhs, rhs, dest);
2005 ARMul_AddOverflow (state, lhs, rhs, dest);
2006 } else {
2007 CLEARN;
2008 CLEARC;
2009 CLEARV;
2010 }
2011 WRITESDEST (dest);
2012 break;
2013
2014 case 0x2c: /* SBC immed */
2015 dest = LHS - DPImmRHS - !CFLAG;
2016 WRITEDEST (dest);
2017 break;
2018
2019 case 0x2d: /* SBCS immed */
2020 lhs = LHS;
2021 rhs = DPImmRHS;
2022 dest = lhs - rhs - !CFLAG;
2023 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
2024 ARMul_SubCarry (state, lhs, rhs, dest);
2025 ARMul_SubOverflow (state, lhs, rhs, dest);
2026 } else {
2027 CLEARC;
2028 CLEARV;
2029 }
2030 WRITESDEST (dest);
2031 break;
2032
2033 case 0x2e: /* RSC immed */
2034 dest = DPImmRHS - LHS - !CFLAG;
2035 WRITEDEST (dest);
2036 break;
2037
2038 case 0x2f: /* RSCS immed */
2039 lhs = LHS;
2040 rhs = DPImmRHS;
2041 dest = rhs - lhs - !CFLAG;
2042 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
2043 ARMul_SubCarry (state, rhs, lhs, dest);
2044 ARMul_SubOverflow (state, rhs, lhs, dest);
2045 } else {
2046 CLEARC;
2047 CLEARV;
2048 }
2049 WRITESDEST (dest);
2050 break;
2051
2052 case 0x30: /* TST immed */
2053 /* shenoubang 2012-3-14*/
2054 if (state->is_v6) { /* movw, ARMV6, ARMv7 */
2055 dest ^= dest;
2056 dest = BITS(16, 19);
2057 dest = ((dest<<12) | BITS(0, 11));
2058 WRITEDEST(dest);
2059 break;
2060 } else {
2061 UNDEF_Test;
2062 break;
2063 }
2064
2065 case 0x31: /* TSTP immed */
2066 if (DESTReg == 15) {
2067 /* TSTP immed. */
2068#ifdef MODE32
2069 state->Cpsr = GETSPSR (state->Bank);
2070 ARMul_CPSRAltered (state);
2071#else
2072 temp = LHS & DPImmRHS;
2073 SETR15PSR (temp);
2074#endif
2075 } else {
2076 /* TST immed. */
2077 DPSImmRHS;
2078 dest = LHS & rhs;
2079 ARMul_NegZero (state, dest);
2080 }
2081 break;
2082
2083 case 0x32: /* TEQ immed and MSR immed to CPSR */
2084 if (DESTReg == 15)
2085 /* MSR immed to CPSR. */
2086 ARMul_FixCPSR (state, instr,
2087 DPImmRHS);
2088 else
2089 UNDEF_Test;
2090 break;
2091
2092 case 0x33: /* TEQP immed */
2093 if (DESTReg == 15) {
2094 /* TEQP immed. */
2095#ifdef MODE32
2096 state->Cpsr = GETSPSR (state->Bank);
2097 ARMul_CPSRAltered (state);
2098#else
2099 temp = LHS ^ DPImmRHS;
2100 SETR15PSR (temp);
2101#endif
2102 } else {
2103 DPSImmRHS; /* TEQ immed */
2104 dest = LHS ^ rhs;
2105 ARMul_NegZero (state, dest);
2106 }
2107 break;
2108
2109 case 0x34: /* CMP immed */
2110 UNDEF_Test;
2111 break;
2112
2113 case 0x35: /* CMPP immed */
2114 if (DESTReg == 15) {
2115 /* CMPP immed. */
2116#ifdef MODE32
2117 state->Cpsr = GETSPSR (state->Bank);
2118 ARMul_CPSRAltered (state);
2119#else
2120 temp = LHS - DPImmRHS;
2121 SETR15PSR (temp);
2122#endif
2123 break;
2124 } else {
2125 /* CMP immed. */
2126 lhs = LHS;
2127 rhs = DPImmRHS;
2128 dest = lhs - rhs;
2129 ARMul_NegZero (state, dest);
2130
2131 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
2132 ARMul_SubCarry (state, lhs, rhs, dest);
2133 ARMul_SubOverflow (state, lhs, rhs, dest);
2134 } else {
2135 CLEARC;
2136 CLEARV;
2137 }
2138 }
2139 break;
2140
2141 case 0x36: /* CMN immed and MSR immed to SPSR */
2142 //if (DESTReg == 15)
2143 /*ARMul0_FixSPSR (state, instr,
2144 DPImmRHS);*/
2145 //else
2146 UNDEF_Test;
2147 break;
2148
2149 case 0x37: /* CMNP immed. */
2150 if (DESTReg == 15) {
2151 /* CMNP immed. */
2152#ifdef MODE32
2153 state->Cpsr = GETSPSR (state->Bank);
2154 ARMul_CPSRAltered (state);
2155#else
2156 temp = LHS + DPImmRHS;
2157 SETR15PSR (temp);
2158#endif
2159 break;
2160 } else {
2161 /* CMN immed. */
2162 lhs = LHS;
2163 rhs = DPImmRHS;
2164 dest = lhs + rhs;
2165 ASSIGNZ (dest == 0);
2166 if ((lhs | rhs) >> 30) {
2167 /* Possible C,V,N to set. */
2168 ASSIGNN (NEG (dest));
2169 ARMul_AddCarry (state, lhs, rhs, dest);
2170 ARMul_AddOverflow (state, lhs, rhs, dest);
2171 } else {
2172 CLEARN;
2173 CLEARC;
2174 CLEARV;
2175 }
2176 }
2177 break;
2178
2179 case 0x38: /* ORR immed. */
2180 dest = LHS | DPImmRHS;
2181 WRITEDEST (dest);
2182 break;
2183
2184 case 0x39: /* ORRS immed. */
2185 DPSImmRHS;
2186 dest = LHS | rhs;
2187 WRITESDEST (dest);
2188 break;
2189
2190 case 0x3a: /* MOV immed. */
2191 dest = DPImmRHS;
2192 WRITEDEST (dest);
2193 break;
2194
2195 case 0x3b: /* MOVS immed. */
2196 DPSImmRHS;
2197 WRITESDEST (rhs);
2198 break;
2199
2200 case 0x3c: /* BIC immed. */
2201 dest = LHS & ~DPImmRHS;
2202 WRITEDEST (dest);
2203 break;
2204
2205 case 0x3d: /* BICS immed. */
2206 DPSImmRHS;
2207 dest = LHS & ~rhs;
2208 WRITESDEST (dest);
2209 break;
2210
2211 case 0x3e: /* MVN immed. */
2212 dest = ~DPImmRHS;
2213 WRITEDEST (dest);
2214 break;
2215
2216 case 0x3f: /* MVNS immed. */
2217 DPSImmRHS;
2218 WRITESDEST (~rhs);
2219 break;
2220
2221 /* Single Data Transfer Immediate RHS Instructions. */
2222
2223 case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */
2224 lhs = LHS;
2225 if (StoreWord (state, instr, lhs))
2226 LSBase = lhs - LSImmRHS;
2227 break;
2228
2229 case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */
2230 lhs = LHS;
2231 if (LoadWord (state, instr, lhs))
2232 LSBase = lhs - LSImmRHS;
2233 break;
2234
2235 case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */
2236 UNDEF_LSRBaseEQDestWb;
2237 UNDEF_LSRPCBaseWb;
2238 lhs = LHS;
2239 temp = lhs - LSImmRHS;
2240 state->NtransSig = LOW;
2241 if (StoreWord (state, instr, lhs))
2242 LSBase = temp;
2243 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2244 break;
2245
2246 case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */
2247 UNDEF_LSRBaseEQDestWb;
2248 UNDEF_LSRPCBaseWb;
2249 lhs = LHS;
2250 state->NtransSig = LOW;
2251 if (LoadWord (state, instr, lhs))
2252 LSBase = lhs - LSImmRHS;
2253 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2254 break;
2255
2256 case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */
2257 lhs = LHS;
2258 if (StoreByte (state, instr, lhs))
2259 LSBase = lhs - LSImmRHS;
2260 break;
2261
2262 case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */
2263 lhs = LHS;
2264 if (LoadByte (state, instr, lhs, LUNSIGNED))
2265 LSBase = lhs - LSImmRHS;
2266 break;
2267
2268 case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */
2269 UNDEF_LSRBaseEQDestWb;
2270 UNDEF_LSRPCBaseWb;
2271 lhs = LHS;
2272 state->NtransSig = LOW;
2273 if (StoreByte (state, instr, lhs))
2274 LSBase = lhs - LSImmRHS;
2275 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2276 break;
2277
2278 case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */
2279 UNDEF_LSRBaseEQDestWb;
2280 UNDEF_LSRPCBaseWb;
2281 lhs = LHS;
2282 state->NtransSig = LOW;
2283 if (LoadByte (state, instr, lhs, LUNSIGNED))
2284 LSBase = lhs - LSImmRHS;
2285 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2286 break;
2287
2288 case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */
2289 lhs = LHS;
2290 if (StoreWord (state, instr, lhs))
2291 LSBase = lhs + LSImmRHS;
2292 break;
2293
2294 case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */
2295 lhs = LHS;
2296 if (LoadWord (state, instr, lhs))
2297 LSBase = lhs + LSImmRHS;
2298 break;
2299
2300 case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */
2301 UNDEF_LSRBaseEQDestWb;
2302 UNDEF_LSRPCBaseWb;
2303 lhs = LHS;
2304 state->NtransSig = LOW;
2305 if (StoreWord (state, instr, lhs))
2306 LSBase = lhs + LSImmRHS;
2307 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2308 break;
2309
2310 case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */
2311 UNDEF_LSRBaseEQDestWb;
2312 UNDEF_LSRPCBaseWb;
2313 lhs = LHS;
2314 state->NtransSig = LOW;
2315 if (LoadWord (state, instr, lhs))
2316 LSBase = lhs + LSImmRHS;
2317 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2318 break;
2319
2320 case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */
2321 lhs = LHS;
2322 if (StoreByte (state, instr, lhs))
2323 LSBase = lhs + LSImmRHS;
2324 break;
2325
2326 case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */
2327 lhs = LHS;
2328 if (LoadByte (state, instr, lhs, LUNSIGNED))
2329 LSBase = lhs + LSImmRHS;
2330 break;
2331
2332 case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */
2333 UNDEF_LSRBaseEQDestWb;
2334 UNDEF_LSRPCBaseWb;
2335 lhs = LHS;
2336 state->NtransSig = LOW;
2337 if (StoreByte (state, instr, lhs))
2338 LSBase = lhs + LSImmRHS;
2339 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2340 break;
2341
2342 case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */
2343 UNDEF_LSRBaseEQDestWb;
2344 UNDEF_LSRPCBaseWb;
2345 lhs = LHS;
2346 state->NtransSig = LOW;
2347 if (LoadByte (state, instr, lhs, LUNSIGNED))
2348 LSBase = lhs + LSImmRHS;
2349 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2350 break;
2351
2352 case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */
2353 (void) StoreWord (state, instr, LHS - LSImmRHS);
2354 break;
2355
2356 case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */
2357 (void) LoadWord (state, instr, LHS - LSImmRHS);
2358 break;
2359
2360 case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */
2361 UNDEF_LSRBaseEQDestWb;
2362 UNDEF_LSRPCBaseWb;
2363 temp = LHS - LSImmRHS;
2364 if (StoreWord (state, instr, temp))
2365 LSBase = temp;
2366 break;
2367
2368 case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */
2369 UNDEF_LSRBaseEQDestWb;
2370 UNDEF_LSRPCBaseWb;
2371 temp = LHS - LSImmRHS;
2372 if (LoadWord (state, instr, temp))
2373 LSBase = temp;
2374 break;
2375
2376 case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */
2377 (void) StoreByte (state, instr, LHS - LSImmRHS);
2378 break;
2379
2380 case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */
2381 (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
2382 break;
2383
2384 case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */
2385 UNDEF_LSRBaseEQDestWb;
2386 UNDEF_LSRPCBaseWb;
2387 temp = LHS - LSImmRHS;
2388 if (StoreByte (state, instr, temp))
2389 LSBase = temp;
2390 break;
2391
2392 case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */
2393 UNDEF_LSRBaseEQDestWb;
2394 UNDEF_LSRPCBaseWb;
2395 temp = LHS - LSImmRHS;
2396 if (LoadByte (state, instr, temp, LUNSIGNED))
2397 LSBase = temp;
2398 break;
2399
2400 case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */
2401 (void) StoreWord (state, instr, LHS + LSImmRHS);
2402 break;
2403
2404 case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */
2405 (void) LoadWord (state, instr, LHS + LSImmRHS);
2406 break;
2407
2408 case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */
2409 UNDEF_LSRBaseEQDestWb;
2410 UNDEF_LSRPCBaseWb;
2411 temp = LHS + LSImmRHS;
2412 if (StoreWord (state, instr, temp))
2413 LSBase = temp;
2414 break;
2415
2416 case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */
2417 UNDEF_LSRBaseEQDestWb;
2418 UNDEF_LSRPCBaseWb;
2419 temp = LHS + LSImmRHS;
2420 if (LoadWord (state, instr, temp))
2421 LSBase = temp;
2422 break;
2423
2424 case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */
2425 (void) StoreByte (state, instr, LHS + LSImmRHS);
2426 break;
2427
2428 case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */
2429 (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
2430 break;
2431
2432 case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */
2433 UNDEF_LSRBaseEQDestWb;
2434 UNDEF_LSRPCBaseWb;
2435 temp = LHS + LSImmRHS;
2436 if (StoreByte (state, instr, temp))
2437 LSBase = temp;
2438 break;
2439
2440 case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */
2441 UNDEF_LSRBaseEQDestWb;
2442 UNDEF_LSRPCBaseWb;
2443 temp = LHS + LSImmRHS;
2444 if (LoadByte (state, instr, temp, LUNSIGNED))
2445 LSBase = temp;
2446 break;
2447
2448 /* Single Data Transfer Register RHS Instructions. */
2449
2450 case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */
2451 if (BIT (4)) {
2452 ARMul_UndefInstr (state, instr);
2453 break;
2454 }
2455 UNDEF_LSRBaseEQOffWb;
2456 UNDEF_LSRBaseEQDestWb;
2457 UNDEF_LSRPCBaseWb;
2458 UNDEF_LSRPCOffWb;
2459 lhs = LHS;
2460 if (StoreWord (state, instr, lhs))
2461 LSBase = lhs - LSRegRHS;
2462 break;
2463
2464 case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */
2465 if (BIT (4)) {
2466#ifdef MODE32
2467 if (state->is_v6 && handle_v6_insn (state, instr))
2468 break;
2469#endif
2470 ARMul_UndefInstr (state, instr);
2471 break;
2472 }
2473 UNDEF_LSRBaseEQOffWb;
2474 UNDEF_LSRBaseEQDestWb;
2475 UNDEF_LSRPCBaseWb;
2476 UNDEF_LSRPCOffWb;
2477 lhs = LHS;
2478 temp = lhs - LSRegRHS;
2479 if (LoadWord (state, instr, lhs))
2480 LSBase = temp;
2481 break;
2482
2483 case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */
2484 if (BIT (4)) {
2485#ifdef MODE32
2486 if (state->is_v6 && handle_v6_insn (state, instr))
2487 break;
2488#endif
2489 ARMul_UndefInstr (state, instr);
2490 break;
2491 }
2492 UNDEF_LSRBaseEQOffWb;
2493 UNDEF_LSRBaseEQDestWb;
2494 UNDEF_LSRPCBaseWb;
2495 UNDEF_LSRPCOffWb;
2496 lhs = LHS;
2497 state->NtransSig = LOW;
2498 if (StoreWord (state, instr, lhs))
2499 LSBase = lhs - LSRegRHS;
2500 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2501 break;
2502
2503 case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */
2504 if (BIT (4)) {
2505#ifdef MODE32
2506 if (state->is_v6 && handle_v6_insn (state, instr))
2507 break;
2508#endif
2509 ARMul_UndefInstr (state, instr);
2510 break;
2511 }
2512 UNDEF_LSRBaseEQOffWb;
2513 UNDEF_LSRBaseEQDestWb;
2514 UNDEF_LSRPCBaseWb;
2515 UNDEF_LSRPCOffWb;
2516 lhs = LHS;
2517 temp = lhs - LSRegRHS;
2518 state->NtransSig = LOW;
2519 if (LoadWord (state, instr, lhs))
2520 LSBase = temp;
2521 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2522 break;
2523
2524 case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */
2525 if (BIT (4)) {
2526 ARMul_UndefInstr (state, instr);
2527 break;
2528 }
2529 UNDEF_LSRBaseEQOffWb;
2530 UNDEF_LSRBaseEQDestWb;
2531 UNDEF_LSRPCBaseWb;
2532 UNDEF_LSRPCOffWb;
2533 lhs = LHS;
2534 if (StoreByte (state, instr, lhs))
2535 LSBase = lhs - LSRegRHS;
2536 break;
2537
2538 case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */
2539 if (BIT (4)) {
2540#ifdef MODE32
2541 if (state->is_v6 && handle_v6_insn (state, instr))
2542 break;
2543#endif
2544 ARMul_UndefInstr (state, instr);
2545 break;
2546 }
2547 UNDEF_LSRBaseEQOffWb;
2548 UNDEF_LSRBaseEQDestWb;
2549 UNDEF_LSRPCBaseWb;
2550 UNDEF_LSRPCOffWb;
2551 lhs = LHS;
2552 temp = lhs - LSRegRHS;
2553 if (LoadByte (state, instr, lhs, LUNSIGNED))
2554 LSBase = temp;
2555 break;
2556
2557 case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */
2558 if (BIT (4)) {
2559#ifdef MODE32
2560 if (state->is_v6 && handle_v6_insn (state, instr))
2561 break;
2562#endif
2563 ARMul_UndefInstr (state, instr);
2564 break;
2565 }
2566 UNDEF_LSRBaseEQOffWb;
2567 UNDEF_LSRBaseEQDestWb;
2568 UNDEF_LSRPCBaseWb;
2569 UNDEF_LSRPCOffWb;
2570 lhs = LHS;
2571 state->NtransSig = LOW;
2572 if (StoreByte (state, instr, lhs))
2573 LSBase = lhs - LSRegRHS;
2574 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2575 break;
2576
2577 case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */
2578 if (BIT (4)) {
2579#ifdef MODE32
2580 if (state->is_v6
2581 && handle_v6_insn (state, instr))
2582 break;
2583#endif
2584
2585 ARMul_UndefInstr (state, instr);
2586 break;
2587 }
2588 UNDEF_LSRBaseEQOffWb;
2589 UNDEF_LSRBaseEQDestWb;
2590 UNDEF_LSRPCBaseWb;
2591 UNDEF_LSRPCOffWb;
2592 lhs = LHS;
2593 temp = lhs - LSRegRHS;
2594 state->NtransSig = LOW;
2595 if (LoadByte (state, instr, lhs, LUNSIGNED))
2596 LSBase = temp;
2597 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2598 break;
2599
2600 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
2601 if ((instr & 0x70) == 0x10) { //pkhbt
2602 u8 idest = BITS(12, 15);
2603 u8 rfis = BITS(16, 19);
2604 u8 rlast = BITS(0, 3);
2605 u8 ishi = BITS(7,11);
2606 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
2607 break;
2608 } else if ((instr & 0x70) == 0x50) { //pkhtb
2609 u8 rd_idx = BITS(12, 15);
2610 u8 rn_idx = BITS(16, 19);
2611 u8 rm_idx = BITS(0, 3);
2612 u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
2613 state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
2614 break;
2615 } else if (BIT (4)) {
2616#ifdef MODE32
2617 if (state->is_v6
2618 && handle_v6_insn (state, instr))
2619 break;
2620#endif
2621
2622 ARMul_UndefInstr (state, instr);
2623 break;
2624 }
2625 UNDEF_LSRBaseEQOffWb;
2626 UNDEF_LSRBaseEQDestWb;
2627 UNDEF_LSRPCBaseWb;
2628 UNDEF_LSRPCOffWb;
2629 lhs = LHS;
2630 if (StoreWord (state, instr, lhs))
2631 LSBase = lhs + LSRegRHS;
2632 break;
2633
2634 case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */
2635 if (BIT (4)) {
2636 ARMul_UndefInstr (state, instr);
2637 break;
2638 }
2639 UNDEF_LSRBaseEQOffWb;
2640 UNDEF_LSRBaseEQDestWb;
2641 UNDEF_LSRPCBaseWb;
2642 UNDEF_LSRPCOffWb;
2643 lhs = LHS;
2644 temp = lhs + LSRegRHS;
2645 if (LoadWord (state, instr, lhs))
2646 LSBase = temp;
2647 break;
2648
2649 case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */
2650 if (BIT (4)) {
2651#ifdef MODE32
2652 if (state->is_v6
2653 && handle_v6_insn (state, instr))
2654 break;
2655#endif
2656
2657 ARMul_UndefInstr (state, instr);
2658 break;
2659 }
2660 UNDEF_LSRBaseEQOffWb;
2661 UNDEF_LSRBaseEQDestWb;
2662 UNDEF_LSRPCBaseWb;
2663 UNDEF_LSRPCOffWb;
2664 lhs = LHS;
2665 state->NtransSig = LOW;
2666 if (StoreWord (state, instr, lhs))
2667 LSBase = lhs + LSRegRHS;
2668 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2669 break;
2670
2671 case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */
2672 if (BIT (4)) {
2673#ifdef MODE32
2674 if (state->is_v6
2675 && handle_v6_insn (state, instr))
2676 break;
2677#endif
2678
2679 ARMul_UndefInstr (state, instr);
2680 break;
2681 }
2682 UNDEF_LSRBaseEQOffWb;
2683 UNDEF_LSRBaseEQDestWb;
2684 UNDEF_LSRPCBaseWb;
2685 UNDEF_LSRPCOffWb;
2686 lhs = LHS;
2687 temp = lhs + LSRegRHS;
2688 state->NtransSig = LOW;
2689 if (LoadWord (state, instr, lhs))
2690 LSBase = temp;
2691 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2692 break;
2693
2694 case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */
2695 if (BIT (4)) {
2696#ifdef MODE32
2697 if (state->is_v6
2698 && handle_v6_insn (state, instr))
2699 break;
2700#endif
2701
2702 ARMul_UndefInstr (state, instr);
2703 break;
2704 }
2705 UNDEF_LSRBaseEQOffWb;
2706 UNDEF_LSRBaseEQDestWb;
2707 UNDEF_LSRPCBaseWb;
2708 UNDEF_LSRPCOffWb;
2709 lhs = LHS;
2710 if (StoreByte (state, instr, lhs))
2711 LSBase = lhs + LSRegRHS;
2712 break;
2713
2714 case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */
2715 if (BIT (4)) {
2716 ARMul_UndefInstr (state, instr);
2717 break;
2718 }
2719 UNDEF_LSRBaseEQOffWb;
2720 UNDEF_LSRBaseEQDestWb;
2721 UNDEF_LSRPCBaseWb;
2722 UNDEF_LSRPCOffWb;
2723 lhs = LHS;
2724 temp = lhs + LSRegRHS;
2725 if (LoadByte (state, instr, lhs, LUNSIGNED))
2726 LSBase = temp;
2727 break;
2728
2729 case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */
2730 if (BIT (4)) {
2731#ifdef MODE32
2732 if (state->is_v6
2733 && handle_v6_insn (state, instr))
2734 break;
2735#endif
2736
2737 ARMul_UndefInstr (state, instr);
2738 break;
2739 }
2740 UNDEF_LSRBaseEQOffWb;
2741 UNDEF_LSRBaseEQDestWb;
2742 UNDEF_LSRPCBaseWb;
2743 UNDEF_LSRPCOffWb;
2744 lhs = LHS;
2745 state->NtransSig = LOW;
2746 if (StoreByte (state, instr, lhs))
2747 LSBase = lhs + LSRegRHS;
2748 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2749 break;
2750
2751 case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */
2752 if (BIT (4)) {
2753#ifdef MODE32
2754 if (state->is_v6
2755 && handle_v6_insn (state, instr))
2756 break;
2757#endif
2758
2759 ARMul_UndefInstr (state, instr);
2760 break;
2761 }
2762 UNDEF_LSRBaseEQOffWb;
2763 UNDEF_LSRBaseEQDestWb;
2764 UNDEF_LSRPCBaseWb;
2765 UNDEF_LSRPCOffWb;
2766 lhs = LHS;
2767 temp = lhs + LSRegRHS;
2768 state->NtransSig = LOW;
2769 if (LoadByte (state, instr, lhs, LUNSIGNED))
2770 LSBase = temp;
2771 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2772 break;
2773
2774 case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */
2775 if (BIT (4)) {
2776#ifdef MODE32
2777 if (state->is_v6 && handle_v6_insn (state, instr))
2778 break;
2779#endif
2780 ARMul_UndefInstr (state, instr);
2781 break;
2782 }
2783 (void) StoreWord (state, instr, LHS - LSRegRHS);
2784 break;
2785
2786 case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */
2787 if (BIT (4)) {
2788 ARMul_UndefInstr (state, instr);
2789 break;
2790 }
2791 (void) LoadWord (state, instr, LHS - LSRegRHS);
2792 break;
2793
2794 case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */
2795 if (BIT (4)) {
2796 ARMul_UndefInstr (state, instr);
2797 break;
2798 }
2799 UNDEF_LSRBaseEQOffWb;
2800 UNDEF_LSRBaseEQDestWb;
2801 UNDEF_LSRPCBaseWb;
2802 UNDEF_LSRPCOffWb;
2803 temp = LHS - LSRegRHS;
2804 if (StoreWord (state, instr, temp))
2805 LSBase = temp;
2806 break;
2807
2808 case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */
2809 if (BIT (4)) {
2810 ARMul_UndefInstr (state, instr);
2811 break;
2812 }
2813 UNDEF_LSRBaseEQOffWb;
2814 UNDEF_LSRBaseEQDestWb;
2815 UNDEF_LSRPCBaseWb;
2816 UNDEF_LSRPCOffWb;
2817 temp = LHS - LSRegRHS;
2818 if (LoadWord (state, instr, temp))
2819 LSBase = temp;
2820 break;
2821
2822 case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */
2823 if (BIT (4)) {
2824#ifdef MODE32
2825 if (state->is_v6 && handle_v6_insn (state, instr))
2826 break;
2827#endif
2828 ARMul_UndefInstr (state, instr);
2829 break;
2830 }
2831 (void) StoreByte (state, instr, LHS - LSRegRHS);
2832 break;
2833
2834 case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */
2835 if (BIT (4)) {
2836#ifdef MODE32
2837 if (state->is_v6 && handle_v6_insn (state, instr))
2838 break;
2839#endif
2840 ARMul_UndefInstr (state, instr);
2841 break;
2842 }
2843 (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
2844 break;
2845
2846 case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */
2847 if (BIT (4)) {
2848 ARMul_UndefInstr (state, instr);
2849 break;
2850 }
2851 UNDEF_LSRBaseEQOffWb;
2852 UNDEF_LSRBaseEQDestWb;
2853 UNDEF_LSRPCBaseWb;
2854 UNDEF_LSRPCOffWb;
2855 temp = LHS - LSRegRHS;
2856 if (StoreByte (state, instr, temp))
2857 LSBase = temp;
2858 break;
2859
2860 case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */
2861 if (BIT (4)) {
2862 ARMul_UndefInstr (state, instr);
2863 break;
2864 }
2865 UNDEF_LSRBaseEQOffWb;
2866 UNDEF_LSRBaseEQDestWb;
2867 UNDEF_LSRPCBaseWb;
2868 UNDEF_LSRPCOffWb;
2869 temp = LHS - LSRegRHS;
2870 if (LoadByte (state, instr, temp, LUNSIGNED))
2871 LSBase = temp;
2872 break;
2873
2874 case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */
2875 if (BIT (4)) {
2876#ifdef MODE32
2877 if (state->is_v6 && handle_v6_insn (state, instr))
2878 break;
2879#endif
2880
2881 ARMul_UndefInstr (state, instr);
2882 break;
2883 }
2884 (void) StoreWord (state, instr, LHS + LSRegRHS);
2885 break;
2886
2887 case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */
2888 if (BIT (4)) {
2889 ARMul_UndefInstr (state, instr);
2890 break;
2891 }
2892 (void) LoadWord (state, instr, LHS + LSRegRHS);
2893 break;
2894
2895 case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */
2896 if (BIT (4)) {
2897#ifdef MODE32
2898 if (state->is_v6 && handle_v6_insn (state, instr))
2899 break;
2900#endif
2901
2902 ARMul_UndefInstr (state, instr);
2903 break;
2904 }
2905 UNDEF_LSRBaseEQOffWb;
2906 UNDEF_LSRBaseEQDestWb;
2907 UNDEF_LSRPCBaseWb;
2908 UNDEF_LSRPCOffWb;
2909 temp = LHS + LSRegRHS;
2910 if (StoreWord (state, instr, temp))
2911 LSBase = temp;
2912 break;
2913
2914 case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */
2915 if (BIT (4)) {
2916 ARMul_UndefInstr (state, instr);
2917 break;
2918 }
2919 UNDEF_LSRBaseEQOffWb;
2920 UNDEF_LSRBaseEQDestWb;
2921 UNDEF_LSRPCBaseWb;
2922 UNDEF_LSRPCOffWb;
2923 temp = LHS + LSRegRHS;
2924 if (LoadWord (state, instr, temp))
2925 LSBase = temp;
2926 break;
2927
2928 case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */
2929 if (BIT (4)) {
2930#ifdef MODE32
2931 if (state->is_v6 && handle_v6_insn (state, instr))
2932 break;
2933#endif
2934
2935 ARMul_UndefInstr (state, instr);
2936 break;
2937 }
2938 (void) StoreByte (state, instr, LHS + LSRegRHS);
2939 break;
2940
2941 case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */
2942 if (BIT (4)) {
2943 ARMul_UndefInstr (state, instr);
2944 break;
2945 }
2946 (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
2947 break;
2948
2949 case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */
2950 if (BIT (4)) {
2951 ARMul_UndefInstr (state, instr);
2952 break;
2953 }
2954 UNDEF_LSRBaseEQOffWb;
2955 UNDEF_LSRBaseEQDestWb;
2956 UNDEF_LSRPCBaseWb;
2957 UNDEF_LSRPCOffWb;
2958 temp = LHS + LSRegRHS;
2959 if (StoreByte (state, instr, temp))
2960 LSBase = temp;
2961 break;
2962
2963 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
2964 if (BIT (4)) {
2965 LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint");
2966 return 1;
2967 }
2968 UNDEF_LSRBaseEQOffWb;
2969 UNDEF_LSRBaseEQDestWb;
2970 UNDEF_LSRPCBaseWb;
2971 UNDEF_LSRPCOffWb;
2972 temp = LHS + LSRegRHS;
2973 if (LoadByte (state, instr, temp, LUNSIGNED))
2974 LSBase = temp;
2975 break;
2976
2977 /* Multiple Data Transfer Instructions. */
2978
2979 case 0x80: /* Store, No WriteBack, Post Dec. */
2980 STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
2981 break;
2982
2983 case 0x81: /* Load, No WriteBack, Post Dec. */
2984 LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
2985 break;
2986
2987 case 0x82: /* Store, WriteBack, Post Dec. */
2988 temp = LSBase - LSMNumRegs;
2989 STOREMULT (instr, temp + 4L, temp);
2990 break;
2991
2992 case 0x83: /* Load, WriteBack, Post Dec. */
2993 temp = LSBase - LSMNumRegs;
2994 LOADMULT (instr, temp + 4L, temp);
2995 break;
2996
2997 case 0x84: /* Store, Flags, No WriteBack, Post Dec. */
2998 STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
2999 break;
3000
3001 case 0x85: /* Load, Flags, No WriteBack, Post Dec. */
3002 LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3003 break;
3004
3005 case 0x86: /* Store, Flags, WriteBack, Post Dec. */
3006 temp = LSBase - LSMNumRegs;
3007 STORESMULT (instr, temp + 4L, temp);
3008 break;
3009
3010 case 0x87: /* Load, Flags, WriteBack, Post Dec. */
3011 temp = LSBase - LSMNumRegs;
3012 LOADSMULT (instr, temp + 4L, temp);
3013 break;
3014
3015 case 0x88: /* Store, No WriteBack, Post Inc. */
3016 STOREMULT (instr, LSBase, 0L);
3017 break;
3018
3019 case 0x89: /* Load, No WriteBack, Post Inc. */
3020 LOADMULT (instr, LSBase, 0L);
3021 break;
3022
3023 case 0x8a: /* Store, WriteBack, Post Inc. */
3024 temp = LSBase;
3025 STOREMULT (instr, temp, temp + LSMNumRegs);
3026 break;
3027
3028 case 0x8b: /* Load, WriteBack, Post Inc. */
3029 temp = LSBase;
3030 LOADMULT (instr, temp, temp + LSMNumRegs);
3031 break;
3032
3033 case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */
3034 STORESMULT (instr, LSBase, 0L);
3035 break;
3036
3037 case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */
3038 LOADSMULT (instr, LSBase, 0L);
3039 break;
3040
3041 case 0x8e: /* Store, Flags, WriteBack, Post Inc. */
3042 temp = LSBase;
3043 STORESMULT (instr, temp, temp + LSMNumRegs);
3044 break;
3045
3046 case 0x8f: /* Load, Flags, WriteBack, Post Inc. */
3047 temp = LSBase;
3048 LOADSMULT (instr, temp, temp + LSMNumRegs);
3049 break;
3050
3051 case 0x90: /* Store, No WriteBack, Pre Dec. */
3052 STOREMULT (instr, LSBase - LSMNumRegs, 0L);
3053 break;
3054
3055 case 0x91: /* Load, No WriteBack, Pre Dec. */
3056 LOADMULT (instr, LSBase - LSMNumRegs, 0L);
3057 break;
3058
3059 case 0x92: /* Store, WriteBack, Pre Dec. */
3060 temp = LSBase - LSMNumRegs;
3061 STOREMULT (instr, temp, temp);
3062 break;
3063
3064 case 0x93: /* Load, WriteBack, Pre Dec. */
3065 temp = LSBase - LSMNumRegs;
3066 LOADMULT (instr, temp, temp);
3067 break;
3068
3069 case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */
3070 STORESMULT (instr, LSBase - LSMNumRegs, 0L);
3071 break;
3072
3073 case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */
3074 LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
3075 break;
3076
3077 case 0x96: /* Store, Flags, WriteBack, Pre Dec. */
3078 temp = LSBase - LSMNumRegs;
3079 STORESMULT (instr, temp, temp);
3080 break;
3081
3082 case 0x97: /* Load, Flags, WriteBack, Pre Dec. */
3083 temp = LSBase - LSMNumRegs;
3084 LOADSMULT (instr, temp, temp);
3085 break;
3086
3087 case 0x98: /* Store, No WriteBack, Pre Inc. */
3088 STOREMULT (instr, LSBase + 4L, 0L);
3089 break;
3090
3091 case 0x99: /* Load, No WriteBack, Pre Inc. */
3092 LOADMULT (instr, LSBase + 4L, 0L);
3093 break;
3094
3095 case 0x9a: /* Store, WriteBack, Pre Inc. */
3096 temp = LSBase;
3097 STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
3098 break;
3099
3100 case 0x9b: /* Load, WriteBack, Pre Inc. */
3101 temp = LSBase;
3102 LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
3103 break;
3104
3105 case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */
3106 STORESMULT (instr, LSBase + 4L, 0L);
3107 break;
3108
3109 case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */
3110 LOADSMULT (instr, LSBase + 4L, 0L);
3111 break;
3112
3113 case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */
3114 temp = LSBase;
3115 STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
3116 break;
3117
3118 case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */
3119 temp = LSBase;
3120 LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
3121 break;
3122
3123 /* Branch forward. */
3124 case 0xa0:
3125 case 0xa1:
3126 case 0xa2:
3127 case 0xa3:
3128 case 0xa4:
3129 case 0xa5:
3130 case 0xa6:
3131 case 0xa7:
3132 state->Reg[15] = pc + 8 + POSBRANCH;
3133 FLUSHPIPE;
3134 break;
3135
3136 /* Branch backward. */
3137 case 0xa8:
3138 case 0xa9:
3139 case 0xaa:
3140 case 0xab:
3141 case 0xac:
3142 case 0xad:
3143 case 0xae:
3144 case 0xaf:
3145 state->Reg[15] = pc + 8 + NEGBRANCH;
3146 FLUSHPIPE;
3147 break;
3148
3149 /* Branch and Link forward. */
3150 case 0xb0:
3151 case 0xb1:
3152 case 0xb2:
3153 case 0xb3:
3154 case 0xb4:
3155 case 0xb5:
3156 case 0xb6:
3157 case 0xb7:
3158
3159 /* Put PC into Link. */
3160#ifdef MODE32
3161 state->Reg[14] = pc + 4;
3162#else
3163 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3164#endif
3165 state->Reg[15] = pc + 8 + POSBRANCH;
3166 FLUSHPIPE;
3167 break;
3168
3169 /* Branch and Link backward. */
3170 case 0xb8:
3171 case 0xb9:
3172 case 0xba:
3173 case 0xbb:
3174 case 0xbc:
3175 case 0xbd:
3176 case 0xbe:
3177 case 0xbf:
3178 /* Put PC into Link. */
3179#ifdef MODE32
3180 state->Reg[14] = pc + 4;
3181#else
3182 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3183#endif
3184 state->Reg[15] = pc + 8 + NEGBRANCH;
3185 FLUSHPIPE;
3186 break;
3187
3188 /* Co-Processor Data Transfers. */
3189 case 0xc4:
3190 if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
3191 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
3192 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
3193 break;
3194 } else if (state->is_v5) {
3195 /* Reading from R15 is UNPREDICTABLE. */
3196 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3197 ARMul_UndefInstr (state, instr);
3198 /* Is access to coprocessor 0 allowed ? */
3199 else if (!CP_ACCESS_ALLOWED(state, CPNum))
3200 ARMul_UndefInstr (state, instr);
3201 else {
3202 /* MCRR, ARMv5TE and up */
3203 ARMul_MCRR (state, instr, DEST, state->Reg[LHSReg]);
3204 break;
3205 }
3206 }
3207 /* Drop through. */
3208
3209 case 0xc0: /* Store , No WriteBack , Post Dec. */
3210 ARMul_STC (state, instr, LHS);
3211 break;
3212
3213 case 0xc5:
3214 if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
3215 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
3216 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
3217 break;
3218 } else if (state->is_v5) {
3219 /* Writes to R15 are UNPREDICATABLE. */
3220 if (DESTReg == 15 || LHSReg == 15)
3221 ARMul_UndefInstr (state, instr);
3222 /* Is access to the coprocessor allowed ? */
3223 else if (!CP_ACCESS_ALLOWED(state, CPNum)) {
3224 ARMul_UndefInstr(state, instr);
3225 } else {
3226 /* MRRC, ARMv5TE and up */
3227 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
3228 break;
3229 }
3230 }
3231 /* Drop through. */
3232
3233 case 0xc1: /* Load , No WriteBack , Post Dec. */
3234 ARMul_LDC (state, instr, LHS);
3235 break;
3236
3237 case 0xc2:
3238 case 0xc6: /* Store , WriteBack , Post Dec. */
3239 lhs = LHS;
3240 state->Base = lhs - LSCOff;
3241 ARMul_STC (state, instr, lhs);
3242 break;
3243
3244 case 0xc3:
3245 case 0xc7: /* Load , WriteBack , Post Dec. */
3246 lhs = LHS;
3247 state->Base = lhs - LSCOff;
3248 ARMul_LDC (state, instr, lhs);
3249 break;
3250
3251 case 0xc8:
3252 case 0xcc: /* Store , No WriteBack , Post Inc. */
3253 ARMul_STC (state, instr, LHS);
3254 break;
3255
3256 case 0xc9:
3257 case 0xcd: /* Load , No WriteBack , Post Inc. */
3258 ARMul_LDC (state, instr, LHS);
3259 break;
3260
3261 case 0xca:
3262 case 0xce: /* Store , WriteBack , Post Inc. */
3263 lhs = LHS;
3264 state->Base = lhs + LSCOff;
3265 ARMul_STC (state, instr, LHS);
3266 break;
3267
3268 case 0xcb:
3269 case 0xcf: /* Load , WriteBack , Post Inc. */
3270 lhs = LHS;
3271 state->Base = lhs + LSCOff;
3272 ARMul_LDC (state, instr, LHS);
3273 break;
3274
3275 case 0xd0:
3276 case 0xd4: /* Store , No WriteBack , Pre Dec. */
3277 ARMul_STC (state, instr, LHS - LSCOff);
3278 break;
3279
3280 case 0xd1:
3281 case 0xd5: /* Load , No WriteBack , Pre Dec. */
3282 ARMul_LDC (state, instr, LHS - LSCOff);
3283 break;
3284
3285 case 0xd2:
3286 case 0xd6: /* Store , WriteBack , Pre Dec. */
3287 lhs = LHS - LSCOff;
3288 state->Base = lhs;
3289 ARMul_STC (state, instr, lhs);
3290 break;
3291
3292 case 0xd3:
3293 case 0xd7: /* Load , WriteBack , Pre Dec. */
3294 lhs = LHS - LSCOff;
3295 state->Base = lhs;
3296 ARMul_LDC (state, instr, lhs);
3297 break;
3298
3299 case 0xd8:
3300 case 0xdc: /* Store , No WriteBack , Pre Inc. */
3301 ARMul_STC (state, instr, LHS + LSCOff);
3302 break;
3303
3304 case 0xd9:
3305 case 0xdd: /* Load , No WriteBack , Pre Inc. */
3306 ARMul_LDC (state, instr, LHS + LSCOff);
3307 break;
3308
3309 case 0xda:
3310 case 0xde: /* Store , WriteBack , Pre Inc. */
3311 lhs = LHS + LSCOff;
3312 state->Base = lhs;
3313 ARMul_STC (state, instr, lhs);
3314 break;
3315
3316 case 0xdb:
3317 case 0xdf: /* Load , WriteBack , Pre Inc. */
3318 lhs = LHS + LSCOff;
3319 state->Base = lhs;
3320 ARMul_LDC (state, instr, lhs);
3321 break;
3322
3323 /* Co-Processor Register Transfers (MCR) and Data Ops. */
3324
3325 case 0xe2:
3326 /*if (!CP_ACCESS_ALLOWED (state, CPNum)) {
3327 ARMul_UndefInstr (state, instr);
3328 break;
3329 }*/
3330
3331 case 0xe0:
3332 case 0xe4:
3333 case 0xe6:
3334 case 0xe8:
3335 case 0xea:
3336 case 0xec:
3337 case 0xee:
3338 if (BIT (4)) {
3339 /* MCR. */
3340 if (DESTReg == 15) {
3341 UNDEF_MCRPC;
3342#ifdef MODE32
3343 ARMul_MCR (state, instr, state->Reg[15] + isize);
3344#else
3345 ARMul_MCR (state, instr, ECC | ER15INT | EMODE | ((state->Reg[15] + isize) & R15PCBITS));
3346#endif
3347 } else
3348 ARMul_MCR (state, instr, DEST);
3349 } else
3350 /* CDP Part 1. */
3351 ARMul_CDP (state, instr);
3352 break;
3353
3354 /* Co-Processor Register Transfers (MRC) and Data Ops. */
3355 case 0xe1:
3356 case 0xe3:
3357 case 0xe5:
3358 case 0xe7:
3359 case 0xe9:
3360 case 0xeb:
3361 case 0xed:
3362 case 0xef:
3363 if (BIT (4)) {
3364 /* MRC */
3365 temp = ARMul_MRC (state, instr);
3366 if (DESTReg == 15) {
3367 ASSIGNN ((temp & NBIT) != 0);
3368 ASSIGNZ ((temp & ZBIT) != 0);
3369 ASSIGNC ((temp & CBIT) != 0);
3370 ASSIGNV ((temp & VBIT) != 0);
3371 } else
3372 DEST = temp;
3373 } else
3374 /* CDP Part 2. */
3375 ARMul_CDP (state, instr);
3376 break;
3377
3378 /* SWI instruction. */
3379 case 0xf0:
3380 case 0xf1:
3381 case 0xf2:
3382 case 0xf3:
3383 case 0xf4:
3384 case 0xf5:
3385 case 0xf6:
3386 case 0xf7:
3387 case 0xf8:
3388 case 0xf9:
3389 case 0xfa:
3390 case 0xfb:
3391 case 0xfc:
3392 case 0xfd:
3393 case 0xfe:
3394 case 0xff:
3395 //svc_Execute(state, BITS(0, 23));
3396 HLE::CallSVC(instr);
3397
3398 break;
3399 }
3400 }
3401
3402#ifdef MODET
3403donext:
3404#endif
3405 state->pc = pc;
3406
3407 /* jump out every time */
3408 //state->EndCondition = 0;
3409 //state->Emulate = STOP;
3410//chy 2006-04-12 for ICE debug
3411TEST_EMULATE:
3412 if (state->Emulate == ONCE)
3413 state->Emulate = STOP;
3414 else if (state->Emulate != RUN)
3415 break;
3416 }
3417
3418 while (state->NumInstrsToExecute);
3419exit:
3420 state->decoded = decoded;
3421 state->loaded = loaded;
3422 state->pc = pc;
3423 //chy 2006-04-12, for ICE debug
3424 state->decoded_addr=decoded_addr;
3425 state->loaded_addr=loaded_addr;
3426
3427 return pc;
3428 }
3429
3430 static volatile void (*gen_func) (void);
3431
3432 static volatile uint32_t tmp_st;
3433 static volatile uint32_t save_st;
3434 static volatile uint32_t save_T0;
3435 static volatile uint32_t save_T1;
3436 static volatile uint32_t save_T2;
3437
3438 /* This routine evaluates most Data Processing register RHS's with the S
3439 bit clear. It is intended to be called from the macro DPRegRHS, which
3440 filters the common case of an unshifted register with in line code. */
3441
3442 static ARMword
3443 GetDPRegRHS (ARMul_State * state, ARMword instr) {
3444 ARMword shamt, base;
3445
3446 base = RHSReg;
3447 if (BIT (4)) {
3448 /* Shift amount in a register. */
3449 UNDEF_Shift;
3450 INCPC;
3451#ifndef MODE32
3452 if (base == 15)
3453 base = ECC | ER15INT | R15PC | EMODE;
3454 else
3455#endif
3456 base = state->Reg[base];
3457 ARMul_Icycles (state, 1, 0L);
3458 shamt = state->Reg[BITS (8, 11)] & 0xff;
3459 switch ((int) BITS (5, 6)) {
3460 case LSL:
3461 if (shamt == 0)
3462 return (base);
3463 else if (shamt >= 32)
3464 return (0);
3465 else
3466 return (base << shamt);
3467 case LSR:
3468 if (shamt == 0)
3469 return (base);
3470 else if (shamt >= 32)
3471 return (0);
3472 else
3473 return (base >> shamt);
3474 case ASR:
3475 if (shamt == 0)
3476 return (base);
3477 else if (shamt >= 32)
3478 return ((ARMword) ((int) base >> 31L));
3479 else
3480 return ((ARMword)
3481 (( int) base >> (int) shamt));
3482 case ROR:
3483 shamt &= 0x1f;
3484 if (shamt == 0)
3485 return (base);
3486 else
3487 return ((base << (32 - shamt)) |
3488 (base >> shamt));
3489 }
3490 } else {
3491 /* Shift amount is a constant. */
3492#ifndef MODE32
3493 if (base == 15)
3494 base = ECC | ER15INT | R15PC | EMODE;
3495 else
3496#endif
3497 base = state->Reg[base];
3498 shamt = BITS (7, 11);
3499 switch ((int) BITS (5, 6)) {
3500 case LSL:
3501 return (base << shamt);
3502 case LSR:
3503 if (shamt == 0)
3504 return (0);
3505 else
3506 return (base >> shamt);
3507 case ASR:
3508 if (shamt == 0)
3509 return ((ARMword) (( int) base >> 31L));
3510 else
3511 return ((ARMword)
3512 (( int) base >> (int) shamt));
3513 case ROR:
3514 if (shamt == 0)
3515 /* It's an RRX. */
3516 return ((base >> 1) | (CFLAG << 31));
3517 else
3518 return ((base << (32 - shamt)) |
3519 (base >> shamt));
3520 }
3521 }
3522
3523 return 0;
3524 }
3525
3526 /* This routine evaluates most Logical Data Processing register RHS's
3527 with the S bit set. It is intended to be called from the macro
3528 DPSRegRHS, which filters the common case of an unshifted register
3529 with in line code. */
3530
3531 static ARMword
3532 GetDPSRegRHS (ARMul_State * state, ARMword instr) {
3533 ARMword shamt, base;
3534
3535 base = RHSReg;
3536 if (BIT (4)) {
3537 /* Shift amount in a register. */
3538 UNDEF_Shift;
3539 INCPC;
3540#ifndef MODE32
3541 if (base == 15)
3542 base = ECC | ER15INT | R15PC | EMODE;
3543 else
3544#endif
3545 base = state->Reg[base];
3546 ARMul_Icycles (state, 1, 0L);
3547 shamt = state->Reg[BITS (8, 11)] & 0xff;
3548 switch ((int) BITS (5, 6)) {
3549 case LSL:
3550 if (shamt == 0)
3551 return (base);
3552 else if (shamt == 32) {
3553 ASSIGNC (base & 1);
3554 return (0);
3555 } else if (shamt > 32) {
3556 CLEARC;
3557 return (0);
3558 } else {
3559 ASSIGNC ((base >> (32 - shamt)) & 1);
3560 return (base << shamt);
3561 }
3562 case LSR:
3563 if (shamt == 0)
3564 return (base);
3565 else if (shamt == 32) {
3566 ASSIGNC (base >> 31);
3567 return (0);
3568 } else if (shamt > 32) {
3569 CLEARC;
3570 return (0);
3571 } else {
3572 ASSIGNC ((base >> (shamt - 1)) & 1);
3573 return (base >> shamt);
3574 }
3575 case ASR:
3576 if (shamt == 0)
3577 return (base);
3578 else if (shamt >= 32) {
3579 ASSIGNC (base >> 31L);
3580 return ((ARMword) (( int) base >> 31L));
3581 } else {
3582 ASSIGNC ((ARMword)
3583 (( int) base >>
3584 (int) (shamt - 1)) & 1);
3585 return ((ARMword)
3586 ((int) base >> (int) shamt));
3587 }
3588 case ROR:
3589 if (shamt == 0)
3590 return (base);
3591 shamt &= 0x1f;
3592 if (shamt == 0) {
3593 ASSIGNC (base >> 31);
3594 return (base);
3595 } else {
3596 ASSIGNC ((base >> (shamt - 1)) & 1);
3597 return ((base << (32 - shamt)) |
3598 (base >> shamt));
3599 }
3600 }
3601 } else {
3602 /* Shift amount is a constant. */
3603#ifndef MODE32
3604 if (base == 15)
3605 base = ECC | ER15INT | R15PC | EMODE;
3606 else
3607#endif
3608 base = state->Reg[base];
3609 shamt = BITS (7, 11);
3610
3611 switch ((int) BITS (5, 6)) {
3612 case LSL:
3613 ASSIGNC ((base >> (32 - shamt)) & 1);
3614 return (base << shamt);
3615 case LSR:
3616 if (shamt == 0) {
3617 ASSIGNC (base >> 31);
3618 return (0);
3619 } else {
3620 ASSIGNC ((base >> (shamt - 1)) & 1);
3621 return (base >> shamt);
3622 }
3623 case ASR:
3624 if (shamt == 0) {
3625 ASSIGNC (base >> 31L);
3626 return ((ARMword) ((int) base >> 31L));
3627 } else {
3628 ASSIGNC ((ARMword)
3629 ((int) base >>
3630 (int) (shamt - 1)) & 1);
3631 return ((ARMword)
3632 (( int) base >> (int) shamt));
3633 }
3634 case ROR:
3635 if (shamt == 0) {
3636 /* It's an RRX. */
3637 shamt = CFLAG;
3638 ASSIGNC (base & 1);
3639 return ((base >> 1) | (shamt << 31));
3640 } else {
3641 ASSIGNC ((base >> (shamt - 1)) & 1);
3642 return ((base << (32 - shamt)) |
3643 (base >> shamt));
3644 }
3645 }
3646 }
3647
3648 return 0;
3649 }
3650
3651 /* This routine handles writes to register 15 when the S bit is not set. */
3652
3653 static void
3654 WriteR15 (ARMul_State * state, ARMword src) {
3655 /* The ARM documentation states that the two least significant bits
3656 are discarded when setting PC, except in the cases handled by
3657 WriteR15Branch() below. It's probably an oversight: in THUMB
3658 mode, the second least significant bit should probably not be
3659 discarded. */
3660#ifdef MODET
3661 if (TFLAG)
3662 src &= 0xfffffffe;
3663 else
3664#endif
3665 src &= 0xfffffffc;
3666
3667#ifdef MODE32
3668 state->Reg[15] = src & PCBITS;
3669#else
3670 state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
3671 ARMul_R15Altered (state);
3672#endif
3673
3674 FLUSHPIPE;
3675 }
3676
3677 /* This routine handles writes to register 15 when the S bit is set. */
3678
3679 static void
3680 WriteSR15 (ARMul_State * state, ARMword src) {
3681#ifdef MODE32
3682 if (state->Bank > 0) {
3683 state->Cpsr = state->Spsr[state->Bank];
3684 ARMul_CPSRAltered (state);
3685 }
3686#ifdef MODET
3687 if (TFLAG)
3688 src &= 0xfffffffe;
3689 else
3690#endif
3691 src &= 0xfffffffc;
3692 state->Reg[15] = src & PCBITS;
3693#else
3694#ifdef MODET
3695 if (TFLAG)
3696 /* ARMul_R15Altered would have to support it. */
3697 abort ();
3698 else
3699#endif
3700 src &= 0xfffffffc;
3701
3702 if (state->Bank == USERBANK)
3703 state->Reg[15] =
3704 (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
3705 else
3706 state->Reg[15] = src;
3707
3708 ARMul_R15Altered (state);
3709#endif
3710 FLUSHPIPE;
3711 }
3712
3713 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
3714 will switch to Thumb mode if the least significant bit is set. */
3715
3716 static void
3717 WriteR15Branch (ARMul_State * state, ARMword src) {
3718#ifdef MODET
3719 if (src & 1) {
3720 /* Thumb bit. */
3721 SETT;
3722 state->Reg[15] = src & 0xfffffffe;
3723 } else {
3724 CLEART;
3725 state->Reg[15] = src & 0xfffffffc;
3726 }
3727 state->Cpsr = ARMul_GetCPSR (state);
3728 FLUSHPIPE;
3729#else
3730 WriteR15 (state, src);
3731#endif
3732 }
3733
3734 /* This routine evaluates most Load and Store register RHS's. It is
3735 intended to be called from the macro LSRegRHS, which filters the
3736 common case of an unshifted register with in line code. */
3737
3738 static ARMword
3739 GetLSRegRHS (ARMul_State * state, ARMword instr) {
3740 ARMword shamt, base;
3741
3742 base = RHSReg;
3743#ifndef MODE32
3744 if (base == 15)
3745 /* Now forbidden, but ... */
3746 base = ECC | ER15INT | R15PC | EMODE;
3747 else
3748#endif
3749 base = state->Reg[base];
3750
3751 shamt = BITS (7, 11);
3752 switch ((int) BITS (5, 6)) {
3753 case LSL:
3754 return (base << shamt);
3755 case LSR:
3756 if (shamt == 0)
3757 return (0);
3758 else
3759 return (base >> shamt);
3760 case ASR:
3761 if (shamt == 0)
3762 return ((ARMword) (( int) base >> 31L));
3763 else
3764 return ((ARMword) (( int) base >> (int) shamt));
3765 case ROR:
3766 if (shamt == 0)
3767 /* It's an RRX. */
3768 return ((base >> 1) | (CFLAG << 31));
3769 else
3770 return ((base << (32 - shamt)) | (base >> shamt));
3771 default:
3772 break;
3773 }
3774 return 0;
3775 }
3776
3777 /* This routine evaluates the ARM7T halfword and signed transfer RHS's. */
3778
3779 static ARMword
3780 GetLS7RHS (ARMul_State * state, ARMword instr) {
3781 if (BIT (22) == 0) {
3782 /* Register. */
3783#ifndef MODE32
3784 if (RHSReg == 15)
3785 /* Now forbidden, but ... */
3786 return ECC | ER15INT | R15PC | EMODE;
3787#endif
3788 return state->Reg[RHSReg];
3789 }
3790
3791 /* Immediate. */
3792 return BITS (0, 3) | (BITS (8, 11) << 4);
3793 }
3794
3795 static unsigned
3796 LoadWord (ARMul_State * state, ARMword instr, ARMword address) {
3797 ARMword dest;
3798
3799 BUSUSEDINCPCS;
3800#ifndef MODE32
3801 if (ADDREXCEPT (address))
3802 INTERNALABORT (address);
3803#endif
3804
3805 dest = ARMul_LoadWordN (state, address);
3806
3807 if (state->Aborted) {
3808 TAKEABORT;
3809 return state->lateabtSig;
3810 }
3811 if (address & 3)
3812 dest = ARMul_Align (state, address, dest);
3813 WRITEDESTB (dest);
3814 ARMul_Icycles (state, 1, 0L);
3815
3816 return (DESTReg != LHSReg);
3817 }
3818
3819#ifdef MODET
3820 /* This function does the work of loading a halfword. */
3821
3822 static unsigned
3823 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
3824 int signextend) {
3825 ARMword dest;
3826
3827 BUSUSEDINCPCS;
3828#ifndef MODE32
3829 if (ADDREXCEPT (address))
3830 INTERNALABORT (address);
3831#endif
3832 dest = ARMul_LoadHalfWord (state, address);
3833 if (state->Aborted) {
3834 TAKEABORT;
3835 return state->lateabtSig;
3836 }
3837 UNDEF_LSRBPC;
3838 if (signextend)
3839 if (dest & 1 << (16 - 1))
3840 dest = (dest & ((1 << 16) - 1)) - (1 << 16);
3841
3842 WRITEDEST (dest);
3843 ARMul_Icycles (state, 1, 0L);
3844
3845 return (DESTReg != LHSReg);
3846 }
3847
3848#endif /* MODET */
3849
3850 /* This function does the work of loading a byte for a LDRB instruction. */
3851
3852 static unsigned
3853 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend) {
3854 ARMword dest;
3855
3856 BUSUSEDINCPCS;
3857#ifndef MODE32
3858 if (ADDREXCEPT (address))
3859 INTERNALABORT (address);
3860#endif
3861 dest = ARMul_LoadByte (state, address);
3862 if (state->Aborted) {
3863 TAKEABORT;
3864 return state->lateabtSig;
3865 }
3866 UNDEF_LSRBPC;
3867 if (signextend)
3868 if (dest & 1 << (8 - 1))
3869 dest = (dest & ((1 << 8) - 1)) - (1 << 8);
3870
3871 WRITEDEST (dest);
3872 ARMul_Icycles (state, 1, 0L);
3873
3874 return (DESTReg != LHSReg);
3875 }
3876
3877 /* This function does the work of loading two words for a LDRD instruction. */
3878
3879 static void
3880 Handle_Load_Double (ARMul_State * state, ARMword instr) {
3881 ARMword dest_reg;
3882 ARMword addr_reg;
3883 ARMword write_back = BIT (21);
3884 ARMword immediate = BIT (22);
3885 ARMword add_to_base = BIT (23);
3886 ARMword pre_indexed = BIT (24);
3887 ARMword offset;
3888 ARMword addr;
3889 ARMword sum;
3890 ARMword base;
3891 ARMword value1;
3892 ARMword value2;
3893
3894 BUSUSEDINCPCS;
3895
3896 /* If the writeback bit is set, the pre-index bit must be clear. */
3897 if (write_back && !pre_indexed) {
3898 ARMul_UndefInstr (state, instr);
3899 return;
3900 }
3901
3902 /* Extract the base address register. */
3903 addr_reg = LHSReg;
3904
3905 /* Extract the destination register and check it. */
3906 dest_reg = DESTReg;
3907
3908 /* Destination register must be even. */
3909 if ((dest_reg & 1)
3910 /* Destination register cannot be LR. */
3911 || (dest_reg == 14)) {
3912 ARMul_UndefInstr (state, instr);
3913 return;
3914 }
3915
3916 /* Compute the base address. */
3917 base = state->Reg[addr_reg];
3918
3919 /* Compute the offset. */
3920 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
3921 Reg[RHSReg];
3922
3923 /* Compute the sum of the two. */
3924 if (add_to_base)
3925 sum = base + offset;
3926 else
3927 sum = base - offset;
3928
3929 /* If this is a pre-indexed mode use the sum. */
3930 if (pre_indexed)
3931 addr = sum;
3932 else
3933 addr = base;
3934
3935 /* The address must be aligned on a 8 byte boundary. */
3936 /*if (addr & 0x7) {
3937 #ifdef ABORTS
3938 ARMul_DATAABORT (addr);
3939 #else
3940 ARMul_UndefInstr (state, instr);
3941 #endif
3942 return;
3943 }*/
3944 /* Lets just forcibly align it for now */
3945 //addr = (addr + 7) & ~7;
3946
3947 /* For pre indexed or post indexed addressing modes,
3948 check that the destination registers do not overlap
3949 the address registers. */
3950 if ((!pre_indexed || write_back)
3951 && (addr_reg == dest_reg || addr_reg == dest_reg + 1)) {
3952 ARMul_UndefInstr (state, instr);
3953 return;
3954 }
3955
3956 /* Load the words. */
3957 value1 = ARMul_LoadWordN (state, addr);
3958 value2 = ARMul_LoadWordN (state, addr + 4);
3959
3960 /* Check for data aborts. */
3961 if (state->Aborted) {
3962 TAKEABORT;
3963 return;
3964 }
3965
3966 ARMul_Icycles (state, 2, 0L);
3967
3968 /* Store the values. */
3969 state->Reg[dest_reg] = value1;
3970 state->Reg[dest_reg + 1] = value2;
3971
3972 /* Do the post addressing and writeback. */
3973 if (!pre_indexed)
3974 addr = sum;
3975
3976 if (!pre_indexed || write_back)
3977 state->Reg[addr_reg] = addr;
3978 }
3979
3980 /* This function does the work of storing two words for a STRD instruction. */
3981
3982 static void
3983 Handle_Store_Double (ARMul_State * state, ARMword instr) {
3984 ARMword src_reg;
3985 ARMword addr_reg;
3986 ARMword write_back = BIT (21);
3987 ARMword immediate = BIT (22);
3988 ARMword add_to_base = BIT (23);
3989 ARMword pre_indexed = BIT (24);
3990 ARMword offset;
3991 ARMword addr;
3992 ARMword sum;
3993 ARMword base;
3994
3995 BUSUSEDINCPCS;
3996
3997 /* If the writeback bit is set, the pre-index bit must be clear. */
3998 if (write_back && !pre_indexed) {
3999 ARMul_UndefInstr (state, instr);
4000 return;
4001 }
4002
4003 /* Extract the base address register. */
4004 addr_reg = LHSReg;
4005
4006 /* Base register cannot be PC. */
4007 if (addr_reg == 15) {
4008 ARMul_UndefInstr (state, instr);
4009 return;
4010 }
4011
4012 /* Extract the source register. */
4013 src_reg = DESTReg;
4014
4015 /* Source register must be even. */
4016 if (src_reg & 1) {
4017 ARMul_UndefInstr (state, instr);
4018 return;
4019 }
4020
4021 /* Compute the base address. */
4022 base = state->Reg[addr_reg];
4023
4024 /* Compute the offset. */
4025 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
4026 Reg[RHSReg];
4027
4028 /* Compute the sum of the two. */
4029 if (add_to_base)
4030 sum = base + offset;
4031 else
4032 sum = base - offset;
4033
4034 /* If this is a pre-indexed mode use the sum. */
4035 if (pre_indexed)
4036 addr = sum;
4037 else
4038 addr = base;
4039
4040 /* The address must be aligned on a 8 byte boundary. */
4041 /*if (addr & 0x7) {
4042 #ifdef ABORTS
4043 ARMul_DATAABORT (addr);
4044 #else
4045 ARMul_UndefInstr (state, instr);
4046 #endif
4047 return;
4048 }*/
4049 /* Lets just forcibly align it for now */
4050 //addr = (addr + 7) & ~7;
4051
4052 /* For pre indexed or post indexed addressing modes,
4053 check that the destination registers do not overlap
4054 the address registers. */
4055 if ((!pre_indexed || write_back)
4056 && (addr_reg == src_reg || addr_reg == src_reg + 1)) {
4057 ARMul_UndefInstr (state, instr);
4058 return;
4059 }
4060
4061 /* Load the words. */
4062 ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
4063 ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
4064
4065 if (state->Aborted) {
4066 TAKEABORT;
4067 return;
4068 }
4069
4070 /* Do the post addressing and writeback. */
4071 if (!pre_indexed)
4072 addr = sum;
4073
4074 if (!pre_indexed || write_back)
4075 state->Reg[addr_reg] = addr;
4076 }
4077
4078 /* This function does the work of storing a word from a STR instruction. */
4079
4080 static unsigned
4081 StoreWord (ARMul_State * state, ARMword instr, ARMword address) {
4082 BUSUSEDINCPCN;
4083#ifndef MODE32
4084 if (DESTReg == 15)
4085 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4086#endif
4087#ifdef MODE32
4088 ARMul_StoreWordN (state, address, DEST);
4089#else
4090 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
4091 INTERNALABORT (address);
4092 (void) ARMul_LoadWordN (state, address);
4093 } else
4094 ARMul_StoreWordN (state, address, DEST);
4095#endif
4096 if (state->Aborted) {
4097 TAKEABORT;
4098 return state->lateabtSig;
4099 }
4100
4101 return TRUE;
4102 }
4103
4104#ifdef MODET
4105 /* This function does the work of storing a byte for a STRH instruction. */
4106
4107 static unsigned
4108 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address) {
4109 BUSUSEDINCPCN;
4110
4111#ifndef MODE32
4112 if (DESTReg == 15)
4113 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4114#endif
4115
4116#ifdef MODE32
4117 ARMul_StoreHalfWord (state, address, DEST);
4118#else
4119 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
4120 INTERNALABORT (address);
4121 (void) ARMul_LoadHalfWord (state, address);
4122 } else
4123 ARMul_StoreHalfWord (state, address, DEST);
4124#endif
4125
4126 if (state->Aborted) {
4127 TAKEABORT;
4128 return state->lateabtSig;
4129 }
4130 return TRUE;
4131 }
4132
4133#endif /* MODET */
4134
4135 /* This function does the work of storing a byte for a STRB instruction. */
4136
4137 static unsigned
4138 StoreByte (ARMul_State * state, ARMword instr, ARMword address) {
4139 BUSUSEDINCPCN;
4140#ifndef MODE32
4141 if (DESTReg == 15)
4142 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4143#endif
4144#ifdef MODE32
4145 ARMul_StoreByte (state, address, DEST);
4146#else
4147 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
4148 INTERNALABORT (address);
4149 (void) ARMul_LoadByte (state, address);
4150 } else
4151 ARMul_StoreByte (state, address, DEST);
4152#endif
4153 if (state->Aborted) {
4154 TAKEABORT;
4155 return state->lateabtSig;
4156 }
4157 //UNDEF_LSRBPC;
4158 return TRUE;
4159 }
4160
4161 /* This function does the work of loading the registers listed in an LDM
4162 instruction, when the S bit is clear. The code here is always increment
4163 after, it's up to the caller to get the input address correct and to
4164 handle base register modification. */
4165
4166 static void
4167 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase) {
4168 ARMword dest, temp;
4169
4170 //UNDEF_LSMNoRegs;
4171 //UNDEF_LSMPCBase;
4172 //UNDEF_LSMBaseInListWb;
4173 BUSUSEDINCPCS;
4174#ifndef MODE32
4175 if (ADDREXCEPT (address))
4176 INTERNALABORT (address);
4177#endif
4178 /*chy 2004-05-23 may write twice
4179 if (BIT (21) && LHSReg != 15)
4180 LSBase = WBBase;
4181 */
4182 /* N cycle first. */
4183 for (temp = 0; !BIT (temp); temp++);
4184
4185 dest = ARMul_LoadWordN (state, address);
4186
4187 if (!state->abortSig && !state->Aborted)
4188 state->Reg[temp++] = dest;
4189 else if (!state->Aborted) {
4190 //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4191 state->Aborted = ARMul_DataAbortV;
4192 }
4193 /*chy 2004-05-23 chy goto end*/
4194 if (state->Aborted)
4195 goto L_ldm_makeabort;
4196 /* S cycles from here on. */
4197 for (; temp < 16; temp++)
4198 if (BIT (temp)) {
4199 /* Load this register. */
4200 address += 4;
4201 dest = ARMul_LoadWordS (state, address);
4202
4203 if (!state->abortSig && !state->Aborted)
4204 state->Reg[temp] = dest;
4205 else if (!state->Aborted) {
4206 /*XScale_set_fsr_far (state,
4207 ARMul_CP15_R5_ST_ALIGN,
4208 address);*/
4209 state->Aborted = ARMul_DataAbortV;
4210 }
4211 /*chy 2004-05-23 chy goto end */
4212 if (state->Aborted)
4213 goto L_ldm_makeabort;
4214 }
4215
4216 if (BIT (15) && !state->Aborted)
4217 /* PC is in the reg list. */
4218 WriteR15Branch (state, PC);
4219
4220 /* To write back the final register. */
4221 /* ARMul_Icycles (state, 1, 0L);*/
4222 /*chy 2004-05-23, see below
4223 if (state->Aborted)
4224 {
4225 if (BIT (21) && LHSReg != 15)
4226 LSBase = WBBase;
4227
4228 TAKEABORT;
4229 }
4230 */
4231 /*chy 2004-05-23 should compare the Abort Models*/
4232L_ldm_makeabort:
4233 /* To write back the final register. */
4234 ARMul_Icycles (state, 1, 0L);
4235
4236 /* chy 2005-11-24, bug found by benjl@cse.unsw.edu.au, etc */
4237 /*
4238 if (state->Aborted)
4239 {
4240 if (BIT (21) && LHSReg != 15)
4241 if (!(state->abortSig && state->Aborted && state->lateabtSig == LOW))
4242 LSBase = WBBase;
4243 TAKEABORT;
4244 }else if (BIT (21) && LHSReg != 15)
4245 LSBase = WBBase;
4246 */
4247 if (state->Aborted) {
4248 if (BIT (21) && LHSReg != 15) {
4249 if (!(state->abortSig)) {
4250 }
4251 }
4252 TAKEABORT;
4253 } else if (BIT (21) && LHSReg != 15) {
4254 LSBase = WBBase;
4255 }
4256 /* chy 2005-11-24, over */
4257 }
4258
4259 /* This function does the work of loading the registers listed in an LDM
4260 instruction, when the S bit is set. The code here is always increment
4261 after, it's up to the caller to get the input address correct and to
4262 handle base register modification. */
4263
4264 static void
4265 LoadSMult (ARMul_State * state,
4266 ARMword instr, ARMword address, ARMword WBBase) {
4267 ARMword dest, temp;
4268
4269 //UNDEF_LSMNoRegs;
4270 //UNDEF_LSMPCBase;
4271 //UNDEF_LSMBaseInListWb;
4272
4273 BUSUSEDINCPCS;
4274
4275#ifndef MODE32
4276 if (ADDREXCEPT (address))
4277 INTERNALABORT (address);
4278#endif
4279 /* chy 2004-05-23, may write twice
4280 if (BIT (21) && LHSReg != 15)
4281 LSBase = WBBase;
4282 */
4283 if (!BIT (15) && state->Bank != USERBANK) {
4284 /* Temporary reg bank switch. */
4285 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
4286 UNDEF_LSMUserBankWb;
4287 }
4288
4289 /* N cycle first. */
4290 for (temp = 0; !BIT (temp); temp++);
4291
4292 dest = ARMul_LoadWordN (state, address);
4293
4294 if (!state->abortSig)
4295 state->Reg[temp++] = dest;
4296 else if (!state->Aborted) {
4297 //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4298 state->Aborted = ARMul_DataAbortV;
4299 }
4300
4301 /*chy 2004-05-23 chy goto end*/
4302 if (state->Aborted)
4303 goto L_ldm_s_makeabort;
4304 /* S cycles from here on. */
4305 for (; temp < 16; temp++)
4306 if (BIT (temp)) {
4307 /* Load this register. */
4308 address += 4;
4309 dest = ARMul_LoadWordS (state, address);
4310
4311 if (!state->abortSig && !state->Aborted)
4312 state->Reg[temp] = dest;
4313 else if (!state->Aborted) {
4314 /*XScale_set_fsr_far (state,
4315 ARMul_CP15_R5_ST_ALIGN,
4316 address);*/
4317 state->Aborted = ARMul_DataAbortV;
4318 }
4319 /*chy 2004-05-23 chy goto end */
4320 if (state->Aborted)
4321 goto L_ldm_s_makeabort;
4322 }
4323
4324 /*chy 2004-05-23 label of ldm_s_makeabort*/
4325L_ldm_s_makeabort:
4326 /*chy 2004-06-06 LSBase process should be here, not in the end of this function. Because ARMul_CPSRAltered maybe change R13(SP) R14(lr). If not, simulate INSTR ldmia sp!,[....pc]^ error.*/
4327 /*chy 2004-05-23 should compare the Abort Models*/
4328 if (state->Aborted) {
4329 if (BIT (21) && LHSReg != 15)
4330 if (!
4331 (state->abortSig && state->Aborted
4332 && state->lateabtSig == LOW))
4333 LSBase = WBBase;
4334 TAKEABORT;
4335 } else if (BIT (21) && LHSReg != 15)
4336 LSBase = WBBase;
4337
4338 if (BIT (15) && !state->Aborted) {
4339 /* PC is in the reg list. */
4340#ifdef MODE32
4341 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
4342 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
4343 state->Cpsr = GETSPSR (state->Bank);
4344 ARMul_CPSRAltered (state);
4345 }
4346
4347 WriteR15 (state, PC);
4348#else
4349 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
4350 if (state->Mode == USER26MODE || state->Mode == USER32MODE ) {
4351 /* Protect bits in user mode. */
4352 ASSIGNN ((state->Reg[15] & NBIT) != 0);
4353 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
4354 ASSIGNC ((state->Reg[15] & CBIT) != 0);
4355 ASSIGNV ((state->Reg[15] & VBIT) != 0);
4356 } else
4357 ARMul_R15Altered (state);
4358
4359 FLUSHPIPE;
4360#endif
4361 }
4362
4363 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
4364 if (!BIT (15) && state->Mode != USER26MODE
4365 && state->Mode != USER32MODE )
4366 /* Restore the correct bank. */
4367 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
4368
4369 /* To write back the final register. */
4370 ARMul_Icycles (state, 1, 0L);
4371 /* chy 2004-05-23, see below
4372 if (state->Aborted)
4373 {
4374 if (BIT (21) && LHSReg != 15)
4375 LSBase = WBBase;
4376
4377 TAKEABORT;
4378 }
4379 */
4380 }
4381
4382 /* This function does the work of storing the registers listed in an STM
4383 instruction, when the S bit is clear. The code here is always increment
4384 after, it's up to the caller to get the input address correct and to
4385 handle base register modification. */
4386
4387 static void
4388 StoreMult (ARMul_State * state,
4389 ARMword instr, ARMword address, ARMword WBBase) {
4390 ARMword temp;
4391
4392 UNDEF_LSMNoRegs;
4393 UNDEF_LSMPCBase;
4394 UNDEF_LSMBaseInListWb;
4395
4396 if (!TFLAG)
4397 /* N-cycle, increment the PC and update the NextInstr state. */
4398 BUSUSEDINCPCN;
4399
4400#ifndef MODE32
4401 if (VECTORACCESS (address) || ADDREXCEPT (address))
4402 INTERNALABORT (address);
4403
4404 if (BIT (15))
4405 PATCHR15;
4406#endif
4407
4408 /* N cycle first. */
4409 for (temp = 0; !BIT (temp); temp++);
4410
4411#ifdef MODE32
4412 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4413#else
4414 if (state->Aborted) {
4415 (void) ARMul_LoadWordN (state, address);
4416
4417 /* Fake the Stores as Loads. */
4418 for (; temp < 16; temp++)
4419 if (BIT (temp)) {
4420 /* Save this register. */
4421 address += 4;
4422 (void) ARMul_LoadWordS (state, address);
4423 }
4424
4425 if (BIT (21) && LHSReg != 15)
4426 LSBase = WBBase;
4427 TAKEABORT;
4428 return;
4429 } else
4430 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4431#endif
4432
4433 if (state->abortSig && !state->Aborted) {
4434 //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4435 state->Aborted = ARMul_DataAbortV;
4436 }
4437
4438//chy 2004-05-23, needn't store other when aborted
4439 if (state->Aborted)
4440 goto L_stm_takeabort;
4441
4442 /* S cycles from here on. */
4443 for (; temp < 16; temp++)
4444 if (BIT (temp)) {
4445 /* Save this register. */
4446 address += 4;
4447
4448 ARMul_StoreWordS (state, address, state->Reg[temp]);
4449
4450 if (state->abortSig && !state->Aborted) {
4451 /*XScale_set_fsr_far (state,
4452 ARMul_CP15_R5_ST_ALIGN,
4453 address);*/
4454 state->Aborted = ARMul_DataAbortV;
4455 }
4456 //chy 2004-05-23, needn't store other when aborted
4457 if (state->Aborted)
4458 goto L_stm_takeabort;
4459 }
4460
4461//chy 2004-05-23,should compare the Abort Models
4462L_stm_takeabort:
4463 if (BIT (21) && LHSReg != 15) {
4464 if (!
4465 (state->abortSig && state->Aborted
4466 && state->lateabtSig == LOW))
4467 LSBase = WBBase;
4468 }
4469 if (state->Aborted)
4470 TAKEABORT;
4471 }
4472
4473 /* This function does the work of storing the registers listed in an STM
4474 instruction when the S bit is set. The code here is always increment
4475 after, it's up to the caller to get the input address correct and to
4476 handle base register modification. */
4477
4478 static void
4479 StoreSMult (ARMul_State * state,
4480 ARMword instr, ARMword address, ARMword WBBase) {
4481 ARMword temp;
4482
4483 UNDEF_LSMNoRegs;
4484 UNDEF_LSMPCBase;
4485 UNDEF_LSMBaseInListWb;
4486
4487 BUSUSEDINCPCN;
4488
4489#ifndef MODE32
4490 if (VECTORACCESS (address) || ADDREXCEPT (address))
4491 INTERNALABORT (address);
4492
4493 if (BIT (15))
4494 PATCHR15;
4495#endif
4496
4497 if (state->Bank != USERBANK) {
4498 /* Force User Bank. */
4499 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
4500 UNDEF_LSMUserBankWb;
4501 }
4502
4503 for (temp = 0; !BIT (temp); temp++); /* N cycle first. */
4504
4505#ifdef MODE32
4506 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4507#else
4508 if (state->Aborted) {
4509 (void) ARMul_LoadWordN (state, address);
4510
4511 for (; temp < 16; temp++)
4512 /* Fake the Stores as Loads. */
4513 if (BIT (temp)) {
4514 /* Save this register. */
4515 address += 4;
4516
4517 (void) ARMul_LoadWordS (state, address);
4518 }
4519
4520 if (BIT (21) && LHSReg != 15)
4521 LSBase = WBBase;
4522
4523 TAKEABORT;
4524 return;
4525 } else
4526 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4527#endif
4528
4529 if (state->abortSig && !state->Aborted) {
4530 //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4531 state->Aborted = ARMul_DataAbortV;
4532 }
4533
4534//chy 2004-05-23, needn't store other when aborted
4535 if (state->Aborted)
4536 goto L_stm_s_takeabort;
4537 /* S cycles from here on. */
4538 for (; temp < 16; temp++)
4539 if (BIT (temp)) {
4540 /* Save this register. */
4541 address += 4;
4542
4543 ARMul_StoreWordS (state, address, state->Reg[temp]);
4544
4545 if (state->abortSig && !state->Aborted) {
4546 /*XScale_set_fsr_far (state,
4547 ARMul_CP15_R5_ST_ALIGN,
4548 address);*/
4549 state->Aborted = ARMul_DataAbortV;
4550 }
4551 //chy 2004-05-23, needn't store other when aborted
4552 if (state->Aborted)
4553 goto L_stm_s_takeabort;
4554 }
4555
4556 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
4557 if (state->Mode != USER26MODE && state->Mode != USER32MODE )
4558 /* Restore the correct bank. */
4559 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
4560
4561//chy 2004-05-23,should compare the Abort Models
4562L_stm_s_takeabort:
4563 if (BIT (21) && LHSReg != 15) {
4564 if (!
4565 (state->abortSig && state->Aborted
4566 && state->lateabtSig == LOW))
4567 LSBase = WBBase;
4568 }
4569
4570 if (state->Aborted)
4571 TAKEABORT;
4572 }
4573
4574 /* This function does the work of adding two 32bit values
4575 together, and calculating if a carry has occurred. */
4576
4577 static ARMword
4578 Add32 (ARMword a1, ARMword a2, int *carry) {
4579 ARMword result = (a1 + a2);
4580 unsigned int uresult = (unsigned int) result;
4581 unsigned int ua1 = (unsigned int) a1;
4582
4583 /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
4584 or (result > RdLo) then we have no carry. */
4585 if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
4586 *carry = 1;
4587 else
4588 *carry = 0;
4589
4590 return result;
4591 }
4592
4593 /* This function does the work of multiplying
4594 two 32bit values to give a 64bit result. */
4595
4596 static unsigned
4597 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc) {
4598 /* Operand register numbers. */
4599 int nRdHi, nRdLo, nRs, nRm;
4600 ARMword RdHi = 0, RdLo = 0, Rm;
4601 /* Cycle count. */
4602 int scount;
4603
4604 nRdHi = BITS (16, 19);
4605 nRdLo = BITS (12, 15);
4606 nRs = BITS (8, 11);
4607 nRm = BITS (0, 3);
4608
4609 /* Needed to calculate the cycle count. */
4610 Rm = state->Reg[nRm];
4611
4612 /* Check for illegal operand combinations first. */
4613 if (nRdHi != 15
4614 && nRdLo != 15
4615 && nRs != 15
4616 //&& nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm) {
4617 && nRm != 15 && nRdHi != nRdLo ) {
4618 /* Intermediate results. */
4619 ARMword lo, mid1, mid2, hi;
4620 int carry;
4621 ARMword Rs = state->Reg[nRs];
4622 int sign = 0;
4623
4624 if (msigned) {
4625 /* Compute sign of result and adjust operands if necessary. */
4626 sign = (Rm ^ Rs) & 0x80000000;
4627
4628 if (((signed int) Rm) < 0)
4629 Rm = -Rm;
4630
4631 if (((signed int) Rs) < 0)
4632 Rs = -Rs;
4633 }
4634
4635 /* We can split the 32x32 into four 16x16 operations. This
4636 ensures that we do not lose precision on 32bit only hosts. */
4637 lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
4638 mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
4639 mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
4640 hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
4641
4642 /* We now need to add all of these results together, taking
4643 care to propogate the carries from the additions. */
4644 RdLo = Add32 (lo, (mid1 << 16), &carry);
4645 RdHi = carry;
4646 RdLo = Add32 (RdLo, (mid2 << 16), &carry);
4647 RdHi += (carry + ((mid1 >> 16) & 0xFFFF) +
4648 ((mid2 >> 16) & 0xFFFF) + hi);
4649
4650 if (sign) {
4651 /* Negate result if necessary. */
4652 RdLo = ~RdLo;
4653 RdHi = ~RdHi;
4654 if (RdLo == 0xFFFFFFFF) {
4655 RdLo = 0;
4656 RdHi += 1;
4657 } else
4658 RdLo += 1;
4659 }
4660
4661 state->Reg[nRdLo] = RdLo;
4662 state->Reg[nRdHi] = RdHi;
4663 } else {
4664 fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS, instr=0x%x\n", instr);
4665 }
4666 if (scc)
4667 /* Ensure that both RdHi and RdLo are used to compute Z,
4668 but don't let RdLo's sign bit make it to N. */
4669 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
4670
4671 /* The cycle count depends on whether the instruction is a signed or
4672 unsigned multiply, and what bits are clear in the multiplier. */
4673 if (msigned && (Rm & ((unsigned) 1 << 31)))
4674 /* Invert the bits to make the check against zero. */
4675 Rm = ~Rm;
4676
4677 if ((Rm & 0xFFFFFF00) == 0)
4678 scount = 1;
4679 else if ((Rm & 0xFFFF0000) == 0)
4680 scount = 2;
4681 else if ((Rm & 0xFF000000) == 0)
4682 scount = 3;
4683 else
4684 scount = 4;
4685
4686 return 2 + scount;
4687 }
4688
4689 /* This function does the work of multiplying two 32bit
4690 values and adding a 64bit value to give a 64bit result. */
4691
4692 static unsigned
4693 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc) {
4694 unsigned scount;
4695 ARMword RdLo, RdHi;
4696 int nRdHi, nRdLo;
4697 int carry = 0;
4698
4699 nRdHi = BITS (16, 19);
4700 nRdLo = BITS (12, 15);
4701
4702 RdHi = state->Reg[nRdHi];
4703 RdLo = state->Reg[nRdLo];
4704
4705 scount = Multiply64 (state, instr, msigned, LDEFAULT);
4706
4707 RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
4708 RdHi = (RdHi + state->Reg[nRdHi]) + carry;
4709
4710 state->Reg[nRdLo] = RdLo;
4711 state->Reg[nRdHi] = RdHi;
4712
4713 if (scc)
4714 /* Ensure that both RdHi and RdLo are used to compute Z,
4715 but don't let RdLo's sign bit make it to N. */
4716 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
4717
4718 /* Extra cycle for addition. */
4719 return scount + 1;
4720 }
4721
4722 /* Attempt to emulate an ARMv6 instruction.
4723 Returns non-zero upon success. */
4724
4725 static int handle_v6_insn(ARMul_State* state, ARMword instr) {
4726 switch (BITS(20, 27)) {
4727 case 0x03:
4728 printf ("Unhandled v6 insn: ldr\n");
4729 break;
4730 case 0x04: // UMAAL
4731 {
4732 const u8 rm_idx = BITS(8, 11);
4733 const u8 rn_idx = BITS(0, 3);
4734 const u8 rd_lo_idx = BITS(12, 15);
4735 const u8 rd_hi_idx = BITS(16, 19);
4736
4737 const u32 rm_val = state->Reg[rm_idx];
4738 const u32 rn_val = state->Reg[rn_idx];
4739 const u32 rd_lo_val = state->Reg[rd_lo_idx];
4740 const u32 rd_hi_val = state->Reg[rd_hi_idx];
4741
4742 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
4743
4744 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
4745 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
4746 return 1;
4747 }
4748 break;
4749 case 0x06:
4750 printf ("Unhandled v6 insn: mls/str\n");
4751 break;
4752 case 0x16:
4753 printf ("Unhandled v6 insn: smi\n");
4754 break;
4755 case 0x18:
4756 if (BITS(4, 7) == 0x9) {
4757 /* strex */
4758 u32 l = LHSReg;
4759 u32 r = RHSReg;
4760 u32 lhs = LHS;
4761
4762 bool enter = false;
4763
4764 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
4765 //StoreWord(state, lhs, RHS)
4766 if (state->Aborted) {
4767 TAKEABORT;
4768 }
4769
4770 if (enter) {
4771 ARMul_StoreWordS(state, lhs, RHS);
4772 state->Reg[DESTReg] = 0;
4773 }
4774 else {
4775 state->Reg[DESTReg] = 1;
4776 }
4777
4778 return 1;
4779 }
4780 printf ("Unhandled v6 insn: strex\n");
4781 break;
4782 case 0x19:
4783 /* ldrex */
4784 if (BITS(4, 7) == 0x9) {
4785 u32 lhs = LHS;
4786
4787 state->currentexaddr = lhs;
4788 state->currentexval = ARMul_ReadWord(state, lhs);
4789
4790 LoadWord(state, instr, lhs);
4791 return 1;
4792 }
4793 printf ("Unhandled v6 insn: ldrex\n");
4794 break;
4795 case 0x1a:
4796 printf ("Unhandled v6 insn: strexd\n");
4797 break;
4798 case 0x1b:
4799 printf ("Unhandled v6 insn: ldrexd\n");
4800 break;
4801 case 0x1c:
4802 if (BITS(4, 7) == 0x9) {
4803 /* strexb */
4804 u32 lhs = LHS;
4805
4806 bool enter = false;
4807
4808 if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
4809
4810 BUSUSEDINCPCN;
4811 if (state->Aborted) {
4812 TAKEABORT;
4813 }
4814
4815 if (enter) {
4816 ARMul_StoreByte(state, lhs, RHS);
4817 state->Reg[DESTReg] = 0;
4818 }
4819 else {
4820 state->Reg[DESTReg] = 1;
4821 }
4822
4823 //printf("In %s, strexb not implemented\n", __FUNCTION__);
4824 UNDEF_LSRBPC;
4825 /* WRITESDEST (dest); */
4826 return 1;
4827 }
4828 printf ("Unhandled v6 insn: strexb\n");
4829 break;
4830 case 0x1d:
4831 if ((BITS(4, 7)) == 0x9) {
4832 /* ldrexb */
4833 u32 lhs = LHS;
4834 LoadByte(state, instr, lhs, LUNSIGNED);
4835
4836 state->currentexaddr = lhs;
4837 state->currentexval = (u32)ARMul_ReadByte(state, lhs);
4838
4839 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
4840 //printf("ldrexb\n");
4841 //printf("instr is %x rm is %d\n", instr, BITS(16, 19));
4842 //exit(-1);
4843
4844 //printf("In %s, ldrexb not implemented\n", __FUNCTION__);
4845 return 1;
4846 }
4847 printf ("Unhandled v6 insn: ldrexb\n");
4848 break;
4849 case 0x1e:
4850 printf ("Unhandled v6 insn: strexh\n");
4851 break;
4852 case 0x1f:
4853 printf ("Unhandled v6 insn: ldrexh\n");
4854 break;
4855 case 0x30:
4856 printf ("Unhandled v6 insn: movw\n");
4857 break;
4858 case 0x32:
4859 printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n");
4860 break;
4861 case 0x34:
4862 printf ("Unhandled v6 insn: movt\n");
4863 break;
4864 case 0x3f:
4865 printf ("Unhandled v6 insn: rbit\n");
4866 break;
4867 case 0x61: // SADD16, SASX, SSAX, and SSUB16
4868 if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
4869 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
4870 {
4871 const u8 rd_idx = BITS(12, 15);
4872 const u8 rm_idx = BITS(0, 3);
4873 const u8 rn_idx = BITS(16, 19);
4874 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
4875 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
4876 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
4877 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
4878
4879 s32 lo_result;
4880 s32 hi_result;
4881
4882 // SADD16
4883 if ((instr & 0xFF0) == 0xf10) {
4884 lo_result = (rn_lo + rm_lo);
4885 hi_result = (rn_hi + rm_hi);
4886 }
4887 // SASX
4888 else if ((instr & 0xFF0) == 0xf30) {
4889 lo_result = (rn_lo - rm_hi);
4890 hi_result = (rn_hi + rm_lo);
4891 }
4892 // SSAX
4893 else if ((instr & 0xFF0) == 0xf50) {
4894 lo_result = (rn_lo + rm_hi);
4895 hi_result = (rn_hi - rm_lo);
4896 }
4897 // SSUB16
4898 else {
4899 lo_result = (rn_lo - rm_lo);
4900 hi_result = (rn_hi - rm_hi);
4901 }
4902
4903 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
4904
4905 if (lo_result >= 0) {
4906 state->GEFlag |= (1 << 16);
4907 state->GEFlag |= (1 << 17);
4908 } else {
4909 state->GEFlag &= ~(1 << 16);
4910 state->GEFlag &= ~(1 << 17);
4911 }
4912
4913 if (hi_result >= 0) {
4914 state->GEFlag |= (1 << 18);
4915 state->GEFlag |= (1 << 19);
4916 } else {
4917 state->GEFlag &= ~(1 << 18);
4918 state->GEFlag &= ~(1 << 19);
4919 }
4920
4921 return 1;
4922 }
4923 // SADD8/SSUB8
4924 else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0)
4925 {
4926 const u8 rd_idx = BITS(12, 15);
4927 const u8 rm_idx = BITS(0, 3);
4928 const u8 rn_idx = BITS(16, 19);
4929 const u32 rm_val = state->Reg[rm_idx];
4930 const u32 rn_val = state->Reg[rn_idx];
4931
4932 s32 lo_val1, lo_val2;
4933 s32 hi_val1, hi_val2;
4934
4935 // SADD8
4936 if ((instr & 0xFF0) == 0xf90) {
4937 lo_val1 = (s32)(s8)(rn_val & 0xFF) + (s32)(s8)(rm_val & 0xFF);
4938 lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) + (s32)(s8)((rm_val >> 8) & 0xFF);
4939 hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) + (s32)(s8)((rm_val >> 16) & 0xFF);
4940 hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) + (s32)(s8)((rm_val >> 24) & 0xFF);
4941 }
4942 // SSUB8
4943 else {
4944 lo_val1 = (s32)(s8)(rn_val & 0xFF) - (s32)(s8)(rm_val & 0xFF);
4945 lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) - (s32)(s8)((rm_val >> 8) & 0xFF);
4946 hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) - (s32)(s8)((rm_val >> 16) & 0xFF);
4947 hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) - (s32)(s8)((rm_val >> 24) & 0xFF);
4948 }
4949
4950 if (lo_val1 >= 0)
4951 state->GEFlag |= (1 << 16);
4952 else
4953 state->GEFlag &= ~(1 << 16);
4954
4955 if (lo_val2 >= 0)
4956 state->GEFlag |= (1 << 17);
4957 else
4958 state->GEFlag &= ~(1 << 17);
4959
4960 if (hi_val1 >= 0)
4961 state->GEFlag |= (1 << 18);
4962 else
4963 state->GEFlag &= ~(1 << 18);
4964
4965 if (hi_val2 >= 0)
4966 state->GEFlag |= (1 << 19);
4967 else
4968 state->GEFlag &= ~(1 << 19);
4969
4970 state->Reg[rd_idx] = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
4971 return 1;
4972 }
4973 else {
4974 printf("Unhandled v6 insn: %08x", instr);
4975 }
4976 break;
4977 case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8
4978 {
4979 const u8 op2 = BITS(5, 7);
4980
4981 const u8 rd_idx = BITS(12, 15);
4982 const u8 rn_idx = BITS(16, 19);
4983 const u8 rm_idx = BITS(0, 3);
4984 const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
4985 const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
4986 const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
4987 const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
4988
4989 u16 lo_result = 0;
4990 u16 hi_result = 0;
4991
4992 // QADD16
4993 if (op2 == 0x00) {
4994 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
4995 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
4996 }
4997 // QASX
4998 else if (op2 == 0x01) {
4999 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5000 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5001 }
5002 // QSAX
5003 else if (op2 == 0x02) {
5004 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5005 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5006 }
5007 // QSUB16
5008 else if (op2 == 0x03) {
5009 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5010 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5011 }
5012 // QADD8
5013 else if (op2 == 0x04) {
5014 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5015 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5016 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5017 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5018 }
5019 // QSUB8
5020 else if (op2 == 0x07) {
5021 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5022 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5023 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5024 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5025 }
5026
5027 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5028 return 1;
5029 }
5030 break;
5031 case 0x63:
5032 printf ("Unhandled v6 insn: shadd/shsub\n");
5033 break;
5034 case 0x65:
5035 {
5036 u32 rd = (instr >> 12) & 0xF;
5037 u32 rn = (instr >> 16) & 0xF;
5038 u32 rm = (instr >> 0) & 0xF;
5039 u32 from = state->Reg[rn];
5040 u32 to = state->Reg[rm];
5041
5042 if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16
5043 u32 h1, h2;
5044 state->Cpsr &= 0xfff0ffff;
5045 if ((instr & 0x0F0) == 0x070) { // USUB16
5046 h1 = ((u16)from - (u16)to);
5047 h2 = ((u16)(from >> 16) - (u16)(to >> 16));
5048
5049 if (!(h1 & 0xffff0000))
5050 state->GEFlag |= (3 << 16);
5051 else
5052 state->GEFlag &= ~(3 << 16);
5053
5054 if (!(h2 & 0xffff0000))
5055 state->GEFlag |= (3 << 18);
5056 else
5057 state->GEFlag &= ~(3 << 18);
5058 }
5059 else { // UADD16
5060 h1 = ((u16)from + (u16)to);
5061 h2 = ((u16)(from >> 16) + (u16)(to >> 16));
5062
5063 if (h1 & 0xffff0000)
5064 state->GEFlag |= (3 << 16);
5065 else
5066 state->GEFlag &= ~(3 << 16);
5067
5068 if (h2 & 0xffff0000)
5069 state->GEFlag |= (3 << 18);
5070 else
5071 state->GEFlag &= ~(3 << 18);
5072 }
5073
5074 state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
5075 return 1;
5076 }
5077 else
5078 if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8
5079 u32 b1, b2, b3, b4;
5080 state->Cpsr &= 0xfff0ffff;
5081 if ((instr & 0x0F0) == 0x0F0) { // USUB8
5082 b1 = ((u8)from - (u8)to);
5083 b2 = ((u8)(from >> 8) - (u8)(to >> 8));
5084 b3 = ((u8)(from >> 16) - (u8)(to >> 16));
5085 b4 = ((u8)(from >> 24) - (u8)(to >> 24));
5086
5087 if (!(b1 & 0xffffff00))
5088 state->GEFlag |= (1 << 16);
5089 else
5090 state->GEFlag &= ~(1 << 16);
5091
5092 if (!(b2 & 0xffffff00))
5093 state->GEFlag |= (1 << 17);
5094 else
5095 state->GEFlag &= ~(1 << 17);
5096
5097 if (!(b3 & 0xffffff00))
5098 state->GEFlag |= (1 << 18);
5099 else
5100 state->GEFlag &= ~(1 << 18);
5101
5102 if (!(b4 & 0xffffff00))
5103 state->GEFlag |= (1 << 19);
5104 else
5105 state->GEFlag &= ~(1 << 19);
5106 }
5107 else { // UADD8
5108 b1 = ((u8)from + (u8)to);
5109 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
5110 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
5111 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5112
5113 if (b1 & 0xffffff00)
5114 state->GEFlag |= (1 << 16);
5115 else
5116 state->GEFlag &= ~(1 << 16);
5117
5118 if (b2 & 0xffffff00)
5119 state->GEFlag |= (1 << 17);
5120 else
5121 state->GEFlag &= ~(1 << 17);
5122
5123 if (b3 & 0xffffff00)
5124 state->GEFlag |= (1 << 18);
5125 else
5126 state->GEFlag &= ~(1 << 18);
5127
5128 if (b4 & 0xffffff00)
5129 state->GEFlag |= (1 << 19);
5130 else
5131 state->GEFlag &= ~(1 << 19);
5132 }
5133
5134 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5135 return 1;
5136 }
5137 }
5138 printf("Unhandled v6 insn: uasx/usax\n");
5139 break;
5140 case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
5141 {
5142 const u8 rd_idx = BITS(12, 15);
5143 const u8 rm_idx = BITS(0, 3);
5144 const u8 rn_idx = BITS(16, 19);
5145 const u8 op2 = BITS(5, 7);
5146 const u32 rm_val = state->Reg[rm_idx];
5147 const u32 rn_val = state->Reg[rn_idx];
5148
5149 u16 lo_val = 0;
5150 u16 hi_val = 0;
5151
5152 // UQADD16
5153 if (op2 == 0x00) {
5154 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
5155 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
5156 }
5157 // UQASX
5158 else if (op2 == 0x01) {
5159 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
5160 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
5161 }
5162 // UQSAX
5163 else if (op2 == 0x02) {
5164 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
5165 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
5166 }
5167 // UQSUB16
5168 else if (op2 == 0x03) {
5169 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
5170 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
5171 }
5172 // UQADD8
5173 else if (op2 == 0x04) {
5174 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
5175 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
5176 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
5177 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
5178 }
5179 // UQSUB8
5180 else {
5181 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
5182 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
5183 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
5184 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
5185 }
5186
5187 state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
5188 return 1;
5189 }
5190 break;
5191 case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
5192 {
5193 const u8 op2 = BITS(5, 7);
5194
5195 const u8 rm_idx = BITS(0, 3);
5196 const u8 rn_idx = BITS(16, 19);
5197 const u8 rd_idx = BITS(12, 15);
5198
5199 const u32 rm_val = state->Reg[rm_idx];
5200 const u32 rn_val = state->Reg[rn_idx];
5201
5202 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
5203 {
5204 u32 lo_val = 0;
5205 u32 hi_val = 0;
5206
5207 // UHADD16
5208 if (op2 == 0x00) {
5209 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
5210 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
5211 }
5212 // UHASX
5213 else if (op2 == 0x01) {
5214 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
5215 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
5216 }
5217 // UHSAX
5218 else if (op2 == 0x02) {
5219 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
5220 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
5221 }
5222 // UHSUB16
5223 else if (op2 == 0x03) {
5224 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
5225 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
5226 }
5227
5228 lo_val >>= 1;
5229 hi_val >>= 1;
5230
5231 state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
5232 return 1;
5233 }
5234 else if (op2 == 0x04 || op2 == 0x07) {
5235 u32 sum1;
5236 u32 sum2;
5237 u32 sum3;
5238 u32 sum4;
5239
5240 // UHADD8
5241 if (op2 == 0x04) {
5242 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
5243 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
5244 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
5245 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
5246 }
5247 // UHSUB8
5248 else {
5249 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
5250 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
5251 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
5252 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
5253 }
5254
5255 sum1 >>= 1;
5256 sum2 >>= 1;
5257 sum3 >>= 1;
5258 sum4 >>= 1;
5259
5260 state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
5261 return 1;
5262 }
5263 }
5264 break;
5265 case 0x68:
5266 {
5267 u32 rd = (instr >> 12) & 0xF;
5268 u32 rn = (instr >> 16) & 0xF;
5269 u32 rm = (instr >> 0) & 0xF;
5270 u32 from = state->Reg[rn];
5271 u32 to = state->Reg[rm];
5272 u32 cpsr = ARMul_GetCPSR(state);
5273 if ((instr & 0xFF0) == 0xFB0) { // SEL
5274 u32 result;
5275 if (cpsr & (1 << 16))
5276 result = from & 0xff;
5277 else
5278 result = to & 0xff;
5279 if (cpsr & (1 << 17))
5280 result |= from & 0x0000ff00;
5281 else
5282 result |= to & 0x0000ff00;
5283 if (cpsr & (1 << 18))
5284 result |= from & 0x00ff0000;
5285 else
5286 result |= to & 0x00ff0000;
5287 if (cpsr & (1 << 19))
5288 result |= from & 0xff000000;
5289 else
5290 result |= to & 0xff000000;
5291 state->Reg[rd] = result;
5292 return 1;
5293 }
5294 }
5295 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
5296 break;
5297
5298 case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
5299 {
5300 const u8 op2 = BITS(5, 7);
5301
5302 // SSAT16
5303 if (op2 == 0x01) {
5304 const u8 rd_idx = BITS(12, 15);
5305 const u8 rn_idx = BITS(0, 3);
5306 const u8 num_bits = BITS(16, 19) + 1;
5307 const s16 min = -(0x8000 >> (16 - num_bits));
5308 const s16 max = (0x7FFF >> (16 - num_bits));
5309 s16 rn_lo = (state->Reg[rn_idx]);
5310 s16 rn_hi = (state->Reg[rn_idx] >> 16);
5311
5312 if (rn_lo > max) {
5313 rn_lo = max;
5314 SETQ;
5315 } else if (rn_lo < min) {
5316 rn_lo = min;
5317 SETQ;
5318 }
5319
5320 if (rn_hi > max) {
5321 rn_hi = max;
5322 SETQ;
5323 } else if (rn_hi < min) {
5324 rn_hi = min;
5325 SETQ;
5326 }
5327
5328 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
5329 return 1;
5330 }
5331 else if (op2 == 0x03) {
5332 const u8 rotation = BITS(10, 11) * 8;
5333 u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
5334 if (rm & 0x80)
5335 rm |= 0xffffff00;
5336
5337 // SXTB, otherwise SXTAB
5338 if (BITS(16, 19) == 0xf)
5339 state->Reg[BITS(12, 15)] = rm;
5340 else
5341 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
5342
5343 return 1;
5344 }
5345 else {
5346 printf("Unimplemented op: SSAT");
5347 }
5348 }
5349 break;
5350
5351 case 0x6b: // REV, REV16, SXTH, and SXTAH
5352 {
5353 const u8 op2 = BITS(5, 7);
5354
5355 // REV
5356 if (op2 == 0x01) {
5357 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
5358 return 1;
5359 }
5360 // REV16
5361 else if (op2 == 0x05) {
5362 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
5363 return 1;
5364 }
5365 else if (op2 == 0x03) {
5366 const u8 rotate = BITS(10, 11) * 8;
5367
5368 u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
5369 if (rm & 0x8000)
5370 rm |= 0xffff0000;
5371
5372 // SXTH, otherwise SXTAH
5373 if (BITS(16, 19) == 15)
5374 state->Reg[BITS(12, 15)] = rm;
5375 else
5376 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
5377
5378 return 1;
5379 }
5380 }
5381 break;
5382
5383 case 0x6c: // UXTB16 and UXTAB16
5384 {
5385 const u8 rm_idx = BITS(0, 3);
5386 const u8 rn_idx = BITS(16, 19);
5387 const u8 rd_idx = BITS(12, 15);
5388 const u32 rm_val = state->Reg[rm_idx];
5389 const u32 rn_val = state->Reg[rn_idx];
5390 const u32 rotation = BITS(10, 11) * 8;
5391 const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
5392
5393 // UXTB16
5394 if ((instr & 0xf03f0) == 0xf0070) {
5395 state->Reg[rd_idx] = rotated_rm & 0x00FF00FF;
5396 }
5397 else { // UXTAB16
5398 const u8 lo_rotated = (rotated_rm & 0xFF);
5399 const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
5400
5401 const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
5402 const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
5403
5404 state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF));
5405 }
5406
5407 return 1;
5408 }
5409 break;
5410 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
5411 {
5412 const u8 op2 = BITS(5, 7);
5413
5414 // USAT16
5415 if (op2 == 0x01) {
5416 const u8 rd_idx = BITS(12, 15);
5417 const u8 rn_idx = BITS(0, 3);
5418 const u8 num_bits = BITS(16, 19);
5419 const s16 max = 0xFFFF >> (16 - num_bits);
5420 s16 rn_lo = (state->Reg[rn_idx]);
5421 s16 rn_hi = (state->Reg[rn_idx] >> 16);
5422
5423 if (max < rn_lo) {
5424 rn_lo = max;
5425 SETQ;
5426 } else if (rn_lo < 0) {
5427 rn_lo = 0;
5428 SETQ;
5429 }
5430
5431 if (max < rn_hi) {
5432 rn_hi = max;
5433 SETQ;
5434 } else if (rn_hi < 0) {
5435 rn_hi = 0;
5436 SETQ;
5437 }
5438
5439 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
5440 return 1;
5441 }
5442 else if (op2 == 0x03) {
5443 const u8 rotate = BITS(10, 11) * 8;
5444 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
5445
5446 if (BITS(16, 19) == 0xf)
5447 /* UXTB */
5448 state->Reg[BITS(12, 15)] = rm;
5449 else
5450 /* UXTAB */
5451 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
5452
5453 return 1;
5454 }
5455 else {
5456 printf("Unimplemented op: USAT");
5457 }
5458 }
5459 break;
5460
5461 case 0x6f: // UXTH, UXTAH, and REVSH.
5462 {
5463 const u8 op2 = BITS(5, 7);
5464
5465 // REVSH
5466 if (op2 == 0x05) {
5467 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
5468 if (DEST & 0x8000)
5469 DEST |= 0xffff0000;
5470 return 1;
5471 }
5472 // UXTH and UXTAH
5473 else if (op2 == 0x03) {
5474 const u8 rotate = BITS(10, 11) * 8;
5475 const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
5476
5477 // UXTH
5478 if (BITS(16, 19) == 0xf) {
5479 state->Reg[BITS(12, 15)] = rm;
5480 }
5481 // UXTAH
5482 else {
5483 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
5484 }
5485
5486 return 1;
5487 }
5488 }
5489 case 0x70:
5490 // ichfly
5491 // SMUAD, SMUSD, SMLAD, and SMLSD
5492 if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 ||
5493 (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50)
5494 {
5495 const u8 rd_idx = BITS(16, 19);
5496 const u8 rn_idx = BITS(0, 3);
5497 const u8 rm_idx = BITS(8, 11);
5498 const u8 ra_idx = BITS(12, 15);
5499 const bool do_swap = (BIT(5) == 1);
5500
5501 u32 rm_val = state->Reg[rm_idx];
5502 const u32 rn_val = state->Reg[rn_idx];
5503
5504 if (do_swap)
5505 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5506
5507 const s16 rm_lo = (rm_val & 0xFFFF);
5508 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
5509 const s16 rn_lo = (rn_val & 0xFFFF);
5510 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
5511
5512 const u32 product1 = (rn_lo * rm_lo);
5513 const u32 product2 = (rn_hi * rm_hi);
5514
5515 // SMUAD and SMLAD
5516 if (BIT(6) == 0) {
5517 state->Reg[rd_idx] = product1 + product2;
5518
5519 if (BITS(12, 15) != 15) {
5520 state->Reg[rd_idx] += state->Reg[ra_idx];
5521 if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx]))
5522 SETQ;
5523 }
5524
5525 if (ARMul_AddOverflowQ(product1, product2))
5526 SETQ;
5527 }
5528 // SMUSD and SMLSD
5529 else {
5530 state->Reg[rd_idx] = product1 - product2;
5531
5532 if (BITS(12, 15) != 15) {
5533 state->Reg[rd_idx] += state->Reg[ra_idx];
5534
5535 if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx]))
5536 SETQ;
5537 }
5538 }
5539
5540 return 1;
5541 }
5542 break;
5543 case 0x74: // SMLALD and SMLSLD
5544 {
5545 const u8 rm_idx = BITS(8, 11);
5546 const u8 rn_idx = BITS(0, 3);
5547 const u8 rdlo_idx = BITS(12, 15);
5548 const u8 rdhi_idx = BITS(16, 19);
5549 const bool do_swap = (BIT(5) == 1);
5550
5551 const u32 rdlo_val = state->Reg[rdlo_idx];
5552 const u32 rdhi_val = state->Reg[rdhi_idx];
5553 const u32 rn_val = state->Reg[rn_idx];
5554 u32 rm_val = state->Reg[rm_idx];
5555
5556 if (do_swap)
5557 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5558
5559 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
5560 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
5561 s64 result;
5562
5563 // SMLALD
5564 if (BIT(6) == 0) {
5565 result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
5566 }
5567 // SMLSLD
5568 else {
5569 result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
5570 }
5571
5572 state->Reg[rdlo_idx] = (result & 0xFFFFFFFF);
5573 state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF);
5574 return 1;
5575 }
5576 break;
5577 case 0x75: // SMMLA, SMMUL, and SMMLS
5578 {
5579 const u8 rm_idx = BITS(8, 11);
5580 const u8 rn_idx = BITS(0, 3);
5581 const u8 ra_idx = BITS(12, 15);
5582 const u8 rd_idx = BITS(16, 19);
5583 const bool do_round = (BIT(5) == 1);
5584
5585 const u32 rm_val = state->Reg[rm_idx];
5586 const u32 rn_val = state->Reg[rn_idx];
5587
5588 // Assume SMMUL by default.
5589 s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
5590
5591 if (ra_idx != 15) {
5592 const u32 ra_val = state->Reg[ra_idx];
5593
5594 // SMMLA, otherwise SMMLS
5595 if (BIT(6) == 0)
5596 result += ((s64)ra_val << 32);
5597 else
5598 result = ((s64)ra_val << 32) - result;
5599 }
5600
5601 if (do_round)
5602 result += 0x80000000;
5603
5604 state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
5605 return 1;
5606 }
5607 break;
5608 case 0x78:
5609 if (BITS(20, 24) == 0x18)
5610 {
5611 const u8 rm_idx = BITS(8, 11);
5612 const u8 rn_idx = BITS(0, 3);
5613 const u8 rd_idx = BITS(16, 19);
5614
5615 const u32 rm_val = state->Reg[rm_idx];
5616 const u32 rn_val = state->Reg[rn_idx];
5617
5618 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
5619 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
5620 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
5621 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
5622
5623 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
5624
5625 // Op is USADA8 if true.
5626 const u8 ra_idx = BITS(12, 15);
5627 if (ra_idx != 15)
5628 finalDif += state->Reg[ra_idx];
5629
5630 state->Reg[rd_idx] = finalDif;
5631 return 1;
5632 }
5633 break;
5634 case 0x7a:
5635 printf ("Unhandled v6 insn: usbfx\n");
5636 break;
5637 case 0x7c:
5638 printf ("Unhandled v6 insn: bfc/bfi\n");
5639 break;
5640 case 0x84:
5641 printf ("Unhandled v6 insn: srs\n");
5642 break;
5643 default:
5644 break;
5645 }
5646 printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27));
5647 return 0;
5648 } \ No newline at end of file
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index 8ab5ef160..a0e041fa0 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -25,24 +25,13 @@
25void ARMul_EmulateInit(); 25void ARMul_EmulateInit();
26ARMul_State* ARMul_NewState(ARMul_State* state); 26ARMul_State* ARMul_NewState(ARMul_State* state);
27void ARMul_Reset (ARMul_State* state); 27void ARMul_Reset (ARMul_State* state);
28ARMword ARMul_DoCycle(ARMul_State* state);
29unsigned ARMul_DoCoPro(ARMul_State* state);
30ARMword ARMul_DoProg(ARMul_State* state);
31ARMword ARMul_DoInstr(ARMul_State* state);
32void ARMul_Abort(ARMul_State* state, ARMword address);
33 28
34unsigned ARMul_MultTable[32] = { 29unsigned ARMul_MultTable[32] = {
35 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 30 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
36 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16 31 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
37}; 32};
38ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */ 33ARMword ARMul_ImmedTable[4096]; // immediate DP LHS values
39char ARMul_BitList[256]; /* number of bits in a byte table */ 34char ARMul_BitList[256]; // number of bits in a byte table
40
41void arm_dyncom_Abort(ARMul_State * state, ARMword vector)
42{
43 ARMul_Abort(state, vector);
44}
45
46 35
47/***************************************************************************\ 36/***************************************************************************\
48* Call this routine once to set up the emulator's tables. * 37* Call this routine once to set up the emulator's tables. *
@@ -51,18 +40,21 @@ void ARMul_EmulateInit()
51{ 40{
52 unsigned int i, j; 41 unsigned int i, j;
53 42
54 for (i = 0; i < 4096; i++) { /* the values of 12 bit dp rhs's */ 43 // the values of 12 bit dp rhs's
44 for (i = 0; i < 4096; i++) {
55 ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL); 45 ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
56 } 46 }
57 47
58 for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */ 48 // how many bits in LSM
49 for (i = 0; i < 256; ARMul_BitList[i++] = 0);
59 for (j = 1; j < 256; j <<= 1) 50 for (j = 1; j < 256; j <<= 1)
60 for (i = 0; i < 256; i++) 51 for (i = 0; i < 256; i++)
61 if ((i & j) > 0) 52 if ((i & j) > 0)
62 ARMul_BitList[i]++; 53 ARMul_BitList[i]++;
63 54
55 // you always need 4 times these values
64 for (i = 0; i < 256; i++) 56 for (i = 0; i < 256; i++)
65 ARMul_BitList[i] *= 4; /* you always need 4 times these values */ 57 ARMul_BitList[i] *= 4;
66 58
67} 59}
68 60
@@ -178,115 +170,3 @@ void ARMul_Reset(ARMul_State* state)
178 state->NumCcycles = 0; 170 state->NumCcycles = 0;
179 state->NumFcycles = 0; 171 state->NumFcycles = 0;
180} 172}
181
182
183/***************************************************************************\
184* Emulate the execution of an entire program. Start the correct emulator *
185* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
186* address of the last instruction that is executed. *
187\***************************************************************************/
188ARMword ARMul_DoProg(ARMul_State* state)
189{
190 ARMword pc = 0;
191
192 state->Emulate = RUN;
193 while (state->Emulate != STOP) {
194 state->Emulate = RUN;
195
196 if (state->prog32Sig && ARMul_MODE32BIT) {
197 pc = ARMul_Emulate32 (state);
198 }
199 else {
200 //pc = ARMul_Emulate26 (state);
201 }
202 }
203
204 return pc;
205}
206
207/***************************************************************************\
208* Emulate the execution of one instruction. Start the correct emulator *
209* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
210* address of the instruction that is executed. *
211\***************************************************************************/
212ARMword ARMul_DoInstr(ARMul_State* state)
213{
214 ARMword pc = 0;
215
216 state->Emulate = ONCE;
217
218 if (state->prog32Sig && ARMul_MODE32BIT) {
219 pc = ARMul_Emulate32 (state);
220 }
221
222 return pc;
223}
224
225/***************************************************************************\
226* This routine causes an Abort to occur, including selecting the correct *
227* mode, register bank, and the saving of registers. Call with the *
228* appropriate vector's memory address (0,4,8 ....) *
229\***************************************************************************/
230void ARMul_Abort(ARMul_State* state, ARMword vector)
231{
232 ARMword temp;
233 int isize = INSN_SIZE;
234 int esize = (TFLAG ? 0 : 4);
235 int e2size = (TFLAG ? -4 : 0);
236
237 state->Aborted = FALSE;
238
239 if (state->prog32Sig)
240 if (ARMul_MODE26BIT)
241 temp = R15PC;
242 else
243 temp = state->Reg[15];
244 else
245 temp = R15PC | ECC | ER15INT | EMODE;
246
247 switch (vector) {
248 case ARMul_ResetV: /* RESET */
249 SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
250 0);
251 break;
252 case ARMul_UndefinedInstrV: /* Undefined Instruction */
253 SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
254 isize);
255 break;
256 case ARMul_SWIV: /* Software Interrupt */
257 SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
258 isize);
259 break;
260 case ARMul_PrefetchAbortV: /* Prefetch Abort */
261 state->AbortAddr = 1;
262 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
263 esize);
264 break;
265 case ARMul_DataAbortV: /* Data Abort */
266 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
267 e2size);
268 break;
269 case ARMul_AddrExceptnV: /* Address Exception */
270 SETABORT (IBIT, SVC26MODE, isize);
271 break;
272 case ARMul_IRQV: /* IRQ */
273 SETABORT (IBIT,
274 state->prog32Sig ? IRQ32MODE : IRQ26MODE,
275 esize);
276 break;
277 case ARMul_FIQV: /* FIQ */
278 SETABORT (INTBITS,
279 state->prog32Sig ? FIQ32MODE : FIQ26MODE,
280 esize);
281 break;
282 }
283
284 if (ARMul_MODE32BIT) {
285 /*if (state->mmu.control & CONTROL_VECTOR)
286 vector += 0xffff0000; //for v4 high exception address*/
287 if (state->vector_remap_flag)
288 vector += state->vector_remap_addr; /* support some remap function in LPC processor */
289 ARMul_SetR15 (state, vector);
290 } else
291 ARMul_SetR15 (state, R15CCINTMODE | vector);
292}
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 5a8f09b22..fd90fb0a4 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -20,395 +20,13 @@
20#include "core/arm/disassembler/arm_disasm.h" 20#include "core/arm/disassembler/arm_disasm.h"
21#include "core/mem_map.h" 21#include "core/mem_map.h"
22 22
23 23// Unsigned sum of absolute difference
24static ARMword ModeToBank (ARMword);
25
26/* This routine returns the value of a register from a mode. */
27
28ARMword
29ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
30{
31 mode &= MODEBITS;
32 if (mode != state->Mode)
33 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
34 else
35 return (state->Reg[reg]);
36}
37
38/* This routine sets the value of a register for a mode. */
39
40void
41ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
42{
43 mode &= MODEBITS;
44 if (mode != state->Mode)
45 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
46 else
47 state->Reg[reg] = value;
48}
49
50/* This routine returns the value of the PC, mode independently. */
51
52ARMword
53ARMul_GetPC (ARMul_State * state)
54{
55 if (state->Mode > SVC26MODE)
56 return state->Reg[15];
57 else
58 return R15PC;
59}
60
61/* This routine returns the value of the PC, mode independently. */
62
63ARMword
64ARMul_GetNextPC (ARMul_State * state)
65{
66 if (state->Mode > SVC26MODE)
67 return state->Reg[15] + INSN_SIZE;
68 else
69 return (state->Reg[15] + INSN_SIZE) & R15PCBITS;
70}
71
72/* This routine sets the value of the PC. */
73
74void
75ARMul_SetPC (ARMul_State * state, ARMword value)
76{
77 if (ARMul_MODE32BIT)
78 state->Reg[15] = value & PCBITS;
79 else
80 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
81 FLUSHPIPE;
82}
83
84/* This routine returns the value of register 15, mode independently. */
85
86ARMword
87ARMul_GetR15 (ARMul_State * state)
88{
89 if (state->Mode > SVC26MODE)
90 return (state->Reg[15]);
91 else
92 return (R15PC | ECC | ER15INT | EMODE);
93}
94
95/* This routine sets the value of Register 15. */
96
97void
98ARMul_SetR15 (ARMul_State * state, ARMword value)
99{
100 if (ARMul_MODE32BIT)
101 state->Reg[15] = value & PCBITS;
102 else {
103 state->Reg[15] = value;
104 ARMul_R15Altered (state);
105 }
106 FLUSHPIPE;
107}
108
109/* This routine returns the value of the CPSR. */
110
111ARMword
112ARMul_GetCPSR (ARMul_State * state)
113{
114 //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
115 //return (CPSR | state->Cpsr); for gdb20030716
116 return (CPSR); //had be tested in old skyeye with gdb5.0-5.3
117}
118
119/* This routine sets the value of the CPSR. */
120
121void
122ARMul_SetCPSR (ARMul_State * state, ARMword value)
123{
124 state->Cpsr = value;
125 ARMul_CPSRAltered (state);
126}
127
128/* This routine does all the nasty bits involved in a write to the CPSR,
129 including updating the register bank, given a MSR instruction. */
130
131void
132ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
133{
134 state->Cpsr = ARMul_GetCPSR (state);
135 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
136 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
137 /* In user mode, only write flags. */
138 if (BIT (16))
139 SETPSR_C (state->Cpsr, rhs);
140 if (BIT (17))
141 SETPSR_X (state->Cpsr, rhs);
142 if (BIT (18))
143 SETPSR_S (state->Cpsr, rhs);
144 }
145 if (BIT (19))
146 SETPSR_F (state->Cpsr, rhs);
147 ARMul_CPSRAltered (state);
148}
149
150/* Get an SPSR from the specified mode. */
151
152ARMword
153ARMul_GetSPSR (ARMul_State * state, ARMword mode)
154{
155 ARMword bank = ModeToBank (mode & MODEBITS);
156
157 if (!BANK_CAN_ACCESS_SPSR (bank))
158 return ARMul_GetCPSR (state);
159
160 return state->Spsr[bank];
161}
162
163/* This routine does a write to an SPSR. */
164
165void
166ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
167{
168 ARMword bank = ModeToBank (mode & MODEBITS);
169
170 if (BANK_CAN_ACCESS_SPSR (bank))
171 state->Spsr[bank] = value;
172}
173
174/* This routine does a write to the current SPSR, given an MSR instruction. */
175
176void
177ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
178{
179 if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
180 if (BIT (16))
181 SETPSR_C (state->Spsr[state->Bank], rhs);
182 if (BIT (17))
183 SETPSR_X (state->Spsr[state->Bank], rhs);
184 if (BIT (18))
185 SETPSR_S (state->Spsr[state->Bank], rhs);
186 if (BIT (19))
187 SETPSR_F (state->Spsr[state->Bank], rhs);
188 }
189}
190
191/* This routine updates the state of the emulator after the Cpsr has been
192 changed. Both the processor flags and register bank are updated. */
193
194void
195ARMul_CPSRAltered (ARMul_State * state)
196{
197 ARMword oldmode;
198
199 if (state->prog32Sig == LOW)
200 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
201
202 oldmode = state->Mode;
203
204 /*if (state->Mode != (state->Cpsr & MODEBITS)) {
205 state->Mode =
206 ARMul_SwitchMode (state, state->Mode,
207 state->Cpsr & MODEBITS);
208
209 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
210 }*/
211 //state->Cpsr &= ~MODEBITS;
212
213 ASSIGNINT (state->Cpsr & INTBITS);
214 //state->Cpsr &= ~INTBITS;
215 ASSIGNN ((state->Cpsr & NBIT) != 0);
216 //state->Cpsr &= ~NBIT;
217 ASSIGNZ ((state->Cpsr & ZBIT) != 0);
218 //state->Cpsr &= ~ZBIT;
219 ASSIGNC ((state->Cpsr & CBIT) != 0);
220 //state->Cpsr &= ~CBIT;
221 ASSIGNV ((state->Cpsr & VBIT) != 0);
222 //state->Cpsr &= ~VBIT;
223 ASSIGNQ ((state->Cpsr & QBIT) != 0);
224 //state->Cpsr &= ~QBIT;
225 state->GEFlag = (state->Cpsr & 0x000F0000);
226#ifdef MODET
227 ASSIGNT ((state->Cpsr & TBIT) != 0);
228 //state->Cpsr &= ~TBIT;
229#endif
230
231 if (oldmode > SVC26MODE) {
232 if (state->Mode <= SVC26MODE) {
233 state->Emulate = CHANGEMODE;
234 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
235 }
236 } else {
237 if (state->Mode > SVC26MODE) {
238 state->Emulate = CHANGEMODE;
239 state->Reg[15] = R15PC;
240 } else
241 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
242 }
243}
244
245/* This routine updates the state of the emulator after register 15 has
246 been changed. Both the processor flags and register bank are updated.
247 This routine should only be called from a 26 bit mode. */
248
249void
250ARMul_R15Altered (ARMul_State * state)
251{
252 if (state->Mode != R15MODE) {
253 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
254 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
255 }
256
257 if (state->Mode > SVC26MODE)
258 state->Emulate = CHANGEMODE;
259
260 ASSIGNR15INT (R15INT);
261
262 ASSIGNN ((state->Reg[15] & NBIT) != 0);
263 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
264 ASSIGNC ((state->Reg[15] & CBIT) != 0);
265 ASSIGNV ((state->Reg[15] & VBIT) != 0);
266}
267
268/* This routine controls the saving and restoring of registers across mode
269 changes. The regbank matrix is largely unused, only rows 13 and 14 are
270 used across all modes, 8 to 14 are used for FIQ, all others use the USER
271 column. It's easier this way. old and new parameter are modes numbers.
272 Notice the side effect of changing the Bank variable. */
273
274ARMword
275ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
276{
277 unsigned i;
278 ARMword oldbank;
279 ARMword newbank;
280 static int revision_value = 53;
281
282 oldbank = ModeToBank (oldmode);
283 newbank = state->Bank = ModeToBank (newmode);
284
285 /* Do we really need to do it? */
286 if (oldbank != newbank) {
287 if (oldbank == 3 && newbank == 2) {
288 //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
289 if (state->NumInstrs >= 5832487) {
290// printf("%d, ", state->NumInstrs + revision_value);
291// printf("revision_value : %d\n", revision_value);
292 revision_value ++;
293 }
294 }
295 /* Save away the old registers. */
296 switch (oldbank) {
297 case USERBANK:
298 case IRQBANK:
299 case SVCBANK:
300 case ABORTBANK:
301 case UNDEFBANK:
302 if (newbank == FIQBANK)
303 for (i = 8; i < 13; i++)
304 state->RegBank[USERBANK][i] =
305 state->Reg[i];
306 state->RegBank[oldbank][13] = state->Reg[13];
307 state->RegBank[oldbank][14] = state->Reg[14];
308 break;
309 case FIQBANK:
310 for (i = 8; i < 15; i++)
311 state->RegBank[FIQBANK][i] = state->Reg[i];
312 break;
313 case DUMMYBANK:
314 for (i = 8; i < 15; i++)
315 state->RegBank[DUMMYBANK][i] = 0;
316 break;
317 default:
318 abort ();
319 }
320
321 /* Restore the new registers. */
322 switch (newbank) {
323 case USERBANK:
324 case IRQBANK:
325 case SVCBANK:
326 case ABORTBANK:
327 case UNDEFBANK:
328 if (oldbank == FIQBANK)
329 for (i = 8; i < 13; i++)
330 state->Reg[i] =
331 state->RegBank[USERBANK][i];
332 state->Reg[13] = state->RegBank[newbank][13];
333 state->Reg[14] = state->RegBank[newbank][14];
334 break;
335 case FIQBANK:
336 for (i = 8; i < 15; i++)
337 state->Reg[i] = state->RegBank[FIQBANK][i];
338 break;
339 case DUMMYBANK:
340 for (i = 8; i < 15; i++)
341 state->Reg[i] = 0;
342 break;
343 default:
344 abort ();
345 }
346 }
347
348 return newmode;
349}
350
351/* Given a processor mode, this routine returns the
352 register bank that will be accessed in that mode. */
353
354static ARMword
355ModeToBank (ARMword mode)
356{
357 static ARMword bankofmode[] = {
358 USERBANK, FIQBANK, IRQBANK, SVCBANK,
359 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
360 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
361 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
362 USERBANK, FIQBANK, IRQBANK, SVCBANK,
363 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
364 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
365 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
366 };
367
368 if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
369 return DUMMYBANK;
370
371 return bankofmode[mode];
372}
373
374/* Returns the register number of the nth register in a reg list. */
375
376unsigned
377ARMul_NthReg (ARMword instr, unsigned number)
378{
379 unsigned bit, upto;
380
381 for (bit = 0, upto = 0; upto <= number; bit++)
382 if (BIT (bit))
383 upto++;
384
385 return (bit - 1);
386}
387
388/* Unsigned sum of absolute difference */
389u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) 24u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
390{ 25{
391 if (left > right) 26 if (left > right)
392 return left - right; 27 return left - right;
393 28
394 return right - left; 29 return right - left;
395}
396
397/* Assigns the N and Z flags depending on the value of result. */
398
399void
400ARMul_NegZero (ARMul_State * state, ARMword result)
401{
402 if (NEG (result)) {
403 SETN;
404 CLEARZ;
405 } else if (result == 0) {
406 CLEARN;
407 SETZ;
408 } else {
409 CLEARN;
410 CLEARZ;
411 }
412} 30}
413 31
414// Add with carry, indicates if a carry-out or signed overflow occurred. 32// Add with carry, indicates if a carry-out or signed overflow occurred.
@@ -441,23 +59,6 @@ bool SubOverflow(ARMword a, ARMword b, ARMword result)
441 (POS(a) && NEG(b) && NEG(result))); 59 (POS(a) && NEG(b) && NEG(result)));
442} 60}
443 61
444/* Assigns the C flag after an addition of a and b to give result. */
445
446void
447ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
448{
449 ASSIGNC ((NEG (a) && NEG (b)) ||
450 (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
451}
452
453/* Assigns the V flag after an addition of a and b to give result. */
454
455void
456ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
457{
458 ASSIGNV (AddOverflow (a, b, result));
459}
460
461// Returns true if the Q flag should be set as a result of overflow. 62// Returns true if the Q flag should be set as a result of overflow.
462bool ARMul_AddOverflowQ(ARMword a, ARMword b) 63bool ARMul_AddOverflowQ(ARMword a, ARMword b)
463{ 64{
@@ -468,24 +69,7 @@ bool ARMul_AddOverflowQ(ARMword a, ARMword b)
468 return false; 69 return false;
469} 70}
470 71
471/* Assigns the C flag after an subtraction of a and b to give result. */ 72// 8-bit signed saturated addition
472
473void
474ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
475{
476 ASSIGNC ((NEG (a) && POS (b)) ||
477 (NEG (a) && POS (result)) || (POS (b) && POS (result)));
478}
479
480/* Assigns the V flag after an subtraction of a and b to give result. */
481
482void
483ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
484{
485 ASSIGNV (SubOverflow (a, b, result));
486}
487
488/* 8-bit signed saturated addition */
489u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) 73u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
490{ 74{
491 u8 result = left + right; 75 u8 result = left + right;
@@ -500,7 +84,7 @@ u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right)
500 return result; 84 return result;
501} 85}
502 86
503/* 8-bit signed saturated subtraction */ 87// 8-bit signed saturated subtraction
504u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) 88u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
505{ 89{
506 u8 result = left - right; 90 u8 result = left - right;
@@ -515,7 +99,7 @@ u8 ARMul_SignedSaturatedSub8(u8 left, u8 right)
515 return result; 99 return result;
516} 100}
517 101
518/* 16-bit signed saturated addition */ 102// 16-bit signed saturated addition
519u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) 103u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
520{ 104{
521 u16 result = left + right; 105 u16 result = left + right;
@@ -530,7 +114,7 @@ u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right)
530 return result; 114 return result;
531} 115}
532 116
533/* 16-bit signed saturated subtraction */ 117// 16-bit signed saturated subtraction
534u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) 118u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
535{ 119{
536 u16 result = left - right; 120 u16 result = left - right;
@@ -545,7 +129,7 @@ u16 ARMul_SignedSaturatedSub16(u16 left, u16 right)
545 return result; 129 return result;
546} 130}
547 131
548/* 8-bit unsigned saturated addition */ 132// 8-bit unsigned saturated addition
549u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) 133u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
550{ 134{
551 u8 result = left + right; 135 u8 result = left + right;
@@ -556,7 +140,7 @@ u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
556 return result; 140 return result;
557} 141}
558 142
559/* 16-bit unsigned saturated addition */ 143// 16-bit unsigned saturated addition
560u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) 144u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
561{ 145{
562 u16 result = left + right; 146 u16 result = left + right;
@@ -567,7 +151,7 @@ u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
567 return result; 151 return result;
568} 152}
569 153
570/* 8-bit unsigned saturated subtraction */ 154// 8-bit unsigned saturated subtraction
571u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) 155u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
572{ 156{
573 if (left <= right) 157 if (left <= right)
@@ -576,7 +160,7 @@ u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
576 return left - right; 160 return left - right;
577} 161}
578 162
579/* 16-bit unsigned saturated subtraction */ 163// 16-bit unsigned saturated subtraction
580u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) 164u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
581{ 165{
582 if (left <= right) 166 if (left <= right)
@@ -620,444 +204,3 @@ u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
620 *saturation_occurred = false; 204 *saturation_occurred = false;
621 return (u32)value; 205 return (u32)value;
622} 206}
623
624/* This function does the work of generating the addresses used in an
625 LDC instruction. The code here is always post-indexed, it's up to the
626 caller to get the input address correct and to handle base register
627 modification. It also handles the Busy-Waiting. */
628
629void
630ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
631{
632 unsigned cpab;
633 ARMword data;
634
635 UNDEF_LSCPCBaseWb;
636 //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
637 /*chy 2004-05-23 should update this function in the future,should concern dataabort*/
638// chy 2004-05-25 , fix it now,so needn't printf
639// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
640 //exit(-1);
641
642 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
643 if (!state->LDC[CPNum]) {
644 /*
645 printf
646 ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
647 CPNum, instr, address);
648 */
649 ARMul_UndefInstr (state, instr);
650 return;
651 }
652
653 /*if (ADDREXCEPT (address))
654 INTERNALABORT (address);*/
655
656 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
657 while (cpab == ARMul_BUSY) {
658 ARMul_Icycles (state, 1, 0);
659
660 if (IntPending (state)) {
661 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
662 instr, 0);
663 return;
664 } else
665 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
666 0);
667 }
668 if (cpab == ARMul_CANT) {
669 /*
670 printf
671 ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
672 CPNum, instr, address);
673 */
674 CPTAKEABORT;
675 return;
676 }
677
678 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
679 data = ARMul_LoadWordN (state, address);
680 //chy 2004-05-25
681 if (state->abortSig || state->Aborted)
682 goto L_ldc_takeabort;
683
684 BUSUSEDINCPCN;
685//chy 2004-05-25
686 /*
687 if (BIT (21))
688 LSBase = state->Base;
689 */
690
691 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
692
693 while (cpab == ARMul_INC) {
694 address += 4;
695 data = ARMul_LoadWordN (state, address);
696 //chy 2004-05-25
697 if (state->abortSig || state->Aborted)
698 goto L_ldc_takeabort;
699
700 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
701 }
702
703//chy 2004-05-25
704L_ldc_takeabort:
705 if (BIT (21)) {
706 if (!
707 ((state->abortSig || state->Aborted)
708 && state->lateabtSig == LOW))
709 LSBase = state->Base;
710 }
711
712 if (state->abortSig || state->Aborted)
713 TAKEABORT;
714}
715
716/* This function does the work of generating the addresses used in an
717 STC instruction. The code here is always post-indexed, it's up to the
718 caller to get the input address correct and to handle base register
719 modification. It also handles the Busy-Waiting. */
720
721void
722ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
723{
724 unsigned cpab;
725 ARMword data;
726
727 UNDEF_LSCPCBaseWb;
728
729 //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
730 /*chy 2004-05-23 should update this function in the future,should concern dataabort */
731// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
732// chy 2004-05-25 , fix it now,so needn't printf
733// printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
734
735 //exit(-1);
736 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
737 if (!state->STC[CPNum]) {
738 /*
739 printf
740 ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
741 CPNum, instr, address);
742 */
743 ARMul_UndefInstr (state, instr);
744 return;
745 }
746
747 /*if (ADDREXCEPT (address) || VECTORACCESS (address))
748 INTERNALABORT (address);*/
749
750 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
751 while (cpab == ARMul_BUSY) {
752 ARMul_Icycles (state, 1, 0);
753 if (IntPending (state)) {
754 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
755 instr, 0);
756 return;
757 } else
758 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
759 &data);
760 }
761
762 if (cpab == ARMul_CANT) {
763 /*
764 printf
765 ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
766 CPNum, instr, address);
767 */
768 CPTAKEABORT;
769 return;
770 }
771 /*#ifndef MODE32
772 if (ADDREXCEPT (address) || VECTORACCESS (address))
773 INTERNALABORT (address);
774 #endif*/
775 BUSUSEDINCPCN;
776//chy 2004-05-25
777 /*
778 if (BIT (21))
779 LSBase = state->Base;
780 */
781 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
782 ARMul_StoreWordN (state, address, data);
783 //chy 2004-05-25
784 if (state->abortSig || state->Aborted)
785 goto L_stc_takeabort;
786
787 while (cpab == ARMul_INC) {
788 address += 4;
789 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
790 ARMul_StoreWordN (state, address, data);
791 //chy 2004-05-25
792 if (state->abortSig || state->Aborted)
793 goto L_stc_takeabort;
794 }
795//chy 2004-05-25
796L_stc_takeabort:
797 if (BIT (21)) {
798 if (!
799 ((state->abortSig || state->Aborted)
800 && state->lateabtSig == LOW))
801 LSBase = state->Base;
802 }
803
804 if (state->abortSig || state->Aborted)
805 TAKEABORT;
806}
807
808/* This function does the Busy-Waiting for an MCR instruction. */
809
810void
811ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
812{
813 unsigned cpab;
814 int cm = BITS(0, 3) & 0xf;
815 int cp = BITS(5, 7) & 0x7;
816 int rd = BITS(12, 15) & 0xf;
817 int cn = BITS(16, 19) & 0xf;
818 int cpopc = BITS(21, 23) & 0x7;
819
820 if (CPNum == 15 && source == 0) //Cache flush
821 {
822 return;
823 }
824
825 //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
826 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
827 if (!state->MCR[CPNum]) {
828 //chy 2004-07-19 should fix in the future ????!!!!
829 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source);
830 ARMul_UndefInstr (state, instr);
831 return;
832 }
833
834 //DEBUG("SKYEYE ARMul_MCR p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
835 //DEBUG("plutoo: MCR not implemented\n");
836 //exit(1);
837 //return;
838
839 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
840
841 while (cpab == ARMul_BUSY) {
842 ARMul_Icycles (state, 1, 0);
843
844 if (IntPending (state)) {
845 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
846 instr, 0);
847 return;
848 } else
849 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
850 source);
851 }
852
853 if (cpab == ARMul_CANT) {
854 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo
855 //ARMul_Abort (state, ARMul_UndefinedInstrV);
856 } else {
857 BUSUSEDINCPCN;
858 ARMul_Ccycles (state, 1, 0);
859 }
860}
861
862/* This function does the Busy-Waiting for an MCRR instruction. */
863
864void
865ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
866{
867 unsigned cpab;
868
869 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
870 if (!state->MCRR[CPNum]) {
871 ARMul_UndefInstr (state, instr);
872 return;
873 }
874
875 cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
876
877 while (cpab == ARMul_BUSY) {
878 ARMul_Icycles (state, 1, 0);
879
880 if (IntPending (state)) {
881 cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
882 instr, 0, 0);
883 return;
884 } else
885 cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
886 source1, source2);
887 }
888 if (cpab == ARMul_CANT) {
889 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
890 ARMul_Abort (state, ARMul_UndefinedInstrV);
891 } else {
892 BUSUSEDINCPCN;
893 ARMul_Ccycles (state, 1, 0);
894 }
895}
896
897/* This function does the Busy-Waiting for an MRC instruction. */
898
899ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
900{
901 int cm = BITS(0, 3) & 0xf;
902 int cp = BITS(5, 7) & 0x7;
903 int rd = BITS(12, 15) & 0xf;
904 int cn = BITS(16, 19) & 0xf;
905 int cpopc = BITS(21, 23) & 0x7;
906
907 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
908 ARMword result = Memory::KERNEL_MEMORY_VADDR;
909
910 if (result != -1) {
911 return result;
912 }
913 }
914
915 //DEBUG("SKYEYE ARMul_MRC p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
916 //DEBUG("plutoo: MRC not implemented\n");
917 //return;
918
919 unsigned cpab;
920 ARMword result = 0;
921
922 //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
923 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
924 if (!state->MRC[CPNum]) {
925 //chy 2004-07-19 should fix in the future????!!!!
926 LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr);
927 ARMul_UndefInstr (state, instr);
928 return -1;
929 }
930
931 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
932 while (cpab == ARMul_BUSY) {
933 ARMul_Icycles (state, 1, 0);
934 if (IntPending (state)) {
935 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
936 instr, 0);
937 return (0);
938 } else
939 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
940 &result);
941 }
942 if (cpab == ARMul_CANT) {
943 printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
944 ARMul_Abort (state, ARMul_UndefinedInstrV);
945 /* Parent will destroy the flags otherwise. */
946 result = ECC;
947 } else {
948 BUSUSEDINCPCN;
949 ARMul_Ccycles (state, 1, 0);
950 ARMul_Icycles (state, 1, 0);
951 }
952
953 return result;
954}
955
956/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
957
958void
959ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
960{
961 unsigned cpab;
962 ARMword result1 = 0;
963 ARMword result2 = 0;
964
965 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
966 if (!state->MRRC[CPNum]) {
967 ARMul_UndefInstr (state, instr);
968 return;
969 }
970
971 cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
972 while (cpab == ARMul_BUSY) {
973 ARMul_Icycles (state, 1, 0);
974 if (IntPending (state)) {
975 cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
976 instr, 0, 0);
977 return;
978 } else
979 cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
980 &result1, &result2);
981 }
982 if (cpab == ARMul_CANT) {
983 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
984 ARMul_Abort (state, ARMul_UndefinedInstrV);
985 } else {
986 BUSUSEDINCPCN;
987 ARMul_Ccycles (state, 1, 0);
988 ARMul_Icycles (state, 1, 0);
989 }
990
991 *dest1 = result1;
992 *dest2 = result2;
993}
994
995/* This function does the Busy-Waiting for an CDP instruction. */
996
997void
998ARMul_CDP (ARMul_State * state, ARMword instr)
999{
1000 unsigned cpab;
1001
1002 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
1003 if (!state->CDP[CPNum]) {
1004 ARMul_UndefInstr (state, instr);
1005 return;
1006 }
1007 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
1008 while (cpab == ARMul_BUSY) {
1009 ARMul_Icycles (state, 1, 0);
1010 if (IntPending (state)) {
1011 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
1012 instr);
1013 return;
1014 } else
1015 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
1016 }
1017 if (cpab == ARMul_CANT)
1018 ARMul_Abort (state, ARMul_UndefinedInstrV);
1019 else
1020 BUSUSEDN;
1021}
1022
1023/* This function handles Undefined instructions, as CP isntruction. */
1024
1025void
1026ARMul_UndefInstr (ARMul_State * state, ARMword instr)
1027{
1028 std::string disasm = ARM_Disasm::Disassemble(state->pc, instr);
1029 LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr);
1030 ARMul_Abort (state, ARMul_UndefinedInstrV);
1031}
1032
1033/* Return TRUE if an interrupt is pending, FALSE otherwise. */
1034
1035unsigned
1036IntPending (ARMul_State * state)
1037{
1038 /* Any exceptions. */
1039 if (state->NresetSig == LOW) {
1040 ARMul_Abort (state, ARMul_ResetV);
1041 return TRUE;
1042 } else if (!state->NfiqSig && !FFLAG) {
1043 ARMul_Abort (state, ARMul_FIQV);
1044 return TRUE;
1045 } else if (!state->NirqSig && !IFLAG) {
1046 ARMul_Abort (state, ARMul_IRQV);
1047 return TRUE;
1048 }
1049
1050 return FALSE;
1051}
1052
1053/* Align a word access to a non word boundary. */
1054
1055ARMword
1056ARMul_Align (ARMul_State* state, ARMword address, ARMword data)
1057{
1058 /* This code assumes the address is really unaligned,
1059 as a shift by 32 is undefined in C. */
1060
1061 address = (address & 3) << 3; /* Get the word address. */
1062 return ((data >> address) | (data << (32 - address))); /* rot right */
1063}
diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp
deleted file mode 100644
index 7845d1042..000000000
--- a/src/core/arm/interpreter/armvirt.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
1/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
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. */
17
18/* This file contains a complete ARMulator memory model, modelling a
19"virtual memory" system. A much simpler model can be found in armfast.c,
20and that model goes faster too, but has a fixed amount of memory. This
21model's memory has 64K pages, allocated on demand from a 64K entry page
22table. The routines PutWord and GetWord implement this. Pages are never
23freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */
25
26#include "core/arm/skyeye_common/armdefs.h"
27#include "core/arm/skyeye_common/armemu.h"
28
29#include "core/mem_map.h"
30
31#define dumpstack 1
32#define dumpstacksize 0x10
33#define maxdmupaddr 0x0033a850
34
35/*ARMword ARMul_GetCPSR (ARMul_State * state) {
36return 0;
37}
38ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode) {
39return 0;
40}
41void ARMul_SetCPSR (ARMul_State * state, ARMword value) {
42
43}
44void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) {
45
46}*/
47
48void ARMul_Icycles(ARMul_State * state, unsigned number, ARMword address) {
49}
50
51void ARMul_Ccycles(ARMul_State * state, unsigned number, ARMword address) {
52}
53
54ARMword ARMul_LoadInstrS(ARMul_State * state, ARMword address, ARMword isize) {
55 state->NumScycles++;
56
57#ifdef HOURGLASS
58 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
59 HOURGLASS;
60 }
61#endif
62 if (isize == 2)
63 return (u16)Memory::Read16(address);
64 else
65 return (u32)Memory::Read32(address);
66}
67
68ARMword ARMul_LoadInstrN(ARMul_State * state, ARMword address, ARMword isize) {
69 state->NumNcycles++;
70
71 if (isize == 2)
72 return (u16)Memory::Read16(address);
73 else
74 return (u32)Memory::Read32(address);
75}
76
77ARMword ARMul_ReLoadInstr(ARMul_State * state, ARMword address, ARMword isize) {
78 ARMword data;
79
80 if ((isize == 2) && (address & 0x2)) {
81 ARMword lo;
82 lo = (u16)Memory::Read16(address);
83 return lo;
84 }
85
86 data = (u32)Memory::Read32(address);
87 return data;
88}
89
90ARMword ARMul_ReadWord(ARMul_State * state, ARMword address) {
91 ARMword data;
92 data = Memory::Read32(address);
93 return data;
94}
95
96ARMword ARMul_LoadWordS(ARMul_State * state, ARMword address) {
97 state->NumScycles++;
98 return ARMul_ReadWord(state, address);
99}
100
101ARMword ARMul_LoadWordN(ARMul_State * state, ARMword address) {
102 state->NumNcycles++;
103 return ARMul_ReadWord(state, address);
104}
105
106ARMword ARMul_LoadHalfWord(ARMul_State * state, ARMword address) {
107 state->NumNcycles++;
108 return (u16)Memory::Read16(address);;
109}
110
111ARMword ARMul_ReadByte(ARMul_State * state, ARMword address) {
112 return (u8)Memory::Read8(address);
113}
114
115ARMword ARMul_LoadByte(ARMul_State * state, ARMword address) {
116 state->NumNcycles++;
117 return ARMul_ReadByte(state, address);
118}
119
120void ARMul_StoreHalfWord(ARMul_State * state, ARMword address, ARMword data) {
121 state->NumNcycles++;
122 Memory::Write16(address, data);
123}
124
125void ARMul_StoreByte(ARMul_State * state, ARMword address, ARMword data) {
126 state->NumNcycles++;
127 ARMul_WriteByte(state, address, data);
128}
129
130ARMword ARMul_SwapWord(ARMul_State * state, ARMword address, ARMword data) {
131 ARMword temp;
132 state->NumNcycles++;
133 temp = ARMul_ReadWord(state, address);
134 state->NumNcycles++;
135 Memory::Write32(address, data);
136 return temp;
137}
138
139ARMword ARMul_SwapByte(ARMul_State * state, ARMword address, ARMword data) {
140 ARMword temp;
141 temp = ARMul_LoadByte(state, address);
142 Memory::Write8(address, data);
143 return temp;
144}
145
146void ARMul_WriteWord(ARMul_State * state, ARMword address, ARMword data) {
147 Memory::Write32(address, data);
148}
149
150void ARMul_WriteByte(ARMul_State * state, ARMword address, ARMword data)
151{
152 Memory::Write8(address, data);
153}
154
155void ARMul_StoreWordS(ARMul_State * state, ARMword address, ARMword data)
156{
157 state->NumScycles++;
158 ARMul_WriteWord(state, address, data);
159}
160
161void ARMul_StoreWordN(ARMul_State * state, ARMword address, ARMword data)
162{
163 state->NumNcycles++;
164 ARMul_WriteWord(state, address, data);
165}
diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp
deleted file mode 100644
index 9cf80672d..000000000
--- a/src/core/arm/interpreter/thumbemu.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
1/* thumbemu.c -- Thumb instruction emulation.
2 Copyright (C) 1996, Cygnus Software Technologies Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
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. */
17
18/* We can provide simple Thumb simulation by decoding the Thumb
19instruction into its corresponding ARM instruction, and using the
20existing ARM simulator. */
21
22#include "core/arm/skyeye_common/skyeye_defs.h"
23
24#ifndef MODET /* required for the Thumb instruction support */
25#if 1
26#error "MODET needs to be defined for the Thumb world to work"
27#else
28#define MODET (1)
29#endif
30#endif
31
32#include "core/arm/skyeye_common/armdefs.h"
33#include "core/arm/skyeye_common/armemu.h"
34#include "core/arm/skyeye_common/armos.h"
35
36
37/* Decode a 16bit Thumb instruction. The instruction is in the low
38 16-bits of the tinstr field, with the following Thumb instruction
39 held in the high 16-bits. Passing in two Thumb instructions allows
40 easier simulation of the special dual BL instruction. */
41
42tdstate
43ARMul_ThumbDecode (
44 ARMul_State *state,
45 ARMword pc,
46 ARMword tinstr,
47 ARMword *ainstr)
48{
49 tdstate valid = t_decoded; /* default assumes a valid instruction */
50 ARMword next_instr;
51
52 if (state->bigendSig) {
53 next_instr = tinstr & 0xFFFF;
54 tinstr >>= 16;
55 }
56 else {
57 next_instr = tinstr >> 16;
58 tinstr &= 0xFFFF;
59 }
60
61#if 1 /* debugging to catch non updates */
62 *ainstr = 0xDEADC0DE;
63#endif
64
65 switch ((tinstr & 0xF800) >> 11) {
66 case 0: /* LSL */
67 case 1: /* LSR */
68 case 2: /* ASR */
69 /* Format 1 */
70 *ainstr = 0xE1B00000 /* base opcode */
71 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
72 |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
73 |((tinstr & 0x0038) >> 3) /* Rs */
74 |((tinstr & 0x0007) << 12); /* Rd */
75 break;
76 case 3: /* ADD/SUB */
77 /* Format 2 */
78 {
79 ARMword subset[4] = {
80 0xE0900000, /* ADDS Rd,Rs,Rn */
81 0xE0500000, /* SUBS Rd,Rs,Rn */
82 0xE2900000, /* ADDS Rd,Rs,#imm3 */
83 0xE2500000 /* SUBS Rd,Rs,#imm3 */
84 };
85 /* It is quicker indexing into a table, than performing switch
86 or conditionals: */
87 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
88 |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
89 |((tinstr & 0x0038) << (16 - 3)) /* Rs */
90 |((tinstr & 0x0007) << (12 - 0)); /* Rd */
91 }
92 break;
93 case 4: /* MOV */
94 case 5: /* CMP */
95 case 6: /* ADD */
96 case 7: /* SUB */
97 /* Format 3 */
98 {
99 ARMword subset[4] = {
100 0xE3B00000, /* MOVS Rd,#imm8 */
101 0xE3500000, /* CMP Rd,#imm8 */
102 0xE2900000, /* ADDS Rd,Rd,#imm8 */
103 0xE2500000, /* SUBS Rd,Rd,#imm8 */
104 };
105 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
106 |((tinstr & 0x00FF) >> 0) /* imm8 */
107 |((tinstr & 0x0700) << (16 - 8)) /* Rn */
108 |((tinstr & 0x0700) << (12 - 8)); /* Rd */
109 }
110 break;
111 case 8: /* Arithmetic and high register transfers */
112 /* TODO: Since the subsets for both Format 4 and Format 5
113 instructions are made up of different ARM encodings, we could
114 save the following conditional, and just have one large
115 subset. */
116 if ((tinstr & (1 << 10)) == 0) {
117 /* Format 4 */
118 enum OpcodeType { t_norm, t_shift, t_neg, t_mul };
119 struct ThumbOpcode {
120 ARMword opcode;
121 OpcodeType otype;
122 };
123
124 ThumbOpcode subset[16] = {
125 {
126 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
127 {
128 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
129 {
130 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
131 {
132 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
133 {
134 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
135 {
136 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
137 {
138 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
139 {
140 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
141 {
142 0xE1100000, t_norm}, /* TST Rd,Rs */
143 {
144 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
145 {
146 0xE1500000, t_norm}, /* CMP Rd,Rs */
147 {
148 0xE1700000, t_norm}, /* CMN Rd,Rs */
149 {
150 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
151 {
152 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
153 {
154 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
155 {
156 0xE1F00000, t_norm} /* MVNS Rd,Rs */
157 };
158 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
159 switch (subset[(tinstr & 0x03C0) >> 6].otype) {
160 case t_norm:
161 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
162 |((tinstr & 0x0007) << 12) /* Rd */
163 |((tinstr & 0x0038) >> 3); /* Rs */
164 break;
165 case t_shift:
166 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
167 |((tinstr & 0x0007) >> 0) /* Rm */
168 |((tinstr & 0x0038) << (8 - 3)); /* Rs */
169 break;
170 case t_neg:
171 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
172 |((tinstr & 0x0038) << (16 - 3)); /* Rn */
173 break;
174 case t_mul:
175 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
176 |((tinstr & 0x0007) << 8) /* Rs */
177 |((tinstr & 0x0038) >> 3); /* Rm */
178 break;
179 }
180 }
181 else {
182 /* Format 5 */
183 ARMword Rd = ((tinstr & 0x0007) >> 0);
184 ARMword Rs = ((tinstr & 0x0038) >> 3);
185 if (tinstr & (1 << 7))
186 Rd += 8;
187 if (tinstr & (1 << 6))
188 Rs += 8;
189 switch ((tinstr & 0x03C0) >> 6) {
190 case 0x1: /* ADD Rd,Rd,Hs */
191 case 0x2: /* ADD Hd,Hd,Rs */
192 case 0x3: /* ADD Hd,Hd,Hs */
193 *ainstr = 0xE0800000 /* base */
194 | (Rd << 16) /* Rn */
195 |(Rd << 12) /* Rd */
196 |(Rs << 0); /* Rm */
197 break;
198 case 0x5: /* CMP Rd,Hs */
199 case 0x6: /* CMP Hd,Rs */
200 case 0x7: /* CMP Hd,Hs */
201 *ainstr = 0xE1500000 /* base */
202 | (Rd << 16) /* Rn */
203 |(Rd << 12) /* Rd */
204 |(Rs << 0); /* Rm */
205 break;
206 case 0x9: /* MOV Rd,Hs */
207 case 0xA: /* MOV Hd,Rs */
208 case 0xB: /* MOV Hd,Hs */
209 *ainstr = 0xE1A00000 /* base */
210 | (Rd << 16) /* Rn */
211 |(Rd << 12) /* Rd */
212 |(Rs << 0); /* Rm */
213 break;
214 case 0xC: /* BX Rs */
215 case 0xD: /* BX Hs */
216 *ainstr = 0xE12FFF10 /* base */
217 | ((tinstr & 0x0078) >> 3); /* Rd */
218 break;
219 case 0x0: /* UNDEFINED */
220 case 0x4: /* UNDEFINED */
221 case 0x8: /* UNDEFINED */
222 valid = t_undefined;
223 break;
224 case 0xE: /* BLX */
225 case 0xF: /* BLX */
226 if (state->is_v5) {
227 *ainstr = 0xE1200030 /* base */
228 |(Rs << 0); /* Rm */
229 } else {
230 valid = t_undefined;
231 }
232 break;
233 }
234 }
235 break;
236 case 9: /* LDR Rd,[PC,#imm8] */
237 /* Format 6 */
238 *ainstr = 0xE59F0000 /* base */
239 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
240 |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
241 break;
242 case 10:
243 case 11:
244 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
245 the following could be merged into a single subset, saving on
246 the following boolean: */
247 if ((tinstr & (1 << 9)) == 0) {
248 /* Format 7 */
249 ARMword subset[4] = {
250 0xE7800000, /* STR Rd,[Rb,Ro] */
251 0xE7C00000, /* STRB Rd,[Rb,Ro] */
252 0xE7900000, /* LDR Rd,[Rb,Ro] */
253 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
254 };
255 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
256 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
257 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
258 |((tinstr & 0x01C0) >> 6); /* Ro */
259 }
260 else {
261 /* Format 8 */
262 ARMword subset[4] = {
263 0xE18000B0, /* STRH Rd,[Rb,Ro] */
264 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
265 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
266 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
267 };
268 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
269 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
270 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
271 |((tinstr & 0x01C0) >> 6); /* Ro */
272 }
273 break;
274 case 12: /* STR Rd,[Rb,#imm5] */
275 case 13: /* LDR Rd,[Rb,#imm5] */
276 case 14: /* STRB Rd,[Rb,#imm5] */
277 case 15: /* LDRB Rd,[Rb,#imm5] */
278 /* Format 9 */
279 {
280 ARMword subset[4] = {
281 0xE5800000, /* STR Rd,[Rb,#imm5] */
282 0xE5900000, /* LDR Rd,[Rb,#imm5] */
283 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
284 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
285 };
286 /* The offset range defends on whether we are transferring a
287 byte or word value: */
288 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
289 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
290 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
291 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
292 }
293 break;
294 case 16: /* STRH Rd,[Rb,#imm5] */
295 case 17: /* LDRH Rd,[Rb,#imm5] */
296 /* Format 10 */
297 *ainstr = ((tinstr & (1 << 11)) /* base */
298 ? 0xE1D000B0 /* LDRH */
299 : 0xE1C000B0) /* STRH */
300 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
301 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
302 |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
303 |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
304 break;
305 case 18: /* STR Rd,[SP,#imm8] */
306 case 19: /* LDR Rd,[SP,#imm8] */
307 /* Format 11 */
308 *ainstr = ((tinstr & (1 << 11)) /* base */
309 ? 0xE59D0000 /* LDR */
310 : 0xE58D0000) /* STR */
311 |((tinstr & 0x0700) << (12 - 8)) /* Rd */
312 |((tinstr & 0x00FF) << 2); /* off8 */
313 break;
314 case 20: /* ADD Rd,PC,#imm8 */
315 case 21: /* ADD Rd,SP,#imm8 */
316 /* Format 12 */
317 if ((tinstr & (1 << 11)) == 0) {
318 /* NOTE: The PC value used here should by word aligned */
319 /* We encode shift-left-by-2 in the rotate immediate field,
320 so no shift of off8 is needed. */
321 *ainstr = 0xE28F0F00 /* base */
322 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
323 |(tinstr & 0x00FF); /* off8 */
324 }
325 else {
326 /* We encode shift-left-by-2 in the rotate immediate field,
327 so no shift of off8 is needed. */
328 *ainstr = 0xE28D0F00 /* base */
329 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
330 |(tinstr & 0x00FF); /* off8 */
331 }
332 break;
333 case 22:
334 case 23:
335 if ((tinstr & 0x0F00) == 0x0000) {
336 /* Format 13 */
337 /* NOTE: The instruction contains a shift left of 2
338 equivalent (implemented as ROR #30): */
339 *ainstr = ((tinstr & (1 << 7)) /* base */
340 ? 0xE24DDF00 /* SUB */
341 : 0xE28DDF00) /* ADD */
342 |(tinstr & 0x007F); /* off7 */
343 }
344 else if ((tinstr & 0x0F00) == 0x0e00)
345 *ainstr = 0xEF000000 | SWI_Breakpoint;
346 else {
347 /* Format 14 */
348 ARMword subset[4] = {
349 0xE92D0000, /* STMDB sp!,{rlist} */
350 0xE92D4000, /* STMDB sp!,{rlist,lr} */
351 0xE8BD0000, /* LDMIA sp!,{rlist} */
352 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
353 };
354 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
355 |(tinstr & 0x00FF); /* mask8 */
356 }
357 break;
358 case 24: /* STMIA */
359 case 25: /* LDMIA */
360 /* Format 15 */
361 *ainstr = ((tinstr & (1 << 11)) /* base */
362 ? 0xE8B00000 /* LDMIA */
363 : 0xE8A00000) /* STMIA */
364 |((tinstr & 0x0700) << (16 - 8)) /* Rb */
365 |(tinstr & 0x00FF); /* mask8 */
366 break;
367 case 26: /* Bcc */
368 case 27: /* Bcc/SWI */
369 if ((tinstr & 0x0F00) == 0x0F00) {
370 if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
371 state->AbortAddr == pc) {
372 *ainstr = ARMul_ABORTWORD;
373 break;
374 }
375 /* Format 17 : SWI */
376 *ainstr = 0xEF000000;
377 /* Breakpoint must be handled specially. */
378 if ((tinstr & 0x00FF) == 0x18)
379 *ainstr |= ((tinstr & 0x00FF) << 16);
380 /* New breakpoint value. See gdb/arm-tdep.c */
381 else if ((tinstr & 0x00FF) == 0xFE)
382 *ainstr |= SWI_Breakpoint;
383 else
384 *ainstr |= (tinstr & 0x00FF);
385 }
386 else if ((tinstr & 0x0F00) != 0x0E00) {
387 /* Format 16 */
388 int doit = FALSE;
389 /* TODO: Since we are doing a switch here, we could just add
390 the SWI and undefined instruction checks into this
391 switch to same on a couple of conditionals: */
392 switch ((tinstr & 0x0F00) >> 8) {
393 case EQ:
394 doit = ZFLAG;
395 break;
396 case NE:
397 doit = !ZFLAG;
398 break;
399 case VS:
400 doit = VFLAG;
401 break;
402 case VC:
403 doit = !VFLAG;
404 break;
405 case MI:
406 doit = NFLAG;
407 break;
408 case PL:
409 doit = !NFLAG;
410 break;
411 case CS:
412 doit = CFLAG;
413 break;
414 case CC:
415 doit = !CFLAG;
416 break;
417 case HI:
418 doit = (CFLAG && !ZFLAG);
419 break;
420 case LS:
421 doit = (!CFLAG || ZFLAG);
422 break;
423 case GE:
424 doit = ((!NFLAG && !VFLAG)
425 || (NFLAG && VFLAG));
426 break;
427 case LT:
428 doit = ((NFLAG && !VFLAG)
429 || (!NFLAG && VFLAG));
430 break;
431 case GT:
432 doit = ((!NFLAG && !VFLAG && !ZFLAG)
433 || (NFLAG && VFLAG && !ZFLAG));
434 break;
435 case LE:
436 doit = ((NFLAG && !VFLAG)
437 || (!NFLAG && VFLAG)) || ZFLAG;
438 break;
439 }
440 if (doit) {
441 state->Reg[15] = (pc + 4
442 + (((tinstr & 0x7F) << 1)
443 | ((tinstr & (1 << 7)) ?
444 0xFFFFFF00 : 0)));
445 FLUSHPIPE;
446 }
447 valid = t_branch;
448 }
449 else /* UNDEFINED : cc=1110(AL) uses different format */
450 valid = t_undefined;
451 break;
452 case 28: /* B */
453 /* Format 18 */
454 state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
455 | ((tinstr & (1 << 10)) ?
456 0xFFFFF800 : 0)));
457 FLUSHPIPE;
458 valid = t_branch;
459 break;
460 case 29:
461 if(tinstr & 0x1)
462 valid = t_undefined;
463 else{
464 /* BLX 1 for armv5t and above */
465 ARMword tmp = (pc + 2);
466 state->Reg[15] =
467 (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
468 state->Reg[14] = (tmp | 1);
469 CLEART;
470 LOG_DEBUG(Core_ARM11, "After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x", state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
471 valid = t_branch;
472 FLUSHPIPE;
473 }
474 break;
475 case 30: /* BL instruction 1 */
476 /* Format 19 */
477 /* There is no single ARM instruction equivalent for this Thumb
478 instruction. To keep the simulation simple (from the user
479 perspective) we check if the following instruction is the
480 second half of this BL, and if it is we simulate it
481 immediately. */
482 state->Reg[14] = state->Reg[15]
483 + (((tinstr & 0x07FF) << 12)
484 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
485 valid = t_branch; /* in-case we don't have the 2nd half */
486 //tinstr = next_instr; /* move the instruction down */
487 //if (((tinstr & 0xF800) >> 11) != 31)
488 // break; /* exit, since not correct instruction */
489 /* else we fall through to process the second half of the BL */
490 //pc += 2; /* point the pc at the 2nd half */
491 state->Reg[15] = pc + 2;
492 FLUSHPIPE;
493 break;
494 case 31: /* BL instruction 2 */
495 /* Format 19 */
496 /* There is no single ARM instruction equivalent for this
497 instruction. Also, it should only ever be matched with the
498 fmt19 "BL instruction 1" instruction. However, we do allow
499 the simulation of it on its own, with undefined results if
500 r14 is not suitably initialised. */
501 {
502 ARMword tmp = (pc + 2);
503 state->Reg[15] =
504 (state->Reg[14] + ((tinstr & 0x07FF) << 1));
505 state->Reg[14] = (tmp | 1);
506 valid = t_branch;
507 FLUSHPIPE;
508 }
509 break;
510 }
511
512 return valid;
513}
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index a9c41ce5a..be54ce71b 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -32,6 +32,9 @@
32#include "core/arm/skyeye_common/armmmu.h" 32#include "core/arm/skyeye_common/armmmu.h"
33#include "core/arm/skyeye_common/skyeye_defs.h" 33#include "core/arm/skyeye_common/skyeye_defs.h"
34 34
35#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
36#define BIT(s, n) ((s >> (n)) & 1)
37
35#ifndef FALSE 38#ifndef FALSE
36#define FALSE 0 39#define FALSE 0
37#define TRUE 1 40#define TRUE 1
@@ -287,15 +290,6 @@ enum {
287 ARM620 = ARM6 290 ARM620 = ARM6
288}; 291};
289 292
290
291/***************************************************************************\
292* Macros to extract instruction fields *
293\***************************************************************************/
294
295#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */
296#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */
297#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */
298
299/***************************************************************************\ 293/***************************************************************************\
300* The hardware vector addresses * 294* The hardware vector addresses *
301\***************************************************************************/ 295\***************************************************************************/
@@ -339,13 +333,6 @@ enum {
339 SYSTEM32MODE = 31 333 SYSTEM32MODE = 31
340}; 334};
341 335
342#define ARM32BITMODE (state->Mode > 3)
343#define ARM26BITMODE (state->Mode <= 3)
344#define ARMMODE (state->Mode)
345#define ARMul_MODEBITS 0x1fL
346#define ARMul_MODE32BIT ARM32BITMODE
347#define ARMul_MODE26BIT ARM26BITMODE
348
349enum { 336enum {
350 USERBANK = 0, 337 USERBANK = 0,
351 FIQBANK = 1, 338 FIQBANK = 1,
@@ -357,10 +344,6 @@ enum {
357 SYSTEMBANK = USERBANK 344 SYSTEMBANK = USERBANK
358}; 345};
359 346
360#define BANK_CAN_ACCESS_SPSR(bank) \
361 ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
362
363
364/***************************************************************************\ 347/***************************************************************************\
365* Definitons of things in the emulator * 348* Definitons of things in the emulator *
366\***************************************************************************/ 349\***************************************************************************/
@@ -372,85 +355,7 @@ extern void ARMul_Reset(ARMul_State* state);
372#ifdef __cplusplus 355#ifdef __cplusplus
373 } 356 }
374#endif 357#endif
375extern ARMul_State *ARMul_NewState(ARMul_State* state); 358extern ARMul_State* ARMul_NewState(ARMul_State* state);
376extern ARMword ARMul_DoProg(ARMul_State* state);
377extern ARMword ARMul_DoInstr(ARMul_State* state);
378
379/***************************************************************************\
380* Useful support routines *
381\***************************************************************************/
382
383extern ARMword ARMul_GetReg (ARMul_State* state, unsigned mode, unsigned reg);
384extern void ARMul_SetReg (ARMul_State* state, unsigned mode, unsigned reg, ARMword value);
385extern ARMword ARMul_GetPC(ARMul_State* state);
386extern ARMword ARMul_GetNextPC(ARMul_State* state);
387extern void ARMul_SetPC(ARMul_State* state, ARMword value);
388extern ARMword ARMul_GetR15(ARMul_State* state);
389extern void ARMul_SetR15(ARMul_State* state, ARMword value);
390
391extern ARMword ARMul_GetCPSR(ARMul_State* state);
392extern void ARMul_SetCPSR(ARMul_State* state, ARMword value);
393extern ARMword ARMul_GetSPSR(ARMul_State* state, ARMword mode);
394extern void ARMul_SetSPSR(ARMul_State* state, ARMword mode, ARMword value);
395
396/***************************************************************************\
397* Definitons of things to handle aborts *
398\***************************************************************************/
399
400extern void ARMul_Abort(ARMul_State* state, ARMword address);
401#ifdef MODET
402#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */
403#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
404 state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L))
405#else
406#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */
407#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
408 state->AbortAddr = (address & ~3L)
409#endif
410#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \
411 state->Aborted = ARMul_DataAbortV ;
412#define ARMul_CLEARABORT state->abortSig = LOW
413
414/***************************************************************************\
415* Definitons of things in the memory interface *
416\***************************************************************************/
417
418extern unsigned ARMul_MemoryInit(ARMul_State* state, unsigned int initmemsize);
419extern void ARMul_MemoryExit(ARMul_State* state);
420
421extern ARMword ARMul_LoadInstrS(ARMul_State* state, ARMword address, ARMword isize);
422extern ARMword ARMul_LoadInstrN(ARMul_State* state, ARMword address, ARMword isize);
423#ifdef __cplusplus
424extern "C" {
425#endif
426extern ARMword ARMul_ReLoadInstr(ARMul_State* state, ARMword address, ARMword isize);
427#ifdef __cplusplus
428 }
429#endif
430extern ARMword ARMul_LoadWordS(ARMul_State* state, ARMword address);
431extern ARMword ARMul_LoadWordN(ARMul_State* state, ARMword address);
432extern ARMword ARMul_LoadHalfWord(ARMul_State* state, ARMword address);
433extern ARMword ARMul_LoadByte(ARMul_State* state, ARMword address);
434
435extern void ARMul_StoreWordS(ARMul_State* state, ARMword address, ARMword data);
436extern void ARMul_StoreWordN(ARMul_State* state, ARMword address, ARMword data);
437extern void ARMul_StoreHalfWord(ARMul_State* state, ARMword address, ARMword data);
438extern void ARMul_StoreByte(ARMul_State* state, ARMword address, ARMword data);
439
440extern ARMword ARMul_SwapWord(ARMul_State* state, ARMword address, ARMword data);
441extern ARMword ARMul_SwapByte(ARMul_State* state, ARMword address, ARMword data);
442
443extern void ARMul_Icycles(ARMul_State* state, unsigned number, ARMword address);
444extern void ARMul_Ccycles(ARMul_State* state, unsigned number, ARMword address);
445
446extern ARMword ARMul_ReadWord(ARMul_State* state, ARMword address);
447extern ARMword ARMul_ReadByte(ARMul_State* state, ARMword address);
448extern void ARMul_WriteWord(ARMul_State* state, ARMword address, ARMword data);
449extern void ARMul_WriteByte(ARMul_State* state, ARMword address, ARMword data);
450
451extern ARMword ARMul_MemAccess(ARMul_State* state, ARMword, ARMword,
452 ARMword, ARMword, ARMword, ARMword, ARMword,
453 ARMword, ARMword, ARMword);
454 359
455/***************************************************************************\ 360/***************************************************************************\
456* Definitons of things in the co-processor interface * 361* Definitons of things in the co-processor interface *
@@ -495,37 +400,10 @@ enum {
495 ARMul_CP15_DBCON_E0 = 0x0003 400 ARMul_CP15_DBCON_E0 = 0x0003
496}; 401};
497 402
498extern unsigned ARMul_CoProInit(ARMul_State* state);
499extern void ARMul_CoProExit(ARMul_State* state);
500extern void ARMul_CoProAttach (ARMul_State* state, unsigned number,
501 ARMul_CPInits* init, ARMul_CPExits* exit,
502 ARMul_LDCs* ldc, ARMul_STCs* stc,
503 ARMul_MRCs* mrc, ARMul_MCRs* mcr,
504 ARMul_MRRCs* mrrc, ARMul_MCRRs* mcrr,
505 ARMul_CDPs* cdp,
506 ARMul_CPReads* read, ARMul_CPWrites* write);
507extern void ARMul_CoProDetach(ARMul_State* state, unsigned number);
508
509/***************************************************************************\ 403/***************************************************************************\
510* Definitons of things in the host environment * 404* Definitons of things in the host environment *
511\***************************************************************************/ 405\***************************************************************************/
512 406
513extern unsigned ARMul_OSInit(ARMul_State* state);
514extern void ARMul_OSExit(ARMul_State* state);
515
516#ifdef __cplusplus
517 extern "C" {
518#endif
519
520extern unsigned ARMul_OSHandleSWI(ARMul_State* state, ARMword number);
521#ifdef __cplusplus
522}
523#endif
524
525extern ARMword ARMul_OSLastErrorP(ARMul_State* state);
526extern ARMword ARMul_Debug(ARMul_State* state, ARMword pc, ARMword instr);
527extern unsigned ARMul_OSException(ARMul_State* state, ARMword vector, ARMword pc);
528
529enum ConditionCode { 407enum ConditionCode {
530 EQ = 0, 408 EQ = 0,
531 NE = 1, 409 NE = 1,
@@ -545,40 +423,9 @@ enum ConditionCode {
545 NV = 15, 423 NV = 15,
546}; 424};
547 425
548#ifndef NFLAG
549#define NFLAG state->NFlag
550#endif //NFLAG
551
552#ifndef ZFLAG
553#define ZFLAG state->ZFlag
554#endif //ZFLAG
555
556#ifndef CFLAG
557#define CFLAG state->CFlag
558#endif //CFLAG
559
560#ifndef VFLAG
561#define VFLAG state->VFlag
562#endif //VFLAG
563
564#ifndef IFLAG
565#define IFLAG (state->IFFlags >> 1)
566#endif //IFLAG
567
568#ifndef FFLAG
569#define FFLAG (state->IFFlags & 1)
570#endif //FFLAG
571
572#ifndef IFFLAGS
573#define IFFLAGS state->IFFlags
574#endif //VFLAG
575
576extern bool AddOverflow(ARMword, ARMword, ARMword); 426extern bool AddOverflow(ARMword, ARMword, ARMword);
577extern bool SubOverflow(ARMword, ARMword, ARMword); 427extern bool SubOverflow(ARMword, ARMword, ARMword);
578 428
579extern void ARMul_UndefInstr(ARMul_State*, ARMword);
580extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
581extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
582extern void ARMul_SelectProcessor(ARMul_State*, unsigned); 429extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
583 430
584extern u32 AddWithCarry(u32, u32, u32, bool*, bool*); 431extern u32 AddWithCarry(u32, u32, u32, bool*, bool*);
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
index 7e10dad86..6071d447b 100644
--- a/src/core/arm/skyeye_common/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -19,12 +19,6 @@
19 19
20#include "core/arm/skyeye_common/armdefs.h" 20#include "core/arm/skyeye_common/armdefs.h"
21 21
22/* Shift Opcodes. */
23#define LSL 0
24#define LSR 1
25#define ASR 2
26#define ROR 3
27
28/* Macros to twiddle the status flags and mode. */ 22/* Macros to twiddle the status flags and mode. */
29#define NBIT ((unsigned)1L << 31) 23#define NBIT ((unsigned)1L << 31)
30#define ZBIT (1L << 30) 24#define ZBIT (1L << 30)
@@ -38,73 +32,6 @@
38#define R15FBIT (1L << 26) 32#define R15FBIT (1L << 26)
39#define R15IFBITS (3L << 26) 33#define R15IFBITS (3L << 26)
40 34
41#ifdef MODET /* Thumb support. */
42/* ??? This bit is actually in the low order bit of the PC in the hardware.
43 It isn't clear if the simulator needs to model that or not. */
44#define TBIT (1L << 5)
45#define TFLAG state->TFlag
46#define SETT state->TFlag = 1
47#define CLEART state->TFlag = 0
48#define ASSIGNT(res) state->TFlag = res
49#define INSN_SIZE (TFLAG ? 2 : 4)
50#else
51#define INSN_SIZE 4
52#endif
53
54/*add armv6 CPSR feature*/
55#define EFLAG state->EFlag
56#define SETE state->EFlag = 1
57#define CLEARE state->EFlag = 0
58#define ASSIGNE(res) state->NFlag = res
59
60#define AFLAG state->AFlag
61#define SETA state->AFlag = 1
62#define CLEARA state->AFlag = 0
63#define ASSIGNA(res) state->NFlag = res
64
65#define QFLAG state->QFlag
66#define SETQ state->QFlag = 1
67#define CLEARQ state->AFlag = 0
68#define ASSIGNQ(res) state->QFlag = res
69
70/* add end */
71
72#define NFLAG state->NFlag
73#define SETN state->NFlag = 1
74#define CLEARN state->NFlag = 0
75#define ASSIGNN(res) state->NFlag = res
76
77#define ZFLAG state->ZFlag
78#define SETZ state->ZFlag = 1
79#define CLEARZ state->ZFlag = 0
80#define ASSIGNZ(res) state->ZFlag = res
81
82#define CFLAG state->CFlag
83#define SETC state->CFlag = 1
84#define CLEARC state->CFlag = 0
85#define ASSIGNC(res) state->CFlag = res
86
87#define VFLAG state->VFlag
88#define SETV state->VFlag = 1
89#define CLEARV state->VFlag = 0
90#define ASSIGNV(res) state->VFlag = res
91
92#define SFLAG state->SFlag
93#define SETS state->SFlag = 1
94#define CLEARS state->SFlag = 0
95#define ASSIGNS(res) state->SFlag = res
96
97#define IFLAG (state->IFFlags >> 1)
98#define FFLAG (state->IFFlags & 1)
99#define IFFLAGS state->IFFlags
100#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3)
101#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ;
102
103#define PSR_FBITS (0xff000000L)
104#define PSR_SBITS (0x00ff0000L)
105#define PSR_XBITS (0x0000ff00L)
106#define PSR_CBITS (0x000000ffL)
107
108#if defined MODE32 || defined MODET 35#if defined MODE32 || defined MODET
109#define CCBITS (0xf8000000L) 36#define CCBITS (0xf8000000L)
110#else 37#else
@@ -128,7 +55,6 @@
128#define R15PCBITS (0x03fffffcL) 55#define R15PCBITS (0x03fffffcL)
129#endif 56#endif
130 57
131#define R15PCMODEBITS (0x03ffffffL)
132#define R15MODEBITS (0x3L) 58#define R15MODEBITS (0x3L)
133 59
134#ifdef MODE32 60#ifdef MODE32
@@ -149,106 +75,7 @@
149#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) 75#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
150#define R15MODE (state->Reg[15] & R15MODEBITS) 76#define R15MODE (state->Reg[15] & R15MODEBITS)
151 77
152#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27)) 78// Different ways to start the next instruction.
153#define EINT (IFFLAGS << 6)
154#define ER15INT (IFFLAGS << 26)
155#define EMODE (state->Mode)
156#define EGEBITS (state->GEFlag & 0x000F0000)
157
158#ifdef MODET
159#define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE)
160#else
161#define CPSR (ECC | EINT | EMODE)
162#endif
163
164#ifdef MODE32
165#define PATCHR15
166#else
167#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC
168#endif
169
170#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE))
171#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS)
172#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS)
173#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS)
174#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS)
175
176#define SETR15PSR(s) \
177 do \
178 { \
179 if (state->Mode == USER26MODE) \
180 { \
181 state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \
182 ASSIGNN ((state->Reg[15] & NBIT) != 0); \
183 ASSIGNZ ((state->Reg[15] & ZBIT) != 0); \
184 ASSIGNC ((state->Reg[15] & CBIT) != 0); \
185 ASSIGNV ((state->Reg[15] & VBIT) != 0); \
186 } \
187 else \
188 { \
189 state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \
190 ARMul_R15Altered (state); \
191 } \
192 } \
193 while (0)
194
195#define SETABORT(i, m, d) \
196 do \
197 { \
198 int SETABORT_mode = (m); \
199 \
200 ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
201 ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
202 | (i) | SETABORT_mode)); \
203 state->Reg[14] = temp - (d); \
204 } \
205 while (0)
206
207#ifndef MODE32
208#define VECTORS 0x20
209#define LEGALADDR 0x03ffffff
210#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
211#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig)
212#endif
213
214#define INTERNALABORT(address) \
215 do \
216 { \
217 if (address < VECTORS) \
218 state->Aborted = ARMul_DataAbortV; \
219 else \
220 state->Aborted = ARMul_AddrExceptnV; \
221 } \
222 while (0)
223
224#ifdef MODE32
225#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV)
226#else
227#define TAKEABORT \
228 do \
229 { \
230 if (state->Aborted == ARMul_AddrExceptnV) \
231 ARMul_Abort (state, ARMul_AddrExceptnV); \
232 else \
233 ARMul_Abort (state, ARMul_DataAbortV); \
234 } \
235 while (0)
236#endif
237
238#define CPTAKEABORT \
239 do \
240 { \
241 if (!state->Aborted) \
242 ARMul_Abort (state, ARMul_UndefinedInstrV); \
243 else if (state->Aborted == ARMul_AddrExceptnV) \
244 ARMul_Abort (state, ARMul_AddrExceptnV); \
245 else \
246 ARMul_Abort (state, ARMul_DataAbortV); \
247 } \
248 while (0);
249
250
251/* Different ways to start the next instruction. */
252#define SEQ 0 79#define SEQ 0
253#define NONSEQ 1 80#define NONSEQ 1
254#define PCINCEDSEQ 2 81#define PCINCEDSEQ 2
@@ -256,349 +83,23 @@
256#define PRIMEPIPE 4 83#define PRIMEPIPE 4
257#define RESUME 8 84#define RESUME 8
258 85
259/************************************/
260/* shenoubang 2012-3-11 */
261/* for armv7 DBG DMB DSB instr*/
262/************************************/
263#define MBReqTypes_Writes 0
264#define MBReqTypes_All 1
265
266#define NORMALCYCLE state->NextInstr = 0
267#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */
268#define BUSUSEDINCPCS \
269 do \
270 { \
271 if (! state->is_v4) \
272 { \
273 /* A standard PC inc and an S cycle. */ \
274 state->Reg[15] += INSN_SIZE; \
275 state->NextInstr = (state->NextInstr & 0xff) | 2; \
276 } \
277 } \
278 while (0)
279
280#define BUSUSEDINCPCN \
281 do \
282 { \
283 if (state->is_v4) \
284 BUSUSEDN; \
285 else \
286 { \
287 /* A standard PC inc and an N cycle. */ \
288 state->Reg[15] += INSN_SIZE; \
289 state->NextInstr |= 3; \
290 } \
291 } \
292 while (0)
293
294#define INCPC \
295 do \
296 { \
297 /* A standard PC inc. */ \
298 state->Reg[15] += INSN_SIZE; \
299 state->NextInstr |= 2; \
300 } \
301 while (0)
302
303#define FLUSHPIPE state->NextInstr |= PRIMEPIPE 86#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
304 87
305/* Cycle based emulation. */ 88// Macro to rotate n right by b bits.
306
307#define OUTPUTCP(i,a,b)
308#define NCYCLE
309#define SCYCLE
310#define ICYCLE
311#define CCYCLE
312#define NEXTCYCLE(c)
313
314/* Macros to extract parts of instructions. */
315#define DESTReg (BITS (12, 15))
316#define LHSReg (BITS (16, 19))
317#define RHSReg (BITS ( 0, 3))
318
319#define DEST (state->Reg[DESTReg])
320
321#ifdef MODE32
322#ifdef MODET
323#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg]))
324#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg]))
325#else
326#define LHS (state->Reg[LHSReg])
327#define RHS (state->Reg[RHSReg])
328#endif
329#else
330#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]))
331#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg]))
332#endif
333
334#define MULDESTReg (BITS (16, 19))
335#define MULLHSReg (BITS ( 0, 3))
336#define MULRHSReg (BITS ( 8, 11))
337#define MULACCReg (BITS (12, 15))
338
339#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)])
340#define DPSImmRHS temp = BITS(0,11) ; \
341 rhs = ARMul_ImmedTable[temp] ; \
342 if (temp > 255) /* There was a shift. */ \
343 ASSIGNC (rhs >> 31) ;
344
345#ifdef MODE32
346#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
347 : GetDPRegRHS (state, instr))
348#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
349 : GetDPSRegRHS (state, instr))
350#else
351#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
352 : GetDPRegRHS (state, instr))
353#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
354 : GetDPSRegRHS (state, instr))
355#endif
356
357#define LSBase state->Reg[LHSReg]
358#define LSImmRHS (BITS(0,11))
359
360#ifdef MODE32
361#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \
362 : GetLSRegRHS (state, instr))
363#else
364#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
365 : GetLSRegRHS (state, instr))
366#endif
367
368#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \
369 (ARMword) ARMul_BitList[BITS (8, 15)] )
370#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \
371 (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0))
372
373#define SWAPSRC (state->Reg[RHSReg])
374
375#define LSCOff (BITS (0, 7) << 2)
376#define CPNum BITS (8, 11)
377
378/* Determine if access to coprocessor CP is permitted.
379 The XScale has a register in CP15 which controls access to CP0 - CP13. */
380//chy 2003-09-03, new CP_ACCESS_ALLOWED
381/*
382#define CP_ACCESS_ALLOWED(STATE, CP) \
383 ( ((CP) >= 14) \
384 || (! (STATE)->is_XScale) \
385 || (read_cp15_reg (15, 0, 1) & (1 << (CP))))
386*/
387#define CP_ACCESS_ALLOWED(STATE, CP) \
388 ( ((CP) >= 14) ) \
389
390/* Macro to rotate n right by b bits. */
391#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b)))) 89#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
392 90
393/* Macros to store results of instructions. */ 91// Values for Emulate.
394#define WRITEDEST(d) \ 92#define STOP 0 // stop
395 do \ 93#define CHANGEMODE 1 // change mode
396 { \ 94#define ONCE 2 // execute just one interation
397 if (DESTReg == 15) \ 95#define RUN 3 // continuous execution
398 WriteR15 (state, d); \
399 else \
400 DEST = d; \
401 } \
402 while (0)
403
404#define WRITESDEST(d) \
405 do \
406 { \
407 if (DESTReg == 15) \
408 WriteSR15 (state, d); \
409 else \
410 { \
411 DEST = d; \
412 ARMul_NegZero (state, d); \
413 } \
414 } \
415 while (0)
416
417#define WRITEDESTB(d) \
418 do \
419 { \
420 if (DESTReg == 15){ \
421 WriteR15Branch (state, d); \
422 } \
423 else{ \
424 DEST = d; \
425 } \
426 } \
427 while (0)
428
429#define BYTETOBUS(data) ((data & 0xff) | \
430 ((data & 0xff) << 8) | \
431 ((data & 0xff) << 16) | \
432 ((data & 0xff) << 24))
433
434#define BUSTOBYTE(address, data) \
435 do \
436 { \
437 if (state->bigendSig) \
438 temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \
439 else \
440 temp = (data >> ((address & 3) << 3)) & 0xff; \
441 } \
442 while (0)
443
444#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb)
445#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb)
446#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb)
447#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb)
448
449#define POSBRANCH ((instr & 0x7fffff) << 2)
450#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2)
451
452
453/* Values for Emulate. */
454#define STOP 0 /* stop */
455#define CHANGEMODE 1 /* change mode */
456#define ONCE 2 /* execute just one interation */
457#define RUN 3 /* continuous execution */
458
459/* Stuff that is shared across modes. */
460extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */
461extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */
462extern char ARMul_BitList[]; /* Number of bits in a byte table. */
463
464#define EVENTLISTSIZE 1024L
465
466/* Thumb support. */
467typedef enum
468{
469 t_undefined, /* Undefined Thumb instruction. */
470 t_decoded, /* Instruction decoded to ARM equivalent. */
471 t_branch /* Thumb branch (already processed). */
472}
473tdstate;
474
475/*********************************************************************************
476 * Check all the possible undef or unpredict behavior, Some of them probably is
477 * out-of-updated with the newer ISA.
478 * -- Michael.Kang
479 ********************************************************************************/
480#define UNDEF_WARNING LOG_WARNING(Core_ARM11, "undefined or unpredicted behavior for arm instruction.");
481
482/* Macros to scrutinize instructions. */
483#define UNDEF_Test UNDEF_WARNING
484//#define UNDEF_Test
485
486//#define UNDEF_Shift UNDEF_WARNING
487#define UNDEF_Shift
488 96
489//#define UNDEF_MSRPC UNDEF_WARNING 97// Stuff that is shared across modes.
490#define UNDEF_MSRPC 98extern unsigned ARMul_MultTable[]; // Number of I cycles for a mult.
99extern ARMword ARMul_ImmedTable[]; // Immediate DP LHS values.
100extern char ARMul_BitList[]; // Number of bits in a byte table.
491 101
492//#define UNDEF_MRSPC UNDEF_WARNING 102// Coprocessor support functions.
493#define UNDEF_MRSPC
494
495#define UNDEF_MULPCDest UNDEF_WARNING
496//#define UNDEF_MULPCDest
497
498#define UNDEF_MULDestEQOp1 UNDEF_WARNING
499//#define UNDEF_MULDestEQOp1
500
501//#define UNDEF_LSRBPC UNDEF_WARNING
502#define UNDEF_LSRBPC
503
504//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING
505#define UNDEF_LSRBaseEQOffWb
506
507//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING
508#define UNDEF_LSRBaseEQDestWb
509
510//#define UNDEF_LSRPCBaseWb UNDEF_WARNING
511#define UNDEF_LSRPCBaseWb
512
513//#define UNDEF_LSRPCOffWb UNDEF_WARNING
514#define UNDEF_LSRPCOffWb
515
516//#define UNDEF_LSMNoRegs UNDEF_WARNING
517#define UNDEF_LSMNoRegs
518
519//#define UNDEF_LSMPCBase UNDEF_WARNING
520#define UNDEF_LSMPCBase
521
522//#define UNDEF_LSMUserBankWb UNDEF_WARNING
523#define UNDEF_LSMUserBankWb
524
525//#define UNDEF_LSMBaseInListWb UNDEF_WARNING
526#define UNDEF_LSMBaseInListWb
527
528#define UNDEF_SWPPC UNDEF_WARNING
529//#define UNDEF_SWPPC
530
531#define UNDEF_CoProHS UNDEF_WARNING
532//#define UNDEF_CoProHS
533
534#define UNDEF_MCRPC UNDEF_WARNING
535//#define UNDEF_MCRPC
536
537//#define UNDEF_LSCPCBaseWb UNDEF_WARNING
538#define UNDEF_LSCPCBaseWb
539
540#define UNDEF_UndefNotBounced UNDEF_WARNING
541//#define UNDEF_UndefNotBounced
542
543#define UNDEF_ShortInt UNDEF_WARNING
544//#define UNDEF_ShortInt
545
546#define UNDEF_IllegalMode UNDEF_WARNING
547//#define UNDEF_IllegalMode
548
549#define UNDEF_Prog32SigChange UNDEF_WARNING
550//#define UNDEF_Prog32SigChange
551
552#define UNDEF_Data32SigChange UNDEF_WARNING
553//#define UNDEF_Data32SigChange
554
555/* Prototypes for exported functions. */
556extern unsigned ARMul_NthReg (ARMword, unsigned);
557
558/* Prototypes for exported functions. */
559#ifdef __cplusplus
560 extern "C" {
561#endif
562extern ARMword ARMul_Emulate26 (ARMul_State *);
563extern ARMword ARMul_Emulate32 (ARMul_State *);
564#ifdef __cplusplus
565 }
566#endif
567extern unsigned IntPending (ARMul_State *);
568extern void ARMul_CPSRAltered (ARMul_State *);
569extern void ARMul_R15Altered (ARMul_State *);
570extern ARMword ARMul_GetPC (ARMul_State *);
571extern ARMword ARMul_GetNextPC (ARMul_State *);
572extern ARMword ARMul_GetR15 (ARMul_State *);
573extern ARMword ARMul_GetCPSR (ARMul_State *);
574extern void ARMul_NegZero (ARMul_State *, ARMword);
575extern void ARMul_SetPC (ARMul_State *, ARMword);
576extern void ARMul_SetR15 (ARMul_State *, ARMword);
577extern void ARMul_SetCPSR (ARMul_State *, ARMword);
578extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword);
579extern void ARMul_Abort26 (ARMul_State *, ARMword);
580extern void ARMul_Abort32 (ARMul_State *, ARMword);
581extern ARMword ARMul_MRC (ARMul_State *, ARMword);
582extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *);
583extern void ARMul_CDP (ARMul_State *, ARMword);
584extern void ARMul_LDC (ARMul_State *, ARMword, ARMword);
585extern void ARMul_STC (ARMul_State *, ARMword, ARMword);
586extern void ARMul_MCR (ARMul_State *, ARMword, ARMword);
587extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword);
588extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword);
589extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
590extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword);
591extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
592extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
593extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
594extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
595extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
596extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
597extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
598extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned);
599extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword);
600
601/* Coprocessor support functions. */
602extern unsigned ARMul_CoProInit (ARMul_State *); 103extern unsigned ARMul_CoProInit (ARMul_State *);
603extern void ARMul_CoProExit (ARMul_State *); 104extern void ARMul_CoProExit (ARMul_State *);
604extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, 105extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
@@ -606,18 +107,3 @@ extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
606 ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *, 107 ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *,
607 ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *); 108 ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
608extern void ARMul_CoProDetach (ARMul_State *, unsigned); 109extern void ARMul_CoProDetach (ARMul_State *, unsigned);
609extern ARMword read_cp15_reg (unsigned, unsigned, unsigned);
610
611extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
612extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
613extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
614extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
615extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword);
616extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
617extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
618extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
619extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
620extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword);
621extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
622extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
623extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword);
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index bff296448..5f3dd4b47 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -43,12 +43,12 @@ unsigned VFPInit(ARMul_State* state)
43unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) 43unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
44{ 44{
45 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 45 /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
46 int CoProc = BITS (8, 11); /* 10 or 11 */ 46 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
47 int OPC_1 = BITS (21, 23); 47 int OPC_1 = BITS(instr, 21, 23);
48 int Rt = BITS (12, 15); 48 int Rt = BITS(instr, 12, 15);
49 int CRn = BITS (16, 19); 49 int CRn = BITS(instr, 16, 19);
50 int CRm = BITS (0, 3); 50 int CRm = BITS(instr, 0, 3);
51 int OPC_2 = BITS (5, 7); 51 int OPC_2 = BITS(instr, 5, 7);
52 52
53 /* TODO check access permission */ 53 /* TODO check access permission */
54 54
@@ -60,7 +60,7 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
60 { 60 {
61 /* VMOV r to s */ 61 /* VMOV r to s */
62 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ 62 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
63 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value); 63 VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, value);
64 return ARMul_DONE; 64 return ARMul_DONE;
65 } 65 }
66 66
@@ -79,12 +79,12 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
79unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) 79unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
80{ 80{
81 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ 81 /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
82 int CoProc = BITS (8, 11); /* 10 or 11 */ 82 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
83 int OPC_1 = BITS (21, 23); 83 int OPC_1 = BITS(instr, 21, 23);
84 int Rt = BITS (12, 15); 84 int Rt = BITS(instr, 12, 15);
85 int CRn = BITS (16, 19); 85 int CRn = BITS(instr, 16, 19);
86 int CRm = BITS (0, 3); 86 int CRm = BITS(instr, 0, 3);
87 int OPC_2 = BITS (5, 7); 87 int OPC_2 = BITS(instr, 5, 7);
88 88
89 /* TODO check access permission */ 89 /* TODO check access permission */
90 90
@@ -95,7 +95,7 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
95 { 95 {
96 /* VMOV s to r */ 96 /* VMOV s to r */
97 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ 97 /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
98 VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value); 98 VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, &value);
99 return ARMul_DONE; 99 return ARMul_DONE;
100 } 100 }
101 101
@@ -126,24 +126,24 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
126unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2) 126unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
127{ 127{
128 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 128 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
129 int CoProc = BITS (8, 11); /* 10 or 11 */ 129 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
130 int OPC_1 = BITS (4, 7); 130 int OPC_1 = BITS(instr, 4, 7);
131 int Rt = BITS (12, 15); 131 int Rt = BITS(instr, 12, 15);
132 int Rt2 = BITS (16, 19); 132 int Rt2 = BITS(instr, 16, 19);
133 int CRm = BITS (0, 3); 133 int CRm = BITS(instr, 0, 3);
134 134
135 if (CoProc == 10 || CoProc == 11) 135 if (CoProc == 10 || CoProc == 11)
136 { 136 {
137 if (CoProc == 10 && (OPC_1 & 0xD) == 1) 137 if (CoProc == 10 && (OPC_1 & 0xD) == 1)
138 { 138 {
139 VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); 139 VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
140 return ARMul_DONE; 140 return ARMul_DONE;
141 } 141 }
142 142
143 if (CoProc == 11 && (OPC_1 & 0xD) == 1) 143 if (CoProc == 11 && (OPC_1 & 0xD) == 1)
144 { 144 {
145 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ 145 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
146 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); 146 VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
147 return ARMul_DONE; 147 return ARMul_DONE;
148 } 148 }
149 } 149 }
@@ -156,11 +156,11 @@ unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32*
156unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2) 156unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
157{ 157{
158 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ 158 /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
159 int CoProc = BITS (8, 11); /* 10 or 11 */ 159 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
160 int OPC_1 = BITS (4, 7); 160 int OPC_1 = BITS(instr, 4, 7);
161 int Rt = BITS (12, 15); 161 int Rt = BITS(instr, 12, 15);
162 int Rt2 = BITS (16, 19); 162 int Rt2 = BITS(instr, 16, 19);
163 int CRm = BITS (0, 3); 163 int CRm = BITS(instr, 0, 3);
164 164
165 /* TODO check access permission */ 165 /* TODO check access permission */
166 166
@@ -170,14 +170,14 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v
170 { 170 {
171 if (CoProc == 10 && (OPC_1 & 0xD) == 1) 171 if (CoProc == 10 && (OPC_1 & 0xD) == 1)
172 { 172 {
173 VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); 173 VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
174 return ARMul_DONE; 174 return ARMul_DONE;
175 } 175 }
176 176
177 if (CoProc == 11 && (OPC_1 & 0xD) == 1) 177 if (CoProc == 11 && (OPC_1 & 0xD) == 1)
178 { 178 {
179 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ 179 /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
180 VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); 180 VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
181 return ARMul_DONE; 181 return ARMul_DONE;
182 } 182 }
183 } 183 }
@@ -190,14 +190,14 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v
190unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value) 190unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
191{ 191{
192 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ 192 /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
193 int CoProc = BITS (8, 11); /* 10 or 11 */ 193 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
194 int CRd = BITS (12, 15); 194 int CRd = BITS(instr, 12, 15);
195 int Rn = BITS (16, 19); 195 int Rn = BITS(instr, 16, 19);
196 int imm8 = BITS (0, 7); 196 int imm8 = BITS(instr, 0, 7);
197 int P = BIT(24); 197 int P = BIT(instr, 24);
198 int U = BIT(23); 198 int U = BIT(instr, 23);
199 int D = BIT(22); 199 int D = BIT(instr, 22);
200 int W = BIT(21); 200 int W = BIT(instr, 21);
201 201
202 /* TODO check access permission */ 202 /* TODO check access permission */
203 203
@@ -239,14 +239,14 @@ unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
239unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value) 239unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
240{ 240{
241 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ 241 /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
242 int CoProc = BITS (8, 11); /* 10 or 11 */ 242 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
243 int CRd = BITS (12, 15); 243 int CRd = BITS(instr, 12, 15);
244 int Rn = BITS (16, 19); 244 int Rn = BITS(instr, 16, 19);
245 int imm8 = BITS (0, 7); 245 int imm8 = BITS(instr, 0, 7);
246 int P = BIT(24); 246 int P = BIT(instr, 24);
247 int U = BIT(23); 247 int U = BIT(instr, 23);
248 int D = BIT(22); 248 int D = BIT(instr, 22);
249 int W = BIT(21); 249 int W = BIT(instr, 21);
250 250
251 /* TODO check access permission */ 251 /* TODO check access permission */
252 252
@@ -277,57 +277,12 @@ unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
277unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) 277unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
278{ 278{
279 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ 279 /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
280 int CoProc = BITS (8, 11); /* 10 or 11 */ 280 int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
281 int OPC_1 = BITS (20, 23); 281 int OPC_1 = BITS(instr, 20, 23);
282 int CRd = BITS (12, 15); 282 int CRd = BITS(instr, 12, 15);
283 int CRn = BITS (16, 19); 283 int CRn = BITS(instr, 16, 19);
284 int CRm = BITS (0, 3); 284 int CRm = BITS(instr, 0, 3);
285 int OPC_2 = BITS (5, 7); 285 int OPC_2 = BITS(instr, 5, 7);
286
287 //ichfly
288 /*if ((instr & 0x0FBF0FD0) == 0x0EB70AC0) //vcvt.f64.f32 d8, s16 (s is bit 0-3 and LSB bit 22) (d is bit 12 - 15 MSB is Bit 6)
289 {
290 struct vfp_double vdd;
291 struct vfp_single vsd;
292 int dn = BITS(12, 15) + (BIT(22) << 4);
293 int sd = (BITS(0, 3) << 1) + BIT(5);
294 s32 n = vfp_get_float(state, sd);
295 vfp_single_unpack(&vsd, n);
296 if (vsd.exponent & 0x80)
297 {
298 vdd.exponent = (vsd.exponent&~0x80) | 0x400;
299 }
300 else
301 {
302 vdd.exponent = vsd.exponent | 0x380;
303 }
304 vdd.sign = vsd.sign;
305 vdd.significand = (u64)(vsd.significand & ~0xC0000000) << 32; // I have no idea why but the 2 uppern bits are not from the significand
306 vfp_put_double(state, vfp_double_pack(&vdd), dn);
307 return ARMul_DONE;
308 }
309 if ((instr & 0x0FBF0FD0) == 0x0EB70BC0) //vcvt.f32.f64 s15, d6
310 {
311 struct vfp_double vdd;
312 struct vfp_single vsd;
313 int sd = BITS(0, 3) + (BIT(5) << 4);
314 int dn = (BITS(12, 15) << 1) + BIT(22);
315 vfp_double_unpack(&vdd, vfp_get_double(state, sd));
316 if (vdd.exponent & 0x400) //todo if the exponent is to low or to high for this convert
317 {
318 vsd.exponent = (vdd.exponent) | 0x80;
319 }
320 else
321 {
322 vsd.exponent = vdd.exponent & ~0x80;
323 }
324 vsd.exponent &= 0xFF;
325 // vsd.exponent = vdd.exponent >> 3;
326 vsd.sign = vdd.sign;
327 vsd.significand = ((u64)(vdd.significand ) >> 32)& ~0xC0000000;
328 vfp_put_float(state, vfp_single_pack(&vsd), dn);
329 return ARMul_DONE;
330 }*/
331 286
332 /* TODO check access permission */ 287 /* TODO check access permission */
333 288
@@ -335,17 +290,17 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
335 290
336 if (CoProc == 10 || CoProc == 11) 291 if (CoProc == 10 || CoProc == 11)
337 { 292 {
338 if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0) 293 if ((OPC_1 & 0xB) == 0xB && BITS(instr, 4, 7) == 0)
339 { 294 {
340 unsigned int single = BIT(8) == 0; 295 unsigned int single = BIT(instr, 8) == 0;
341 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); 296 unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
342 unsigned int imm; 297 unsigned int imm;
343 instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */ 298 instr = BITS(instr, 16, 19) << 4 | BITS(instr, 0, 3); // FIXME dirty workaround to get a correct imm
344 299
345 if (single) 300 if (single)
346 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19; 301 imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0x1f : 0)<<25 | BITS(instr, 0, 5)<<19;
347 else 302 else
348 imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16; 303 imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0xff : 0)<<22 | BITS(instr, 0, 5)<<16;
349 304
350 VMOVI(state, single, d, imm); 305 VMOVI(state, single, d, imm);
351 return ARMul_DONE; 306 return ARMul_DONE;
@@ -353,9 +308,9 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
353 308
354 if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2) 309 if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
355 { 310 {
356 unsigned int single = BIT(8) == 0; 311 unsigned int single = BIT(instr, 8) == 0;
357 unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); 312 unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
358 unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);; 313 unsigned int m = (single ? BITS(instr, 0, 3)<<1 | BIT(instr, 5) : BITS(instr, 0, 3) | BIT(instr, 5)<<4);
359 VMOVR(state, single, d, m); 314 VMOVR(state, single, d, m);
360 return ARMul_DONE; 315 return ARMul_DONE;
361 } 316 }
@@ -477,11 +432,11 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
477 static int single_reg, add, d, n, imm32, regs; 432 static int single_reg, add, d, n, imm32, regs;
478 if (type == ARMul_FIRST) 433 if (type == ARMul_FIRST)
479 { 434 {
480 single_reg = BIT(8) == 0; /* Double precision */ 435 single_reg = BIT(instr, 8) == 0; // Double precision
481 add = BIT(23); /* */ 436 add = BIT(instr, 23);
482 imm32 = BITS(0,7)<<2; /* may not be used */ 437 imm32 = BITS(instr, 0,7)<<2; // may not be used
483 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 438 d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); /* Base register */
484 n = BITS(16, 19); /* destination register */ 439 n = BITS(instr, 16, 19); // destination register
485 440
486 i = 0; 441 i = 0;
487 regs = 1; 442 regs = 1;
@@ -519,10 +474,10 @@ int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
519 static int single_regs, add, wback, d, n, imm32, regs; 474 static int single_regs, add, wback, d, n, imm32, regs;
520 if (type == ARMul_FIRST) 475 if (type == ARMul_FIRST)
521 { 476 {
522 single_regs = BIT(8) == 0; /* Single precision */ 477 single_regs = BIT(instr, 8) == 0; // Single precision
523 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 478 d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
524 imm32 = BITS(0,7)<<2; /* may not be used */ 479 imm32 = BITS(instr, 0,7)<<2; // may not be used
525 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */ 480 regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FSTMX if regs is odd
526 481
527 state->Reg[R13] = state->Reg[R13] - imm32; 482 state->Reg[R13] = state->Reg[R13] - imm32;
528 483
@@ -561,13 +516,13 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
561 static int single_regs, add, wback, d, n, imm32, regs; 516 static int single_regs, add, wback, d, n, imm32, regs;
562 if (type == ARMul_FIRST) 517 if (type == ARMul_FIRST)
563 { 518 {
564 single_regs = BIT(8) == 0; /* Single precision */ 519 single_regs = BIT(instr, 8) == 0; // Single precision
565 add = BIT(23); /* */ 520 add = BIT(instr, 23);
566 wback = BIT(21); /* write-back */ 521 wback = BIT(instr, 21); // write-back
567 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 522 d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
568 n = BITS(16, 19); /* destination register */ 523 n = BITS(instr, 16, 19); // destination register
569 imm32 = BITS(0,7) * 4; /* may not be used */ 524 imm32 = BITS(instr, 0,7) * 4; // may not be used
570 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */ 525 regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FSTMX if regs is odd
571 526
572 if (wback) { 527 if (wback) {
573 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); 528 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
@@ -610,10 +565,10 @@ int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
610 static int single_regs, add, wback, d, n, imm32, regs; 565 static int single_regs, add, wback, d, n, imm32, regs;
611 if (type == ARMul_FIRST) 566 if (type == ARMul_FIRST)
612 { 567 {
613 single_regs = BIT(8) == 0; /* Single precision */ 568 single_regs = BIT(instr, 8) == 0; // Single precision
614 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 569 d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
615 imm32 = BITS(0,7)<<2; /* may not be used */ 570 imm32 = BITS(instr, 0, 7)<<2; // may not be used
616 regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */ 571 regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FLDMX if regs is odd
617 572
618 state->Reg[R13] = state->Reg[R13] + imm32; 573 state->Reg[R13] = state->Reg[R13] + imm32;
619 574
@@ -656,11 +611,11 @@ int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
656 static int single_reg, add, d, n, imm32, regs; 611 static int single_reg, add, d, n, imm32, regs;
657 if (type == ARMul_FIRST) 612 if (type == ARMul_FIRST)
658 { 613 {
659 single_reg = BIT(8) == 0; /* Double precision */ 614 single_reg = BIT(instr, 8) == 0; // Double precision
660 add = BIT(23); /* */ 615 add = BIT(instr, 23);
661 imm32 = BITS(0,7)<<2; /* may not be used */ 616 imm32 = BITS(instr, 0, 7)<<2; // may not be used
662 d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 617 d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
663 n = BITS(16, 19); /* destination register */ 618 n = BITS(instr, 16, 19); // destination register
664 619
665 i = 0; 620 i = 0;
666 regs = 1; 621 regs = 1;
@@ -702,13 +657,13 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
702 static int single_regs, add, wback, d, n, imm32, regs; 657 static int single_regs, add, wback, d, n, imm32, regs;
703 if (type == ARMul_FIRST) 658 if (type == ARMul_FIRST)
704 { 659 {
705 single_regs = BIT(8) == 0; /* Single precision */ 660 single_regs = BIT(instr, 8) == 0; // Single precision
706 add = BIT(23); /* */ 661 add = BIT(instr, 23);
707 wback = BIT(21); /* write-back */ 662 wback = BIT(instr, 21); // write-back
708 d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ 663 d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
709 n = BITS(16, 19); /* destination register */ 664 n = BITS(instr, 16, 19); // destination register
710 imm32 = BITS(0,7) * 4; /* may not be used */ 665 imm32 = BITS(instr, 0, 7) * 4; // may not be used
711 regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */ 666 regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FLDMX if regs is odd
712 667
713 if (wback) { 668 if (wback) {
714 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); 669 state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
@@ -787,8 +742,7 @@ void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg)
787 742
788uint64_t vfp_get_double(arm_core_t* state, unsigned int reg) 743uint64_t vfp_get_double(arm_core_t* state, unsigned int reg)
789{ 744{
790 uint64_t result; 745 uint64_t result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
791 result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
792 LOG_TRACE(Core_ARM11, "VFP get double: s[%d-%d]=[%016llx]\n", reg * 2 + 1, reg * 2, result); 746 LOG_TRACE(Core_ARM11, "VFP get double: s[%d-%d]=[%016llx]\n", reg * 2 + 1, reg * 2, result);
793 return result; 747 return result;
794} 748}
diff --git a/src/core/core.cpp b/src/core/core.cpp
index e9e5c35cc..63be27be2 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -10,7 +10,6 @@
10#include "core/settings.h" 10#include "core/settings.h"
11#include "core/arm/arm_interface.h" 11#include "core/arm/arm_interface.h"
12#include "core/arm/disassembler/arm_disasm.h" 12#include "core/arm/disassembler/arm_disasm.h"
13#include "core/arm/interpreter/arm_interpreter.h"
14#include "core/arm/dyncom/arm_dyncom.h" 13#include "core/arm/dyncom/arm_dyncom.h"
15#include "core/hle/hle.h" 14#include "core/hle/hle.h"
16#include "core/hle/kernel/thread.h" 15#include "core/hle/kernel/thread.h"
@@ -59,17 +58,8 @@ void Stop() {
59int Init() { 58int Init() {
60 LOG_DEBUG(Core, "initialized OK"); 59 LOG_DEBUG(Core, "initialized OK");
61 60
62 g_sys_core = new ARM_Interpreter(); 61 g_sys_core = new ARM_DynCom();
63 62 g_app_core = new ARM_DynCom();
64 switch (Settings::values.cpu_core) {
65 case CPU_Interpreter:
66 g_app_core = new ARM_DynCom();
67 break;
68 case CPU_OldInterpreter:
69 default:
70 g_app_core = new ARM_Interpreter();
71 break;
72 }
73 63
74 return 0; 64 return 0;
75} 65}
diff --git a/src/core/core.h b/src/core/core.h
index 2f5e8bc6b..8504bb2d9 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -12,11 +12,6 @@ class ARM_Interface;
12 12
13namespace Core { 13namespace Core {
14 14
15enum CPUCore {
16 CPU_Interpreter,
17 CPU_OldInterpreter,
18};
19
20struct ThreadContext { 15struct ThreadContext {
21 u32 cpu_registers[13]; 16 u32 cpu_registers[13];
22 u32 sp; 17 u32 sp;
diff --git a/src/core/settings.h b/src/core/settings.h
index 4b8928847..cedba3a98 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -29,7 +29,6 @@ struct Values {
29 int pad_sright_key; 29 int pad_sright_key;
30 30
31 // Core 31 // Core
32 int cpu_core;
33 int gpu_refresh_rate; 32 int gpu_refresh_rate;
34 int frame_skip; 33 int frame_skip;
35 34