2961
|
1 /*
|
|
2 Copyright (C) 2006 yopyop
|
|
3 yopyop156@ifrance.com
|
|
4 yopyop156.ifrance.com
|
|
5
|
|
6 Code added on 18/08/2006 by shash
|
|
7 - Missing missaligned addresses correction
|
|
8 (reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments)
|
|
9
|
|
10 This file is part of DeSmuME
|
|
11
|
|
12 DeSmuME is free software; you can redistribute it and/or modify
|
|
13 it under the terms of the GNU General Public License as published by
|
|
14 the Free Software Foundation; either version 2 of the License, or
|
|
15 (at your option) any later version.
|
|
16
|
|
17 DeSmuME is distributed in the hope that it will be useful,
|
|
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 GNU General Public License for more details.
|
|
21
|
|
22 You should have received a copy of the GNU General Public License
|
|
23 along with DeSmuME; if not, write to the Free Software
|
|
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
25 */
|
|
26
|
|
27 #include "bios.h"
|
|
28 #include "debug.h"
|
|
29 #include "MMU.h"
|
|
30
|
|
31 #define REG_NUM(i, n) (((i)>>n)&0x7)
|
|
32
|
|
33 extern BOOL execute;
|
|
34
|
|
35 // Use this macros for reading/writing, so the GDB stub isn't broken
|
|
36 #ifdef GDB_STUB
|
|
37 #define READ32(a,b) cpu->mem_if->read32(a,b)
|
|
38 #define WRITE32(a,b,c) cpu->mem_if->write32(a,b,c)
|
|
39 #define READ16(a,b) cpu->mem_if->read16(a,b)
|
|
40 #define WRITE16(a,b,c) cpu->mem_if->write16(a,b,c)
|
|
41 #define READ8(a,b) cpu->mem_if->read8(a,b)
|
|
42 #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c)
|
|
43 #else
|
|
44 #define READ32(a,b) MMU_read32(cpu->proc_ID, b)
|
|
45 #define WRITE32(a,b,c) MMU_write32(cpu->proc_ID,b,c)
|
|
46 #define READ16(a,b) MMU_read16(cpu->proc_ID, b)
|
|
47 #define WRITE16(a,b,c) MMU_write16(cpu->proc_ID,b,c)
|
|
48 #define READ8(a,b) MMU_read8(cpu->proc_ID, b)
|
|
49 #define WRITE8(a,b,c) MMU_write8(cpu->proc_ID,b,c)
|
|
50 #endif
|
|
51
|
|
52 static u32 FASTCALL OP_UND_THUMB(armcpu_t *cpu)
|
|
53 {
|
|
54 execute = FALSE;
|
|
55 return 1;
|
|
56 }
|
|
57
|
|
58 static u32 FASTCALL OP_LSL_0(armcpu_t *cpu)
|
|
59 {
|
|
60 u32 i = cpu->instruction;
|
|
61 cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)];
|
|
62 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
63 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
64
|
|
65 return 2;
|
|
66 }
|
|
67
|
|
68 static u32 FASTCALL OP_LSL(armcpu_t *cpu)
|
|
69 {
|
|
70 u32 i = cpu->instruction;
|
|
71 u32 v = (i>>6) & 0x1F;
|
|
72 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v);
|
|
73 cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v);
|
|
74 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
75 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
76
|
|
77 return 2;
|
|
78 }
|
|
79
|
|
80 static u32 FASTCALL OP_LSR_0(armcpu_t *cpu)
|
|
81 {
|
|
82 u32 i = cpu->instruction;
|
|
83 // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
84 cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
|
|
85 cpu->R[REG_NUM(i, 0)] = 0;
|
|
86 cpu->CPSR.bits.N = 0;
|
|
87 cpu->CPSR.bits.Z = 1;
|
|
88
|
|
89 return 2;
|
|
90 }
|
|
91
|
|
92 static u32 FASTCALL OP_LSR(armcpu_t *cpu)
|
|
93 {
|
|
94 u32 i = cpu->instruction;
|
|
95 u32 v = (i>>6) & 0x1F;
|
|
96 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
|
|
97 cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v);
|
|
98 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
99 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
100
|
|
101 return 2;
|
|
102 }
|
|
103
|
|
104 static u32 FASTCALL OP_ASR_0(armcpu_t *cpu)
|
|
105 {
|
|
106 u32 i = cpu->instruction;
|
|
107 cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]);
|
|
108 cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF;
|
|
109 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
110 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
111
|
|
112 return 2;
|
|
113 }
|
|
114
|
|
115 static u32 FASTCALL OP_ASR(armcpu_t *cpu)
|
|
116 {
|
|
117 u32 i = cpu->instruction;
|
|
118 u32 v = (i>>6) & 0x1F;
|
|
119 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1);
|
|
120 cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v);
|
|
121 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
122 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
123
|
|
124 return 2;
|
|
125 }
|
|
126
|
|
127 static u32 FASTCALL OP_ADD_REG(armcpu_t *cpu)
|
|
128 {
|
|
129 u32 i = cpu->instruction;
|
|
130 u32 a = cpu->R[REG_NUM(i, 3)];
|
|
131 u32 b = cpu->R[REG_NUM(i, 6)];
|
|
132 cpu->R[REG_NUM(i, 0)] = a + b;
|
|
133 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
134 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
135 cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
|
|
136 cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
|
|
137
|
|
138 return 3;
|
|
139 }
|
|
140
|
|
141 static u32 FASTCALL OP_SUB_REG(armcpu_t *cpu)
|
|
142 {
|
|
143 u32 i = cpu->instruction;
|
|
144 u32 a = cpu->R[REG_NUM(i, 3)];
|
|
145 u32 b = cpu->R[REG_NUM(i, 6)];
|
|
146 cpu->R[REG_NUM(i, 0)] = a - b;
|
|
147 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
148 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
149 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
|
|
150 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]);
|
|
151
|
|
152 return 3;
|
|
153 }
|
|
154
|
|
155 static u32 FASTCALL OP_ADD_IMM3(armcpu_t *cpu)
|
|
156 {
|
|
157 u32 i = cpu->instruction;
|
|
158 u32 a = cpu->R[REG_NUM(i, 3)];
|
|
159 cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6);
|
|
160 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
161 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
162 cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
|
|
163 cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
|
|
164
|
|
165 return 2;
|
|
166 }
|
|
167
|
|
168 static u32 FASTCALL OP_SUB_IMM3(armcpu_t *cpu)
|
|
169 {
|
|
170 u32 i = cpu->instruction;
|
|
171 u32 a = cpu->R[REG_NUM(i, 3)];
|
|
172 cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6);
|
|
173 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
174 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
175 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
|
|
176 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]);
|
|
177
|
|
178 return 2;
|
|
179 }
|
|
180
|
|
181 static u32 FASTCALL OP_MOV_IMM8(armcpu_t *cpu)
|
|
182 {
|
|
183 u32 i = cpu->instruction;
|
|
184 cpu->R[REG_NUM(i, 8)] = i & 0xFF;
|
|
185 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]);
|
|
186 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0;
|
|
187
|
|
188 return 2;
|
|
189 }
|
|
190
|
|
191 static u32 FASTCALL OP_CMP_IMM8(armcpu_t *cpu)
|
|
192 {
|
|
193 u32 i = cpu->instruction;
|
|
194 u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
|
|
195 cpu->CPSR.bits.N = BIT31(tmp);
|
|
196 cpu->CPSR.bits.Z = tmp == 0;
|
|
197 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
198 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
199
|
|
200 return 2;
|
|
201 }
|
|
202
|
|
203 static u32 FASTCALL OP_ADD_IMM8(armcpu_t *cpu)
|
|
204 {
|
|
205 u32 i = cpu->instruction;
|
|
206 u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF);
|
|
207 cpu->CPSR.bits.N = BIT31(tmp);
|
|
208 cpu->CPSR.bits.Z = tmp == 0;
|
|
209 cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
210 cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
211 cpu->R[REG_NUM(i, 8)] = tmp;
|
|
212
|
|
213 return 2;
|
|
214 }
|
|
215
|
|
216 static u32 FASTCALL OP_SUB_IMM8(armcpu_t *cpu)
|
|
217 {
|
|
218 u32 i = cpu->instruction;
|
|
219 u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF);
|
|
220 cpu->CPSR.bits.N = BIT31(tmp);
|
|
221 cpu->CPSR.bits.Z = tmp == 0;
|
|
222 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
223 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp);
|
|
224 cpu->R[REG_NUM(i, 8)] = tmp;
|
|
225
|
|
226 return 2;
|
|
227 }
|
|
228
|
|
229 static u32 FASTCALL OP_AND(armcpu_t *cpu)
|
|
230 {
|
|
231 u32 i = cpu->instruction;
|
|
232 cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)];
|
|
233 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
234 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
235
|
|
236 return 3;
|
|
237 }
|
|
238
|
|
239 static u32 FASTCALL OP_EOR(armcpu_t *cpu)
|
|
240 {
|
|
241 u32 i = cpu->instruction;
|
|
242 cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)];
|
|
243 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
244 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
245
|
|
246 return 3;
|
|
247 }
|
|
248
|
|
249 static u32 FASTCALL OP_LSL_REG(armcpu_t *cpu)
|
|
250 {
|
|
251 u32 i = cpu->instruction;
|
|
252 u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
|
|
253
|
|
254 if(!v)
|
|
255 {
|
|
256 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
257 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
258 return 3;
|
|
259 }
|
|
260 if(v<32)
|
|
261 {
|
|
262 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v);
|
|
263 cpu->R[REG_NUM(i, 0)] <<= v;
|
|
264 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
265 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
266 return 3;
|
|
267 }
|
|
268 if(v==32)
|
|
269 cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]);
|
|
270 else
|
|
271 cpu->CPSR.bits.C = 0;
|
|
272 cpu->R[REG_NUM(i, 0)] = 0;
|
|
273 cpu->CPSR.bits.N = 0;
|
|
274 cpu->CPSR.bits.Z = 1;
|
|
275
|
|
276 return 3;
|
|
277 }
|
|
278
|
|
279 static u32 FASTCALL OP_LSR_REG(armcpu_t *cpu)
|
|
280 {
|
|
281 u32 i = cpu->instruction;
|
|
282 u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
|
|
283
|
|
284 if(!v)
|
|
285 {
|
|
286 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
287 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
288 return 3;
|
|
289 }
|
|
290 if(v<32)
|
|
291 {
|
|
292 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
|
|
293 cpu->R[REG_NUM(i, 0)] >>= v;
|
|
294 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
295 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
296 return 3;
|
|
297 }
|
|
298 if(v==32)
|
|
299 cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
300 else
|
|
301 cpu->CPSR.bits.C = 0;
|
|
302 cpu->R[REG_NUM(i, 0)] = 0;
|
|
303 cpu->CPSR.bits.N = 0;
|
|
304 cpu->CPSR.bits.Z = 1;
|
|
305
|
|
306 return 3;
|
|
307 }
|
|
308
|
|
309 static u32 FASTCALL OP_ASR_REG(armcpu_t *cpu)
|
|
310 {
|
|
311 u32 i = cpu->instruction;
|
|
312 u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
|
|
313
|
|
314 if(!v)
|
|
315 {
|
|
316 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
317 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
318 return 3;
|
|
319 }
|
|
320 if(v<32)
|
|
321 {
|
|
322 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
|
|
323 cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v);
|
|
324 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
325 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
326 return 3;
|
|
327 }
|
|
328
|
|
329 cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
330 cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF;
|
|
331 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
332 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
333
|
|
334 return 3;
|
|
335 }
|
|
336
|
|
337 static u32 FASTCALL OP_ADC_REG(armcpu_t *cpu)
|
|
338 {
|
|
339 u32 i = cpu->instruction;
|
|
340 u32 a = cpu->R[REG_NUM(i, 0)];
|
|
341 u32 b = cpu->R[REG_NUM(i, 3)];
|
|
342 u32 tmp = b + cpu->CPSR.bits.C;
|
|
343 u32 res = a + tmp;
|
|
344
|
|
345 cpu->R[REG_NUM(i, 0)] = res;
|
|
346
|
|
347 cpu->CPSR.bits.N = BIT31(res);
|
|
348 cpu->CPSR.bits.Z = res == 0;
|
|
349
|
|
350 cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res);
|
|
351 cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res);
|
|
352
|
|
353 return 3;
|
|
354 }
|
|
355
|
|
356 static u32 FASTCALL OP_SBC_REG(armcpu_t *cpu)
|
|
357 {
|
|
358 u32 i = cpu->instruction;
|
|
359 u32 a = cpu->R[REG_NUM(i, 0)];
|
|
360 u32 b = cpu->R[REG_NUM(i, 3)];
|
|
361 u32 tmp = a - (!cpu->CPSR.bits.C);
|
|
362 u32 res = tmp - b;
|
|
363 cpu->R[REG_NUM(i, 0)] = res;
|
|
364
|
|
365 cpu->CPSR.bits.N = BIT31(res);
|
|
366 cpu->CPSR.bits.Z = res == 0;
|
|
367
|
|
368 cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res));
|
|
369 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, !cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, b, res);
|
|
370
|
|
371 return 3;
|
|
372 }
|
|
373
|
|
374 static u32 FASTCALL OP_ROR_REG(armcpu_t *cpu)
|
|
375 {
|
|
376 u32 i = cpu->instruction;
|
|
377 u32 v = cpu->R[REG_NUM(i, 3)]&0xFF;
|
|
378
|
|
379 if(v == 0)
|
|
380 {
|
|
381 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
382 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
383 return 3;
|
|
384 }
|
|
385 v &= 0xF;
|
|
386 if(v == 0)
|
|
387 {
|
|
388 cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
389 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
390 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
391 return 3;
|
|
392 }
|
|
393 cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1);
|
|
394 cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v);
|
|
395 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
396 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
397
|
|
398 return 3;
|
|
399 }
|
|
400
|
|
401 static u32 FASTCALL OP_TST(armcpu_t *cpu)
|
|
402 {
|
|
403 u32 i = cpu->instruction;
|
|
404 u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)];
|
|
405 cpu->CPSR.bits.N = BIT31(tmp);
|
|
406 cpu->CPSR.bits.Z = tmp == 0;
|
|
407
|
|
408 return 3;
|
|
409 }
|
|
410
|
|
411 static u32 FASTCALL OP_NEG(armcpu_t *cpu)
|
|
412 {
|
|
413 u32 i = cpu->instruction;
|
|
414 u32 a = cpu->R[REG_NUM(i, 3)];
|
|
415 cpu->R[REG_NUM(i, 0)] = -((signed int)a);
|
|
416
|
|
417 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
418 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
419 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
|
|
420 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(0, a, cpu->R[REG_NUM(i, 0)]);
|
|
421
|
|
422 return 3;
|
|
423 }
|
|
424
|
|
425 static u32 FASTCALL OP_CMP(armcpu_t *cpu)
|
|
426 {
|
|
427 u32 i = cpu->instruction;
|
|
428 u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)];
|
|
429
|
|
430 cpu->CPSR.bits.N = BIT31(tmp);
|
|
431 cpu->CPSR.bits.Z = tmp == 0;
|
|
432 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
|
|
433 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
|
|
434
|
|
435 return 3;
|
|
436 }
|
|
437
|
|
438 static u32 FASTCALL OP_CMN(armcpu_t *cpu)
|
|
439 {
|
|
440 u32 i = cpu->instruction;
|
|
441 u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)];
|
|
442
|
|
443 //execute = FALSE;
|
|
444 //log::ajouter("OP_CMN THUMB");
|
|
445 cpu->CPSR.bits.N = BIT31(tmp);
|
|
446 cpu->CPSR.bits.Z = tmp == 0;
|
|
447 cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
|
|
448 cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp);
|
|
449
|
|
450 return 3;
|
|
451 }
|
|
452
|
|
453 static u32 FASTCALL OP_ORR(armcpu_t *cpu)
|
|
454 {
|
|
455 u32 i = cpu->instruction;
|
|
456 cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)];
|
|
457 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
458 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
459
|
|
460 return 3;
|
|
461 }
|
|
462
|
|
463 static u32 FASTCALL OP_MUL_REG(armcpu_t *cpu)
|
|
464 {
|
|
465 u32 i = cpu->instruction;
|
|
466 cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)];
|
|
467 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
468 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
469
|
|
470 return 3;
|
|
471 }
|
|
472
|
|
473 static u32 FASTCALL OP_BIC(armcpu_t *cpu)
|
|
474 {
|
|
475 u32 i = cpu->instruction;
|
|
476 cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]);
|
|
477 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
478 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
479
|
|
480 return 3;
|
|
481 }
|
|
482
|
|
483 static u32 FASTCALL OP_MVN(armcpu_t *cpu)
|
|
484 {
|
|
485 u32 i = cpu->instruction;
|
|
486 cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]);
|
|
487 cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]);
|
|
488 cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0;
|
|
489
|
|
490 return 3;
|
|
491 }
|
|
492
|
|
493 static u32 FASTCALL OP_ADD_SPE(armcpu_t *cpu)
|
|
494 {
|
|
495 u32 i = cpu->instruction;
|
|
496 u32 Rd = (i&7) | ((i>>4)&8);
|
|
497 cpu->R[Rd] += cpu->R[REG_POS(i, 3)];
|
|
498
|
|
499 if(Rd==15)
|
|
500 cpu->next_instruction = cpu->R[15];
|
|
501
|
|
502 return 2;
|
|
503 }
|
|
504
|
|
505 static u32 FASTCALL OP_CMP_SPE(armcpu_t *cpu)
|
|
506 {
|
|
507 u32 i = cpu->instruction;
|
|
508 u32 Rn = (i&7) | ((i>>4)&8);
|
|
509 u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)];
|
|
510
|
|
511 cpu->CPSR.bits.N = BIT31(tmp);
|
|
512 cpu->CPSR.bits.Z = tmp == 0;
|
|
513 cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
|
|
514 cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp);
|
|
515
|
|
516 return 3;
|
|
517 }
|
|
518
|
|
519 static u32 FASTCALL OP_MOV_SPE(armcpu_t *cpu)
|
|
520 {
|
|
521 u32 i = cpu->instruction;
|
|
522 u32 Rd = (i&7) | ((i>>4)&8);
|
|
523 cpu->R[Rd] = cpu->R[REG_POS(i, 3)];
|
|
524
|
|
525 if(Rd==15)
|
|
526 cpu->next_instruction = cpu->R[15];
|
|
527
|
|
528 return 2;
|
|
529 }
|
|
530
|
|
531 static u32 FASTCALL OP_BX_THUMB(armcpu_t *cpu)
|
|
532 {
|
|
533 u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
|
|
534
|
|
535 cpu->CPSR.bits.T = BIT0(Rm);
|
|
536 cpu->R[15] = (Rm & 0xFFFFFFFE);
|
|
537 cpu->next_instruction = cpu->R[15];
|
|
538
|
|
539 return 3;
|
|
540 }
|
|
541
|
|
542 static u32 FASTCALL OP_BLX_THUMB(armcpu_t *cpu)
|
|
543 {
|
|
544 u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)];
|
|
545
|
|
546 cpu->CPSR.bits.T = BIT0(Rm);
|
|
547 cpu->R[14] = cpu->next_instruction | 1;
|
|
548 cpu->R[15] = (Rm & 0xFFFFFFFE);
|
|
549 cpu->next_instruction = cpu->R[15];
|
|
550
|
|
551 return 3;
|
|
552 }
|
|
553
|
|
554 static u32 FASTCALL OP_LDR_PCREL(armcpu_t *cpu)
|
|
555 {
|
|
556 u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2);
|
|
557
|
|
558 cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr);
|
|
559
|
|
560 return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
561 }
|
|
562
|
|
563 static u32 FASTCALL OP_STR_REG_OFF(armcpu_t *cpu)
|
|
564 {
|
|
565 u32 i = cpu->instruction;
|
|
566 u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)];
|
|
567 WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
|
|
568
|
|
569 return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
570 }
|
|
571
|
|
572 static u32 FASTCALL OP_STRH_REG_OFF(armcpu_t *cpu)
|
|
573 {
|
|
574 u32 i = cpu->instruction;
|
|
575 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
576 WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)]));
|
|
577
|
|
578 return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
579 }
|
|
580
|
|
581 static u32 FASTCALL OP_STRB_REG_OFF(armcpu_t *cpu)
|
|
582 {
|
|
583 u32 i = cpu->instruction;
|
|
584 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
585 WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)]));
|
|
586
|
|
587 return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
588 }
|
|
589
|
|
590 static u32 FASTCALL OP_LDRSB_REG_OFF(armcpu_t *cpu)
|
|
591 {
|
|
592 u32 i = cpu->instruction;
|
|
593 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
594 cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr));
|
|
595
|
|
596 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
597 }
|
|
598
|
|
599 static u32 FASTCALL OP_LDR_REG_OFF(armcpu_t *cpu)
|
|
600 {
|
|
601 u32 i = cpu->instruction;
|
|
602 u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]);
|
|
603 u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
|
|
604
|
|
605 adr = (adr&3)*8;
|
|
606 tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
|
|
607 cpu->R[REG_NUM(i, 0)] = tempValue;
|
|
608
|
|
609 return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
610 }
|
|
611
|
|
612 static u32 FASTCALL OP_LDRH_REG_OFF(armcpu_t *cpu)
|
|
613 {
|
|
614 u32 i = cpu->instruction;
|
|
615 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
616 cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr);
|
|
617
|
|
618 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
619 }
|
|
620
|
|
621 static u32 FASTCALL OP_LDRB_REG_OFF(armcpu_t *cpu)
|
|
622 {
|
|
623 u32 i = cpu->instruction;
|
|
624 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
625 cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr);
|
|
626
|
|
627 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
628 }
|
|
629
|
|
630 static u32 FASTCALL OP_LDRSH_REG_OFF(armcpu_t *cpu)
|
|
631 {
|
|
632 u32 i = cpu->instruction;
|
|
633 u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)];
|
|
634 cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr));
|
|
635
|
|
636 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
637 }
|
|
638
|
|
639 static u32 FASTCALL OP_STR_IMM_OFF(armcpu_t *cpu)
|
|
640 {
|
|
641 u32 i = cpu->instruction;
|
|
642 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
|
|
643 WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]);
|
|
644
|
|
645 return 2 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
646 }
|
|
647
|
|
648 static u32 FASTCALL OP_LDR_IMM_OFF(armcpu_t *cpu)
|
|
649 {
|
|
650 u32 i = cpu->instruction;
|
|
651 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C);
|
|
652 u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC);
|
|
653 adr = (adr&3)*8;
|
|
654 tempValue = (tempValue>>adr) | (tempValue<<(32-adr));
|
|
655 cpu->R[REG_NUM(i, 0)] = tempValue;
|
|
656
|
|
657 return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
658 }
|
|
659
|
|
660 static u32 FASTCALL OP_STRB_IMM_OFF(armcpu_t *cpu)
|
|
661 {
|
|
662 u32 i = cpu->instruction;
|
|
663 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
|
|
664 WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]);
|
|
665
|
|
666 return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
667 }
|
|
668
|
|
669 static u32 FASTCALL OP_LDRB_IMM_OFF(armcpu_t *cpu)
|
|
670 {
|
|
671 u32 i = cpu->instruction;
|
|
672 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F);
|
|
673 cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr);
|
|
674
|
|
675 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
676 }
|
|
677
|
|
678 static u32 FASTCALL OP_STRH_IMM_OFF(armcpu_t *cpu)
|
|
679 {
|
|
680 u32 i = cpu->instruction;
|
|
681 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
|
|
682 WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]);
|
|
683
|
|
684 return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
685 }
|
|
686
|
|
687 static u32 FASTCALL OP_LDRH_IMM_OFF(armcpu_t *cpu)
|
|
688 {
|
|
689 u32 i = cpu->instruction;
|
|
690 u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E);
|
|
691 cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr);
|
|
692
|
|
693 return 3 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
694 }
|
|
695
|
|
696 static u32 FASTCALL OP_STR_SPREL(armcpu_t *cpu)
|
|
697 {
|
|
698 u32 i = cpu->instruction;
|
|
699 u32 adr = cpu->R[13] + ((i&0xFF)<<2);
|
|
700 WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]);
|
|
701
|
|
702 return 2 + MMU.MMU_WAIT16[cpu->proc_ID][(adr>>24)&0xF];
|
|
703 }
|
|
704
|
|
705 static u32 FASTCALL OP_LDR_SPREL(armcpu_t *cpu)
|
|
706 {
|
|
707 u32 i = cpu->instruction;
|
|
708 u32 adr = cpu->R[13] + ((i&0xFF)<<2);
|
|
709 cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr);
|
|
710
|
|
711 return 3 + MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
712 }
|
|
713
|
|
714 static u32 FASTCALL OP_ADD_2PC(armcpu_t *cpu)
|
|
715 {
|
|
716 u32 i = cpu->instruction;
|
|
717 cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2);
|
|
718
|
|
719 return 5;
|
|
720 }
|
|
721
|
|
722 static u32 FASTCALL OP_ADD_2SP(armcpu_t *cpu)
|
|
723 {
|
|
724 u32 i = cpu->instruction;
|
|
725 cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2);
|
|
726
|
|
727 return 2;
|
|
728 }
|
|
729
|
|
730 static u32 FASTCALL OP_ADJUST_P_SP(armcpu_t *cpu)
|
|
731 {
|
|
732 cpu->R[13] += ((cpu->instruction&0x7F)<<2);
|
|
733
|
|
734 return 1;
|
|
735 }
|
|
736
|
|
737 static u32 FASTCALL OP_ADJUST_M_SP(armcpu_t *cpu)
|
|
738 {
|
|
739 cpu->R[13] -= ((cpu->instruction&0x7F)<<2);
|
|
740
|
|
741 return 1;
|
|
742 }
|
|
743
|
|
744 static u32 FASTCALL OP_PUSH(armcpu_t *cpu)
|
|
745 {
|
|
746 u32 i = cpu->instruction;
|
|
747 u32 adr = cpu->R[13] - 4;
|
|
748 u32 c = 0, j;
|
|
749
|
|
750 for(j = 0; j<8; ++j)
|
|
751 if(BIT_N(i, 7-j))
|
|
752 {
|
|
753 WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
|
|
754 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
755 adr -= 4;
|
|
756 }
|
|
757 cpu->R[13] = adr + 4;
|
|
758
|
|
759 return c + 3;
|
|
760 }
|
|
761
|
|
762 static u32 FASTCALL OP_PUSH_LR(armcpu_t *cpu)
|
|
763 {
|
|
764 u32 i = cpu->instruction;
|
|
765 u32 adr = cpu->R[13] - 4;
|
|
766 u32 c = 0, j;
|
|
767
|
|
768 WRITE32(cpu->mem_if->data, adr, cpu->R[14]);
|
|
769 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
770 adr -= 4;
|
|
771
|
|
772 for(j = 0; j<8; ++j)
|
|
773 if(BIT_N(i, 7-j))
|
|
774 {
|
|
775 WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]);
|
|
776 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
777 adr -= 4;
|
|
778 }
|
|
779 cpu->R[13] = adr + 4;
|
|
780
|
|
781 return c + 4;
|
|
782 }
|
|
783
|
|
784 static u32 FASTCALL OP_POP(armcpu_t *cpu)
|
|
785 {
|
|
786 u32 i = cpu->instruction;
|
|
787 u32 adr = cpu->R[13];
|
|
788 u32 c = 0, j;
|
|
789
|
|
790 for(j = 0; j<8; ++j)
|
|
791 if(BIT_N(i, j))
|
|
792 {
|
|
793 cpu->R[j] = READ32(cpu->mem_if->data, adr);
|
|
794 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
795 adr += 4;
|
|
796 }
|
|
797 cpu->R[13] = adr;
|
|
798
|
|
799 return c + 2;
|
|
800 }
|
|
801
|
|
802 static u32 FASTCALL OP_POP_PC(armcpu_t *cpu)
|
|
803 {
|
|
804 u32 i = cpu->instruction;
|
|
805 u32 adr = cpu->R[13];
|
|
806 u32 c = 0, j;
|
|
807 u32 v;
|
|
808
|
|
809 for(j = 0; j<8; ++j)
|
|
810 if(BIT_N(i, j))
|
|
811 {
|
|
812 cpu->R[j] = READ32(cpu->mem_if->data, adr);
|
|
813 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
814 adr += 4;
|
|
815 }
|
|
816
|
|
817 v = READ32(cpu->mem_if->data, adr);
|
|
818 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
819 cpu->R[15] = v & 0xFFFFFFFE;
|
|
820 cpu->next_instruction = v & 0xFFFFFFFE;
|
|
821 if(cpu->proc_ID==0)
|
|
822 cpu->CPSR.bits.T = BIT0(v);
|
|
823 adr += 4;
|
|
824
|
|
825 cpu->R[13] = adr;
|
|
826 return c + 5;
|
|
827 }
|
|
828
|
|
829 static u32 FASTCALL OP_BKPT_THUMB(armcpu_t *cpu)
|
|
830 {
|
|
831 return 1;
|
|
832 }
|
|
833
|
|
834 static u32 FASTCALL OP_STMIA_THUMB(armcpu_t *cpu)
|
|
835 {
|
|
836 u32 i = cpu->instruction;
|
|
837 u32 adr = cpu->R[REG_NUM(i, 8)];
|
|
838 u32 c = 0, j;
|
|
839
|
|
840 for(j = 0; j<8; ++j)
|
|
841 if(BIT_N(i, j))
|
|
842 {
|
|
843 WRITE32(cpu->mem_if->data, adr, cpu->R[j]);
|
|
844 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
845 adr += 4;
|
|
846 }
|
|
847 cpu->R[REG_NUM(i, 8)] = adr;
|
|
848 return c + 2;
|
|
849 }
|
|
850
|
|
851 static u32 FASTCALL OP_LDMIA_THUMB(armcpu_t *cpu)
|
|
852 {
|
|
853 u32 i = cpu->instruction;
|
|
854 u32 adr = cpu->R[REG_NUM(i, 8)];
|
|
855 u32 c = 0, j;
|
|
856
|
|
857 for(j = 0; j<8; ++j)
|
|
858 if(BIT_N(i, j))
|
|
859 {
|
|
860 cpu->R[j] = READ32(cpu->mem_if->data, adr);
|
|
861 c += MMU.MMU_WAIT32[cpu->proc_ID][(adr>>24)&0xF];
|
|
862 adr += 4;
|
|
863 }
|
|
864 cpu->R[REG_NUM(i, 8)] = adr;
|
|
865 return c + 3;
|
|
866 }
|
|
867
|
|
868 static u32 FASTCALL OP_B_COND(armcpu_t *cpu)
|
|
869 {
|
|
870 u32 i = cpu->instruction;
|
|
871 if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR))
|
|
872 return 1;
|
|
873
|
|
874 cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1;
|
|
875 cpu->next_instruction = cpu->R[15];
|
|
876 return 3;
|
|
877 }
|
|
878
|
|
879 static u32 FASTCALL OP_SWI_THUMB(armcpu_t *cpu)
|
|
880 {
|
|
881 if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
|
|
882 {
|
|
883 /* we use an irq thats not in the irq tab, as
|
|
884 it was replaced duie to a changed intVector */
|
|
885 Status_Reg tmp = cpu->CPSR;
|
|
886 armcpu_switchMode(cpu, SVC); /* enter svc mode */
|
|
887 cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */
|
|
888 cpu->SPSR = tmp; /* save old CPSR as new SPSR */
|
|
889 cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
|
|
890 cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */
|
|
891 cpu->R[15] = cpu->intVector + 0x08;
|
|
892 cpu->next_instruction = cpu->R[15];
|
|
893 return 3;
|
|
894 }
|
|
895 else
|
|
896 {
|
|
897 u32 swinum = cpu->instruction & 0xFF;
|
|
898 return cpu->swi_tab[swinum](cpu) + 3;
|
|
899 }
|
|
900 //return 3;
|
|
901 }
|
|
902
|
|
903 #define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800))
|
|
904
|
|
905 static u32 FASTCALL OP_B_UNCOND(armcpu_t *cpu)
|
|
906 {
|
|
907 u32 i = cpu->instruction;
|
|
908 cpu->R[15] += (SIGNEEXT_IMM11(i)<<1);
|
|
909 cpu->next_instruction = cpu->R[15];
|
|
910 return 3;
|
|
911 }
|
|
912
|
|
913 static u32 FASTCALL OP_BLX(armcpu_t *cpu)
|
|
914 {
|
|
915 u32 i = cpu->instruction;
|
|
916 cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC;
|
|
917 cpu->R[14] = cpu->next_instruction | 1;
|
|
918 cpu->next_instruction = cpu->R[15];
|
|
919 cpu->CPSR.bits.T = 0;
|
|
920 return 3;
|
|
921 }
|
|
922
|
|
923 static u32 FASTCALL OP_BL_10(armcpu_t *cpu)
|
|
924 {
|
|
925 u32 i = cpu->instruction;
|
|
926 cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12);
|
|
927 return 1;
|
|
928 }
|
|
929
|
|
930 static u32 FASTCALL OP_BL_THUMB(armcpu_t *cpu)
|
|
931 {
|
|
932 u32 i = cpu->instruction;
|
|
933 cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1));
|
|
934 cpu->R[14] = cpu->next_instruction | 1;
|
|
935 cpu->next_instruction = cpu->R[15];
|
|
936 return 3;
|
|
937 }
|
|
938
|
|
939 #define TYPE_RETOUR u32
|
|
940 #define CALLTYPE FASTCALL
|
|
941 #define PARAMETRES armcpu_t *cpu
|
|
942 #define NOM_THUMB_TAB thumb_instructions_set
|
|
943
|
|
944 #include "thumb_tabdef.inc"
|