rename expr.cpp.h to expr.c.h
[rofl0r-VisualBoyAdvance.git] / src / arm-new.h
blob0a1daaffe745866cf7f535f8348fb4ae33c1b774
1 // -*- C++ -*-
2 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
3 // Copyright (C) 1999-2003 Forgotten
4 // Copyright (C) 2005-2006 Forgotten and the VBA development team
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or(at your option)
9 // any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #ifdef BKPT_SUPPORT
21 #define CONSOLE_OUTPUT(a,b) \
22 extern void (*dbgOutput)(char *, u32);\
23 if((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) {\
24 dbgOutput((a), (b));\
26 #else
27 #define CONSOLE_OUTPUT(a,b)
28 #endif
30 #define OP_AND \
31 reg[dest].I = reg[(opcode>>16)&15].I & value;\
32 CONSOLE_OUTPUT(NULL,reg[2].I);
34 #define OP_ANDS \
35 reg[dest].I = reg[(opcode>>16)&15].I & value;\
37 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
38 Z_FLAG = (reg[dest].I) ? false : true;\
39 C_FLAG = C_OUT;
41 #define OP_EOR \
42 reg[dest].I = reg[(opcode>>16)&15].I ^ value;
44 #define OP_EORS \
45 reg[dest].I = reg[(opcode>>16)&15].I ^ value;\
47 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
48 Z_FLAG = (reg[dest].I) ? false : true;\
49 C_FLAG = C_OUT;
50 #ifdef C_CORE
51 #define NEG(i) ((i) >> 31)
52 #define POS(i) ((~(i)) >> 31)
53 #define ADDCARRY(a, b, c) \
54 C_FLAG = ((NEG(a) & NEG(b)) |\
55 (NEG(a) & POS(c)) |\
56 (NEG(b) & POS(c))) ? true : false;
57 #define ADDOVERFLOW(a, b, c) \
58 V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\
59 (POS(a) & POS(b) & NEG(c))) ? true : false;
60 #define SUBCARRY(a, b, c) \
61 C_FLAG = ((NEG(a) & POS(b)) |\
62 (NEG(a) & POS(c)) |\
63 (POS(b) & POS(c))) ? true : false;
64 #define SUBOVERFLOW(a, b, c)\
65 V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\
66 (POS(a) & NEG(b) & NEG(c))) ? true : false;
67 #define OP_SUB \
69 reg[dest].I = reg[base].I - value;\
71 #define OP_SUBS \
73 u32 lhs = reg[base].I;\
74 u32 rhs = value;\
75 u32 res = lhs - rhs;\
76 reg[dest].I = res;\
77 Z_FLAG = (res == 0) ? true : false;\
78 N_FLAG = NEG(res) ? true : false;\
79 SUBCARRY(lhs, rhs, res);\
80 SUBOVERFLOW(lhs, rhs, res);\
82 #define OP_RSB \
84 reg[dest].I = value - reg[base].I;\
86 #define OP_RSBS \
88 u32 lhs = reg[base].I;\
89 u32 rhs = value;\
90 u32 res = rhs - lhs;\
91 reg[dest].I = res;\
92 Z_FLAG = (res == 0) ? true : false;\
93 N_FLAG = NEG(res) ? true : false;\
94 SUBCARRY(rhs, lhs, res);\
95 SUBOVERFLOW(rhs, lhs, res);\
97 #define OP_ADD \
99 reg[dest].I = reg[base].I + value;\
101 #define OP_ADDS \
103 u32 lhs = reg[base].I;\
104 u32 rhs = value;\
105 u32 res = lhs + rhs;\
106 reg[dest].I = res;\
107 Z_FLAG = (res == 0) ? true : false;\
108 N_FLAG = NEG(res) ? true : false;\
109 ADDCARRY(lhs, rhs, res);\
110 ADDOVERFLOW(lhs, rhs, res);\
112 #define OP_ADC \
114 reg[dest].I = reg[base].I + value + (u32)C_FLAG;\
116 #define OP_ADCS \
118 u32 lhs = reg[base].I;\
119 u32 rhs = value;\
120 u32 res = lhs + rhs + (u32)C_FLAG;\
121 reg[dest].I = res;\
122 Z_FLAG = (res == 0) ? true : false;\
123 N_FLAG = NEG(res) ? true : false;\
124 ADDCARRY(lhs, rhs, res);\
125 ADDOVERFLOW(lhs, rhs, res);\
127 #define OP_SBC \
129 reg[dest].I = reg[base].I - value - !((u32)C_FLAG);\
131 #define OP_SBCS \
133 u32 lhs = reg[base].I;\
134 u32 rhs = value;\
135 u32 res = lhs - rhs - !((u32)C_FLAG);\
136 reg[dest].I = res;\
137 Z_FLAG = (res == 0) ? true : false;\
138 N_FLAG = NEG(res) ? true : false;\
139 SUBCARRY(lhs, rhs, res);\
140 SUBOVERFLOW(lhs, rhs, res);\
142 #define OP_RSC \
144 reg[dest].I = value - reg[base].I - !((u32)C_FLAG);\
146 #define OP_RSCS \
148 u32 lhs = reg[base].I;\
149 u32 rhs = value;\
150 u32 res = rhs - lhs - !((u32)C_FLAG);\
151 reg[dest].I = res;\
152 Z_FLAG = (res == 0) ? true : false;\
153 N_FLAG = NEG(res) ? true : false;\
154 SUBCARRY(rhs, lhs, res);\
155 SUBOVERFLOW(rhs, lhs, res);\
157 #define OP_CMP \
159 u32 lhs = reg[base].I;\
160 u32 rhs = value;\
161 u32 res = lhs - rhs;\
162 Z_FLAG = (res == 0) ? true : false;\
163 N_FLAG = NEG(res) ? true : false;\
164 SUBCARRY(lhs, rhs, res);\
165 SUBOVERFLOW(lhs, rhs, res);\
167 #define OP_CMN \
169 u32 lhs = reg[base].I;\
170 u32 rhs = value;\
171 u32 res = lhs + rhs;\
172 Z_FLAG = (res == 0) ? true : false;\
173 N_FLAG = NEG(res) ? true : false;\
174 ADDCARRY(lhs, rhs, res);\
175 ADDOVERFLOW(lhs, rhs, res);\
178 #define LOGICAL_LSL_REG \
180 u32 v = reg[opcode & 0x0f].I;\
181 C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
182 value = v << shift;\
184 #define LOGICAL_LSR_REG \
186 u32 v = reg[opcode & 0x0f].I;\
187 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
188 value = v >> shift;\
190 #define LOGICAL_ASR_REG \
192 u32 v = reg[opcode & 0x0f].I;\
193 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\
194 value = (s32)v >> (int)shift;\
196 #define LOGICAL_ROR_REG \
198 u32 v = reg[opcode & 0x0f].I;\
199 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
200 value = ((v << (32 - shift)) |\
201 (v >> shift));\
203 #define LOGICAL_RRX_REG \
205 u32 v = reg[opcode & 0x0f].I;\
206 shift = (int)C_FLAG;\
207 C_OUT = (v & 1) ? true : false;\
208 value = ((v >> 1) |\
209 (shift << 31));\
211 #define LOGICAL_ROR_IMM \
213 u32 v = opcode & 0xff;\
214 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
215 value = ((v << (32 - shift)) |\
216 (v >> shift));\
218 #define ARITHMETIC_LSL_REG \
220 u32 v = reg[opcode & 0x0f].I;\
221 value = v << shift;\
223 #define ARITHMETIC_LSR_REG \
225 u32 v = reg[opcode & 0x0f].I;\
226 value = v >> shift;\
228 #define ARITHMETIC_ASR_REG \
230 u32 v = reg[opcode & 0x0f].I;\
231 value = (s32)v >> (int)shift;\
233 #define ARITHMETIC_ROR_REG \
235 u32 v = reg[opcode & 0x0f].I;\
236 value = ((v << (32 - shift)) |\
237 (v >> shift));\
239 #define ARITHMETIC_RRX_REG \
241 u32 v = reg[opcode & 0x0f].I;\
242 shift = (int)C_FLAG;\
243 value = ((v >> 1) |\
244 (shift << 31));\
246 #define ARITHMETIC_ROR_IMM \
248 u32 v = opcode & 0xff;\
249 value = ((v << (32 - shift)) |\
250 (v >> shift));\
252 #define ROR_IMM_MSR \
254 u32 v = opcode & 0xff;\
255 value = ((v << (32 - shift)) |\
256 (v >> shift));\
258 #define ROR_VALUE \
260 value = ((value << (32 - shift)) |\
261 (value >> shift));\
263 #define RCR_VALUE \
265 shift = (int)C_FLAG;\
266 value = ((value >> 1) |\
267 (shift << 31));\
269 #else
270 #ifdef __GNUC__
271 #ifdef __POWERPC__
272 #define OP_SUB \
274 reg[dest].I = reg[base].I - value;\
276 #define OP_SUBS \
278 register int Flags; \
279 register int Result; \
280 asm volatile("subco. %0, %2, %3\n" \
281 "mcrxr cr1\n" \
282 "mfcr %1\n" \
283 : "=r" (Result), \
284 "=r" (Flags) \
285 : "r" (reg[base].I), \
286 "r" (value) \
287 ); \
288 reg[dest].I = Result; \
289 Z_FLAG = (Flags >> 29) & 1; \
290 N_FLAG = (Flags >> 31) & 1; \
291 C_FLAG = (Flags >> 25) & 1; \
292 V_FLAG = (Flags >> 26) & 1; \
294 #define OP_RSB \
296 reg[dest].I = value - reg[base].I;\
298 #define OP_RSBS \
300 register int Flags; \
301 register int Result; \
302 asm volatile("subfco. %0, %2, %3\n" \
303 "mcrxr cr1\n" \
304 "mfcr %1\n" \
305 : "=r" (Result), \
306 "=r" (Flags) \
307 : "r" (reg[base].I), \
308 "r" (value) \
309 ); \
310 reg[dest].I = Result; \
311 Z_FLAG = (Flags >> 29) & 1; \
312 N_FLAG = (Flags >> 31) & 1; \
313 C_FLAG = (Flags >> 25) & 1; \
314 V_FLAG = (Flags >> 26) & 1; \
316 #define OP_ADD \
318 reg[dest].I = reg[base].I + value;\
321 #define OP_ADDS \
323 register int Flags; \
324 register int Result; \
325 asm volatile("addco. %0, %2, %3\n" \
326 "mcrxr cr1\n" \
327 "mfcr %1\n" \
328 : "=r" (Result), \
329 "=r" (Flags) \
330 : "r" (reg[base].I), \
331 "r" (value) \
332 ); \
333 reg[dest].I = Result; \
334 Z_FLAG = (Flags >> 29) & 1; \
335 N_FLAG = (Flags >> 31) & 1; \
336 C_FLAG = (Flags >> 25) & 1; \
337 V_FLAG = (Flags >> 26) & 1; \
339 #define OP_ADC \
341 reg[dest].I = reg[base].I + value + (u32)C_FLAG;\
343 #define OP_ADCS \
345 register int Flags; \
346 register int Result; \
347 asm volatile("mtspr xer, %4\n" \
348 "addeo. %0, %2, %3\n" \
349 "mcrxr cr1\n" \
350 "mfcr %1\n" \
351 : "=r" (Result), \
352 "=r" (Flags) \
353 : "r" (reg[base].I), \
354 "r" (value), \
355 "r" (C_FLAG << 29) \
356 ); \
357 reg[dest].I = Result; \
358 Z_FLAG = (Flags >> 29) & 1; \
359 N_FLAG = (Flags >> 31) & 1; \
360 C_FLAG = (Flags >> 25) & 1; \
361 V_FLAG = (Flags >> 26) & 1; \
363 #define OP_SBC \
365 reg[dest].I = reg[base].I - value - (C_FLAG^1);\
367 #define OP_SBCS \
369 register int Flags; \
370 register int Result; \
371 asm volatile("mtspr xer, %4\n" \
372 "subfeo. %0, %3, %2\n" \
373 "mcrxr cr1\n" \
374 "mfcr %1\n" \
375 : "=r" (Result), \
376 "=r" (Flags) \
377 : "r" (reg[base].I), \
378 "r" (value), \
379 "r" (C_FLAG << 29) \
380 ); \
381 reg[dest].I = Result; \
382 Z_FLAG = (Flags >> 29) & 1; \
383 N_FLAG = (Flags >> 31) & 1; \
384 C_FLAG = (Flags >> 25) & 1; \
385 V_FLAG = (Flags >> 26) & 1; \
387 #define OP_RSC \
389 reg[dest].I = value - reg[base].I - (C_FLAG^1);\
391 #define OP_RSCS \
393 register int Flags; \
394 register int Result; \
395 asm volatile("mtspr xer, %4\n" \
396 "subfeo. %0, %2, %3\n" \
397 "mcrxr cr1\n" \
398 "mfcr %1\n" \
399 : "=r" (Result), \
400 "=r" (Flags) \
401 : "r" (reg[base].I), \
402 "r" (value), \
403 "r" (C_FLAG << 29) \
404 ); \
405 reg[dest].I = Result; \
406 Z_FLAG = (Flags >> 29) & 1; \
407 N_FLAG = (Flags >> 31) & 1; \
408 C_FLAG = (Flags >> 25) & 1; \
409 V_FLAG = (Flags >> 26) & 1; \
411 #define OP_CMP \
413 register int Flags; \
414 register int Result; \
415 asm volatile("subco. %0, %2, %3\n" \
416 "mcrxr cr1\n" \
417 "mfcr %1\n" \
418 : "=r" (Result), \
419 "=r" (Flags) \
420 : "r" (reg[base].I), \
421 "r" (value) \
422 ); \
423 Z_FLAG = (Flags >> 29) & 1; \
424 N_FLAG = (Flags >> 31) & 1; \
425 C_FLAG = (Flags >> 25) & 1; \
426 V_FLAG = (Flags >> 26) & 1; \
428 #define OP_CMN \
430 register int Flags; \
431 register int Result; \
432 asm volatile("addco. %0, %2, %3\n" \
433 "mcrxr cr1\n" \
434 "mfcr %1\n" \
435 : "=r" (Result), \
436 "=r" (Flags) \
437 : "r" (reg[base].I), \
438 "r" (value) \
439 ); \
440 Z_FLAG = (Flags >> 29) & 1; \
441 N_FLAG = (Flags >> 31) & 1; \
442 C_FLAG = (Flags >> 25) & 1; \
443 V_FLAG = (Flags >> 26) & 1; \
446 #define LOGICAL_LSL_REG \
448 u32 v = reg[opcode & 0x0f].I;\
449 C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
450 value = v << shift;\
452 #define LOGICAL_LSR_REG \
454 u32 v = reg[opcode & 0x0f].I;\
455 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
456 value = v >> shift;\
458 #define LOGICAL_ASR_REG \
460 u32 v = reg[opcode & 0x0f].I;\
461 C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\
462 value = (s32)v >> (int)shift;\
464 #define LOGICAL_ROR_REG \
466 u32 v = reg[opcode & 0x0f].I;\
467 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
468 value = ((v << (32 - shift)) |\
469 (v >> shift));\
471 #define LOGICAL_RRX_REG \
473 u32 v = reg[opcode & 0x0f].I;\
474 shift = (int)C_FLAG;\
475 C_OUT = (v & 1) ? true : false;\
476 value = ((v >> 1) |\
477 (shift << 31));\
479 #define LOGICAL_ROR_IMM \
481 u32 v = opcode & 0xff;\
482 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
483 value = ((v << (32 - shift)) |\
484 (v >> shift));\
486 #define ARITHMETIC_LSL_REG \
488 u32 v = reg[opcode & 0x0f].I;\
489 value = v << shift;\
491 #define ARITHMETIC_LSR_REG \
493 u32 v = reg[opcode & 0x0f].I;\
494 value = v >> shift;\
496 #define ARITHMETIC_ASR_REG \
498 u32 v = reg[opcode & 0x0f].I;\
499 value = (s32)v >> (int)shift;\
501 #define ARITHMETIC_ROR_REG \
503 u32 v = reg[opcode & 0x0f].I;\
504 value = ((v << (32 - shift)) |\
505 (v >> shift));\
507 #define ARITHMETIC_RRX_REG \
509 u32 v = reg[opcode & 0x0f].I;\
510 shift = (int)C_FLAG;\
511 value = ((v >> 1) |\
512 (shift << 31));\
514 #define ARITHMETIC_ROR_IMM \
516 u32 v = opcode & 0xff;\
517 value = ((v << (32 - shift)) |\
518 (v >> shift));\
520 #define ROR_IMM_MSR \
522 u32 v = opcode & 0xff;\
523 value = ((v << (32 - shift)) |\
524 (v >> shift));\
526 #define ROR_VALUE \
528 value = ((value << (32 - shift)) |\
529 (value >> shift));\
531 #define RCR_VALUE \
533 shift = (int)C_FLAG;\
534 value = ((value >> 1) |\
535 (shift << 31));\
537 #else
538 #define OP_SUB \
539 asm ("sub %1, %%ebx;"\
540 : "=b" (reg[dest].I)\
541 : "r" (value), "b" (reg[base].I));
543 #define OP_SUBS \
544 asm ("sub %1, %%ebx;"\
545 "setsb N_FLAG;"\
546 "setzb Z_FLAG;"\
547 "setncb C_FLAG;"\
548 "setob V_FLAG;"\
549 : "=b" (reg[dest].I)\
550 : "r" (value), "b" (reg[base].I));
552 #define OP_RSB \
553 asm ("sub %1, %%ebx;"\
554 : "=b" (reg[dest].I)\
555 : "r" (reg[base].I), "b" (value));
557 #define OP_RSBS \
558 asm ("sub %1, %%ebx;"\
559 "setsb N_FLAG;"\
560 "setzb Z_FLAG;"\
561 "setncb C_FLAG;"\
562 "setob V_FLAG;"\
563 : "=b" (reg[dest].I)\
564 : "r" (reg[base].I), "b" (value));
566 #define OP_ADD \
567 asm ("add %1, %%ebx;"\
568 : "=b" (reg[dest].I)\
569 : "r" (value), "b" (reg[base].I));
571 #define OP_ADDS \
572 asm ("add %1, %%ebx;"\
573 "setsb N_FLAG;"\
574 "setzb Z_FLAG;"\
575 "setcb C_FLAG;"\
576 "setob V_FLAG;"\
577 : "=b" (reg[dest].I)\
578 : "r" (value), "b" (reg[base].I));
580 #define OP_ADC \
581 asm ("bt $0, C_FLAG;"\
582 "adc %1, %%ebx;"\
583 : "=b" (reg[dest].I)\
584 : "r" (value), "b" (reg[base].I));
586 #define OP_ADCS \
587 asm ("bt $0, C_FLAG;"\
588 "adc %1, %%ebx;"\
589 "setsb N_FLAG;"\
590 "setzb Z_FLAG;"\
591 "setcb C_FLAG;"\
592 "setob V_FLAG;"\
593 : "=b" (reg[dest].I)\
594 : "r" (value), "b" (reg[base].I));
596 #define OP_SBC \
597 asm ("bt $0, C_FLAG;"\
598 "cmc;"\
599 "sbb %1, %%ebx;"\
600 : "=b" (reg[dest].I)\
601 : "r" (value), "b" (reg[base].I));
603 #define OP_SBCS \
604 asm ("bt $0, C_FLAG;"\
605 "cmc;"\
606 "sbb %1, %%ebx;"\
607 "setsb N_FLAG;"\
608 "setzb Z_FLAG;"\
609 "setncb C_FLAG;"\
610 "setob V_FLAG;"\
611 : "=b" (reg[dest].I)\
612 : "r" (value), "b" (reg[base].I));
613 #define OP_RSC \
614 asm ("bt $0, C_FLAG;"\
615 "cmc;"\
616 "sbb %1, %%ebx;"\
617 : "=b" (reg[dest].I)\
618 : "r" (reg[base].I), "b" (value));
620 #define OP_RSCS \
621 asm ("bt $0, C_FLAG;"\
622 "cmc;"\
623 "sbb %1, %%ebx;"\
624 "setsb N_FLAG;"\
625 "setzb Z_FLAG;"\
626 "setncb C_FLAG;"\
627 "setob V_FLAG;"\
628 : "=b" (reg[dest].I)\
629 : "r" (reg[base].I), "b" (value));
630 #define OP_CMP \
631 asm ("sub %0, %1;"\
632 "setsb N_FLAG;"\
633 "setzb Z_FLAG;"\
634 "setncb C_FLAG;"\
635 "setob V_FLAG;"\
637 : "r" (value), "r" (reg[base].I));
639 #define OP_CMN \
640 asm ("add %0, %1;"\
641 "setsb N_FLAG;"\
642 "setzb Z_FLAG;"\
643 "setcb C_FLAG;"\
644 "setob V_FLAG;"\
646 : "r" (value), "r" (reg[base].I));
647 #define LOGICAL_LSL_REG \
648 asm("shl %%cl, %%eax;"\
649 "setcb %%cl;"\
650 : "=a" (value), "=c" (C_OUT)\
651 : "a" (reg[opcode & 0x0f].I), "c" (shift));
653 #define LOGICAL_LSR_REG \
654 asm("shr %%cl, %%eax;"\
655 "setcb %%cl;"\
656 : "=a" (value), "=c" (C_OUT)\
657 : "a" (reg[opcode & 0x0f].I), "c" (shift));
659 #define LOGICAL_ASR_REG \
660 asm("sar %%cl, %%eax;"\
661 "setcb %%cl;"\
662 : "=a" (value), "=c" (C_OUT)\
663 : "a" (reg[opcode & 0x0f].I), "c" (shift));
665 #define LOGICAL_ROR_REG \
666 asm("ror %%cl, %%eax;"\
667 "setcb %%cl;"\
668 : "=a" (value), "=c" (C_OUT)\
669 : "a" (reg[opcode & 0x0f].I), "c" (shift));
671 #define LOGICAL_RRX_REG \
672 asm("bt $0, C_FLAG;"\
673 "rcr $1, %%eax;"\
674 "setcb %%cl;"\
675 : "=a" (value), "=c" (C_OUT)\
676 : "a" (reg[opcode & 0x0f].I));
678 #define LOGICAL_ROR_IMM \
679 asm("ror %%cl, %%eax;"\
680 "setcb %%cl;"\
681 : "=a" (value), "=c" (C_OUT)\
682 : "a" (opcode & 0xff), "c" (shift));
683 #define ARITHMETIC_LSL_REG \
684 asm("\
685 shl %%cl, %%eax;"\
686 : "=a" (value)\
687 : "a" (reg[opcode & 0x0f].I), "c" (shift));
689 #define ARITHMETIC_LSR_REG \
690 asm("\
691 shr %%cl, %%eax;"\
692 : "=a" (value)\
693 : "a" (reg[opcode & 0x0f].I), "c" (shift));
695 #define ARITHMETIC_ASR_REG \
696 asm("\
697 sar %%cl, %%eax;"\
698 : "=a" (value)\
699 : "a" (reg[opcode & 0x0f].I), "c" (shift));
701 #define ARITHMETIC_ROR_REG \
702 asm("\
703 ror %%cl, %%eax;"\
704 : "=a" (value)\
705 : "a" (reg[opcode & 0x0f].I), "c" (shift));
707 #define ARITHMETIC_RRX_REG \
708 asm("\
709 bt $0, C_FLAG;\
710 rcr $1, %%eax;"\
711 : "=a" (value)\
712 : "a" (reg[opcode & 0x0f].I));
714 #define ARITHMETIC_ROR_IMM \
715 asm("\
716 ror %%cl, %%eax;"\
717 : "=a" (value)\
718 : "a" (opcode & 0xff), "c" (shift));
719 #define ROR_IMM_MSR \
720 asm ("ror %%cl, %%eax;"\
721 : "=a" (value)\
722 : "a" (opcode & 0xFF), "c" (shift));
723 #define ROR_VALUE \
724 asm("ror %%cl, %0"\
725 : "=r" (value)\
726 : "r" (value), "c" (shift));
727 #define RCR_VALUE \
728 asm("bt $0, C_FLAG;"\
729 "rcr $1, %0"\
730 : "=r" (value)\
731 : "r" (value));
732 #endif
733 #else
734 #define OP_SUB \
736 __asm mov ebx, base\
737 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
738 __asm sub ebx, value\
739 __asm mov eax, dest\
740 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
743 #define OP_SUBS \
745 __asm mov ebx, base\
746 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
747 __asm sub ebx, value\
748 __asm mov eax, dest\
749 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
750 __asm sets byte ptr N_FLAG\
751 __asm setz byte ptr Z_FLAG\
752 __asm setnc byte ptr C_FLAG\
753 __asm seto byte ptr V_FLAG\
756 #define OP_RSB \
758 __asm mov ebx, base\
759 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
760 __asm mov eax, value\
761 __asm sub eax, ebx\
762 __asm mov ebx, dest\
763 __asm mov dword ptr [OFFSET reg+4*ebx], eax\
766 #define OP_RSBS \
768 __asm mov ebx, base\
769 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
770 __asm mov eax, value\
771 __asm sub eax, ebx\
772 __asm mov ebx, dest\
773 __asm mov dword ptr [OFFSET reg+4*ebx], eax\
774 __asm sets byte ptr N_FLAG\
775 __asm setz byte ptr Z_FLAG\
776 __asm setnc byte ptr C_FLAG\
777 __asm seto byte ptr V_FLAG\
780 #define OP_ADD \
782 __asm mov ebx, base\
783 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
784 __asm add ebx, value\
785 __asm mov eax, dest\
786 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
789 #define OP_ADDS \
791 __asm mov ebx, base\
792 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
793 __asm add ebx, value\
794 __asm mov eax, dest\
795 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
796 __asm sets byte ptr N_FLAG\
797 __asm setz byte ptr Z_FLAG\
798 __asm setc byte ptr C_FLAG\
799 __asm seto byte ptr V_FLAG\
802 #define OP_ADC \
804 __asm mov ebx, base\
805 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
806 __asm bt word ptr C_FLAG, 0\
807 __asm adc ebx, value\
808 __asm mov eax, dest\
809 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
812 #define OP_ADCS \
814 __asm mov ebx, base\
815 __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
816 __asm bt word ptr C_FLAG, 0\
817 __asm adc ebx, value\
818 __asm mov eax, dest\
819 __asm mov dword ptr [OFFSET reg+4*eax], ebx\
820 __asm sets byte ptr N_FLAG\
821 __asm setz byte ptr Z_FLAG\
822 __asm setc byte ptr C_FLAG\
823 __asm seto byte ptr V_FLAG\
826 #define OP_SBC \
828 __asm mov ebx, base\
829 __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
830 __asm mov eax, value\
831 __asm bt word ptr C_FLAG, 0\
832 __asm cmc\
833 __asm sbb ebx, eax\
834 __asm mov eax, dest\
835 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
838 #define OP_SBCS \
840 __asm mov ebx, base\
841 __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
842 __asm mov eax, value\
843 __asm bt word ptr C_FLAG, 0\
844 __asm cmc\
845 __asm sbb ebx, eax\
846 __asm mov eax, dest\
847 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
848 __asm sets byte ptr N_FLAG\
849 __asm setz byte ptr Z_FLAG\
850 __asm setnc byte ptr C_FLAG\
851 __asm seto byte ptr V_FLAG\
853 #define OP_RSC \
855 __asm mov ebx, value\
856 __asm mov eax, base\
857 __asm mov eax, dword ptr[OFFSET reg + 4*eax]\
858 __asm bt word ptr C_FLAG, 0\
859 __asm cmc\
860 __asm sbb ebx, eax\
861 __asm mov eax, dest\
862 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
865 #define OP_RSCS \
867 __asm mov ebx, value\
868 __asm mov eax, base\
869 __asm mov eax, dword ptr[OFFSET reg + 4*eax]\
870 __asm bt word ptr C_FLAG, 0\
871 __asm cmc\
872 __asm sbb ebx, eax\
873 __asm mov eax, dest\
874 __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
875 __asm sets byte ptr N_FLAG\
876 __asm setz byte ptr Z_FLAG\
877 __asm setnc byte ptr C_FLAG\
878 __asm seto byte ptr V_FLAG\
880 #define OP_CMP \
882 __asm mov eax, base\
883 __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
884 __asm sub ebx, value\
885 __asm sets byte ptr N_FLAG\
886 __asm setz byte ptr Z_FLAG\
887 __asm setnc byte ptr C_FLAG\
888 __asm seto byte ptr V_FLAG\
891 #define OP_CMN \
893 __asm mov eax, base\
894 __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
895 __asm add ebx, value\
896 __asm sets byte ptr N_FLAG\
897 __asm setz byte ptr Z_FLAG\
898 __asm setc byte ptr C_FLAG\
899 __asm seto byte ptr V_FLAG\
901 #define LOGICAL_LSL_REG \
902 __asm mov eax, opcode\
903 __asm and eax, 0x0f\
904 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
905 __asm mov cl, byte ptr shift\
906 __asm shl eax, cl\
907 __asm mov value, eax\
908 __asm setc byte ptr C_OUT
910 #define LOGICAL_LSR_REG \
911 __asm mov eax, opcode\
912 __asm and eax, 0x0f\
913 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
914 __asm mov cl, byte ptr shift\
915 __asm shr eax, cl\
916 __asm mov value, eax\
917 __asm setc byte ptr C_OUT
919 #define LOGICAL_ASR_REG \
920 __asm mov eax, opcode\
921 __asm and eax, 0x0f\
922 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
923 __asm mov cl, byte ptr shift\
924 __asm sar eax, cl\
925 __asm mov value, eax\
926 __asm setc byte ptr C_OUT
928 #define LOGICAL_ROR_REG \
929 __asm mov eax, opcode\
930 __asm and eax, 0x0F\
931 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
932 __asm mov cl, byte ptr shift\
933 __asm ror eax, cl\
934 __asm mov value, eax\
935 __asm setc byte ptr C_OUT
937 #define LOGICAL_RRX_REG \
938 __asm mov eax, opcode\
939 __asm and eax, 0x0F\
940 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
941 __asm bt word ptr C_OUT, 0\
942 __asm rcr eax, 1\
943 __asm mov value, eax\
944 __asm setc byte ptr C_OUT
946 #define LOGICAL_ROR_IMM \
947 __asm mov eax, opcode\
948 __asm and eax, 0xff\
949 __asm mov cl, byte ptr shift\
950 __asm ror eax, cl\
951 __asm mov value, eax\
952 __asm setc byte ptr C_OUT
953 #define ARITHMETIC_LSL_REG \
954 __asm mov eax, opcode\
955 __asm and eax, 0x0f\
956 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
957 __asm mov cl, byte ptr shift\
958 __asm shl eax, cl\
959 __asm mov value, eax
961 #define ARITHMETIC_LSR_REG \
962 __asm mov eax, opcode\
963 __asm and eax, 0x0f\
964 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
965 __asm mov cl, byte ptr shift\
966 __asm shr eax, cl\
967 __asm mov value, eax
969 #define ARITHMETIC_ASR_REG \
970 __asm mov eax, opcode\
971 __asm and eax, 0x0f\
972 __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
973 __asm mov cl, byte ptr shift\
974 __asm sar eax, cl\
975 __asm mov value, eax
977 #define ARITHMETIC_ROR_REG \
978 __asm mov eax, opcode\
979 __asm and eax, 0x0F\
980 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
981 __asm mov cl, byte ptr shift\
982 __asm ror eax, cl\
983 __asm mov value, eax
985 #define ARITHMETIC_RRX_REG \
986 __asm mov eax, opcode\
987 __asm and eax, 0x0F\
988 __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
989 __asm bt word ptr C_FLAG, 0\
990 __asm rcr eax, 1\
991 __asm mov value, eax
993 #define ARITHMETIC_ROR_IMM \
994 __asm mov eax, opcode\
995 __asm and eax, 0xff\
996 __asm mov cl, byte ptr shift\
997 __asm ror eax, cl\
998 __asm mov value, eax
999 #define ROR_IMM_MSR \
1001 __asm mov eax, opcode\
1002 __asm and eax, 0xff\
1003 __asm mov cl, byte ptr shift\
1004 __asm ror eax, CL\
1005 __asm mov value, eax\
1007 #define ROR_VALUE \
1009 __asm mov cl, byte ptr shift\
1010 __asm ror dword ptr value, cl\
1012 #define RCR_VALUE \
1014 __asm mov cl, byte ptr shift\
1015 __asm bt word ptr C_FLAG, 0\
1016 __asm rcr dword ptr value, 1\
1018 #endif
1019 #endif
1021 #define OP_TST \
1022 u32 res = reg[base].I & value;\
1023 N_FLAG = (res & 0x80000000) ? true : false;\
1024 Z_FLAG = (res) ? false : true;\
1025 C_FLAG = C_OUT;
1027 #define OP_TEQ \
1028 u32 res = reg[base].I ^ value;\
1029 N_FLAG = (res & 0x80000000) ? true : false;\
1030 Z_FLAG = (res) ? false : true;\
1031 C_FLAG = C_OUT;
1033 #define OP_ORR \
1034 reg[dest].I = reg[base].I | value;
1036 #define OP_ORRS \
1037 reg[dest].I = reg[base].I | value;\
1038 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
1039 Z_FLAG = (reg[dest].I) ? false : true;\
1040 C_FLAG = C_OUT;
1042 #define OP_MOV \
1043 reg[dest].I = value;
1045 #define OP_MOVS \
1046 reg[dest].I = value;\
1047 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
1048 Z_FLAG = (reg[dest].I) ? false : true;\
1049 C_FLAG = C_OUT;
1051 #define OP_BIC \
1052 reg[dest].I = reg[base].I & (~value);
1054 #define OP_BICS \
1055 reg[dest].I = reg[base].I & (~value);\
1056 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
1057 Z_FLAG = (reg[dest].I) ? false : true;\
1058 C_FLAG = C_OUT;
1060 #define OP_MVN \
1061 reg[dest].I = ~value;
1063 #define OP_MVNS \
1064 reg[dest].I = ~value; \
1065 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
1066 Z_FLAG = (reg[dest].I) ? false : true;\
1067 C_FLAG = C_OUT;
1069 #define CASE_16(BASE) \
1070 case BASE:\
1071 case BASE+1:\
1072 case BASE+2:\
1073 case BASE+3:\
1074 case BASE+4:\
1075 case BASE+5:\
1076 case BASE+6:\
1077 case BASE+7:\
1078 case BASE+8:\
1079 case BASE+9:\
1080 case BASE+10:\
1081 case BASE+11:\
1082 case BASE+12:\
1083 case BASE+13:\
1084 case BASE+14:\
1085 case BASE+15:
1087 #define CASE_256(BASE) \
1088 CASE_16(BASE)\
1089 CASE_16(BASE+0x10)\
1090 CASE_16(BASE+0x20)\
1091 CASE_16(BASE+0x30)\
1092 CASE_16(BASE+0x40)\
1093 CASE_16(BASE+0x50)\
1094 CASE_16(BASE+0x60)\
1095 CASE_16(BASE+0x70)\
1096 CASE_16(BASE+0x80)\
1097 CASE_16(BASE+0x90)\
1098 CASE_16(BASE+0xa0)\
1099 CASE_16(BASE+0xb0)\
1100 CASE_16(BASE+0xc0)\
1101 CASE_16(BASE+0xd0)\
1102 CASE_16(BASE+0xe0)\
1103 CASE_16(BASE+0xf0)
1105 #define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
1106 case BASE: \
1107 case BASE+8:\
1109 /* OP Rd,Rb,Rm LSL # */ \
1110 int base = (opcode >> 16) & 0x0F;\
1111 int shift = (opcode >> 7) & 0x1F;\
1112 int dest = (opcode>>12) & 15;\
1113 bool C_OUT = C_FLAG;\
1114 u32 value;\
1116 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1118 clockTicks = 1+codeTicksAccess32(armNextPC);\
1119 if ((opcode & 0x02000010)==0x10)\
1120 clockTicks++;\
1122 if(shift) {\
1123 LOGICAL_LSL_REG\
1124 } else {\
1125 value = reg[opcode & 0x0F].I;\
1127 if(dest == 15) {\
1128 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1129 OPCODE2\
1130 /* todo */\
1131 if(opcode & 0x00100000) {\
1132 CPUSwitchMode(reg[17].I & 0x1f, false);\
1134 if(armState) {\
1135 reg[15].I &= 0xFFFFFFFC;\
1136 armNextPC = reg[15].I;\
1137 reg[15].I += 4;\
1138 ARM_PREFETCH;\
1139 } else {\
1140 reg[15].I &= 0xFFFFFFFE;\
1141 armNextPC = reg[15].I;\
1142 reg[15].I += 2;\
1143 THUMB_PREFETCH;\
1145 } else {\
1146 OPCODE \
1149 break;\
1150 case BASE+2:\
1151 case BASE+10:\
1153 /* OP Rd,Rb,Rm LSR # */ \
1154 int base = (opcode >> 16) & 0x0F;\
1155 int shift = (opcode >> 7) & 0x1F;\
1156 int dest = (opcode>>12) & 15;\
1157 bool C_OUT = C_FLAG;\
1158 u32 value;\
1159 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1161 clockTicks = 1+codeTicksAccess32(armNextPC);\
1162 if ((opcode & 0x02000010)==0x10)\
1163 clockTicks++;\
1165 if(shift) {\
1166 LOGICAL_LSR_REG\
1167 } else {\
1168 value = 0;\
1169 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
1172 if(dest == 15) {\
1173 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1174 OPCODE2\
1175 /* todo */\
1176 if(opcode & 0x00100000) {\
1177 CPUSwitchMode(reg[17].I & 0x1f, false);\
1179 if(armState) {\
1180 reg[15].I &= 0xFFFFFFFC;\
1181 armNextPC = reg[15].I;\
1182 reg[15].I += 4;\
1183 ARM_PREFETCH;\
1184 } else {\
1185 reg[15].I &= 0xFFFFFFFE;\
1186 armNextPC = reg[15].I;\
1187 reg[15].I += 2;\
1188 THUMB_PREFETCH;\
1190 } else {\
1191 OPCODE \
1194 break;\
1195 case BASE+4:\
1196 case BASE+12:\
1198 /* OP Rd,Rb,Rm ASR # */\
1199 int base = (opcode >> 16) & 0x0F;\
1200 int shift = (opcode >> 7) & 0x1F;\
1201 int dest = (opcode>>12) & 15;\
1202 bool C_OUT = C_FLAG;\
1203 u32 value;\
1204 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1206 clockTicks = 1+codeTicksAccess32(armNextPC);\
1207 if ((opcode & 0x02000010)==0x10)\
1208 clockTicks++;\
1210 if(shift) {\
1211 LOGICAL_ASR_REG\
1212 } else {\
1213 if(reg[opcode & 0x0F].I & 0x80000000){\
1214 value = 0xFFFFFFFF;\
1215 C_OUT = true;\
1216 } else {\
1217 value = 0;\
1218 C_OUT = false;\
1222 if(dest == 15) {\
1223 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1224 OPCODE2\
1225 /* todo */\
1226 if(opcode & 0x00100000) {\
1227 CPUSwitchMode(reg[17].I & 0x1f, false);\
1229 if(armState) {\
1230 reg[15].I &= 0xFFFFFFFC;\
1231 armNextPC = reg[15].I;\
1232 reg[15].I += 4;\
1233 ARM_PREFETCH;\
1234 } else {\
1235 reg[15].I &= 0xFFFFFFFE;\
1236 armNextPC = reg[15].I;\
1237 reg[15].I += 2;\
1238 THUMB_PREFETCH;\
1240 } else {\
1241 OPCODE \
1244 break;\
1245 case BASE+6:\
1246 case BASE+14:\
1248 /* OP Rd,Rb,Rm ROR # */\
1249 int base = (opcode >> 16) & 0x0F;\
1250 int shift = (opcode >> 7) & 0x1F;\
1251 int dest = (opcode>>12) & 15;\
1252 bool C_OUT = C_FLAG;\
1253 u32 value;\
1254 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1256 clockTicks = 1+codeTicksAccess32(armNextPC);\
1257 if ((opcode & 0x02000010)==0x10)\
1258 clockTicks++;\
1260 if(shift) {\
1261 LOGICAL_ROR_REG\
1262 } else {\
1263 LOGICAL_RRX_REG\
1265 if(dest == 15) {\
1266 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1267 OPCODE2\
1268 /* todo */\
1269 if(opcode & 0x00100000) {\
1270 CPUSwitchMode(reg[17].I & 0x1f, false);\
1272 if(armState) {\
1273 reg[15].I &= 0xFFFFFFFC;\
1274 armNextPC = reg[15].I;\
1275 reg[15].I += 4;\
1276 ARM_PREFETCH;\
1277 } else {\
1278 reg[15].I &= 0xFFFFFFFE;\
1279 armNextPC = reg[15].I;\
1280 reg[15].I += 2;\
1281 THUMB_PREFETCH;\
1283 } else {\
1284 OPCODE \
1287 break;\
1288 case BASE+1:\
1290 /* OP Rd,Rb,Rm LSL Rs */\
1291 int base = (opcode >> 16) & 0x0F;\
1292 int shift = reg[(opcode >> 8)&15].B.B0;\
1293 int dest = (opcode>>12) & 15;\
1294 bool C_OUT = C_FLAG;\
1295 u32 value;\
1296 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1298 clockTicks = 1+codeTicksAccess32(armNextPC);\
1299 if ((opcode & 0x02000010)==0x10)\
1300 clockTicks++;\
1302 if(shift) {\
1303 if(shift == 32) {\
1304 value = 0;\
1305 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
1306 } else if(shift < 32) {\
1307 LOGICAL_LSL_REG\
1308 } else {\
1309 value = 0;\
1310 C_OUT = false;\
1312 } else {\
1313 value = reg[opcode & 0x0F].I;\
1315 if(dest == 15) {\
1316 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1317 OPCODE2\
1318 /* todo */\
1319 if(opcode & 0x00100000) {\
1320 CPUSwitchMode(reg[17].I & 0x1f, false);\
1322 if(armState) {\
1323 reg[15].I &= 0xFFFFFFFC;\
1324 armNextPC = reg[15].I;\
1325 reg[15].I += 4;\
1326 ARM_PREFETCH;\
1327 } else {\
1328 reg[15].I &= 0xFFFFFFFE;\
1329 armNextPC = reg[15].I;\
1330 reg[15].I += 2;\
1331 THUMB_PREFETCH;\
1333 } else {\
1334 OPCODE \
1337 break;\
1338 case BASE+3:\
1340 /* OP Rd,Rb,Rm LSR Rs */ \
1341 int base = (opcode >> 16) & 0x0F;\
1342 int shift = reg[(opcode >> 8)&15].B.B0;\
1343 int dest = (opcode>>12) & 15;\
1344 bool C_OUT = C_FLAG;\
1345 u32 value;\
1346 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1348 clockTicks = 1+codeTicksAccess32(armNextPC);\
1349 if ((opcode & 0x02000010)==0x10)\
1350 clockTicks++;\
1352 if(shift) {\
1353 if(shift == 32) {\
1354 value = 0;\
1355 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
1356 } else if(shift < 32) {\
1357 LOGICAL_LSR_REG\
1358 } else {\
1359 value = 0;\
1360 C_OUT = false;\
1362 } else {\
1363 value = reg[opcode & 0x0F].I;\
1365 if(dest == 15) {\
1366 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1367 OPCODE2\
1368 /* todo */\
1369 if(opcode & 0x00100000) {\
1370 CPUSwitchMode(reg[17].I & 0x1f, false);\
1372 if(armState) {\
1373 reg[15].I &= 0xFFFFFFFC;\
1374 armNextPC = reg[15].I;\
1375 reg[15].I += 4;\
1376 ARM_PREFETCH;\
1377 } else {\
1378 reg[15].I &= 0xFFFFFFFE;\
1379 armNextPC = reg[15].I;\
1380 reg[15].I += 2;\
1381 THUMB_PREFETCH;\
1383 } else {\
1384 OPCODE \
1387 break;\
1388 case BASE+5:\
1390 /* OP Rd,Rb,Rm ASR Rs */ \
1391 int base = (opcode >> 16) & 0x0F;\
1392 int shift = reg[(opcode >> 8)&15].B.B0;\
1393 int dest = (opcode>>12) & 15;\
1394 bool C_OUT = C_FLAG;\
1395 u32 value;\
1396 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1398 clockTicks = 1+codeTicksAccess32(armNextPC);\
1399 if ((opcode & 0x02000010)==0x10)\
1400 clockTicks++;\
1402 if(shift < 32) {\
1403 if(shift) {\
1404 LOGICAL_ASR_REG\
1405 } else {\
1406 value = reg[opcode & 0x0F].I;\
1408 } else {\
1409 if(reg[opcode & 0x0F].I & 0x80000000){\
1410 value = 0xFFFFFFFF;\
1411 C_OUT = true;\
1412 } else {\
1413 value = 0;\
1414 C_OUT = false;\
1417 if(dest == 15) {\
1418 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1419 OPCODE2\
1420 /* todo */\
1421 if(opcode & 0x00100000) {\
1422 CPUSwitchMode(reg[17].I & 0x1f, false);\
1424 if(armState) {\
1425 reg[15].I &= 0xFFFFFFFC;\
1426 armNextPC = reg[15].I;\
1427 reg[15].I += 4;\
1428 ARM_PREFETCH;\
1429 } else {\
1430 reg[15].I &= 0xFFFFFFFE;\
1431 armNextPC = reg[15].I;\
1432 reg[15].I += 2;\
1433 THUMB_PREFETCH;\
1435 } else {\
1436 OPCODE \
1439 break;\
1440 case BASE+7:\
1442 /* OP Rd,Rb,Rm ROR Rs */\
1443 int base = (opcode >> 16) & 0x0F;\
1444 int shift = reg[(opcode >> 8)&15].B.B0;\
1445 int dest = (opcode>>12) & 15;\
1446 bool C_OUT = C_FLAG;\
1447 u32 value;\
1448 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1450 clockTicks = 1+codeTicksAccess32(armNextPC);\
1451 if ((opcode & 0x02000010)==0x10)\
1452 clockTicks++;\
1454 if(shift) {\
1455 shift &= 0x1f;\
1456 if(shift) {\
1457 LOGICAL_ROR_REG\
1458 } else {\
1459 value = reg[opcode & 0x0F].I;\
1460 C_OUT = (value & 0x80000000 ? true : false);\
1462 } else {\
1463 value = reg[opcode & 0x0F].I;\
1464 C_OUT = (value & 0x80000000 ? true : false);\
1466 if(dest == 15) {\
1467 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1468 OPCODE2\
1469 /* todo */\
1470 if(opcode & 0x00100000) {\
1471 CPUSwitchMode(reg[17].I & 0x1f, false);\
1473 if(armState) {\
1474 reg[15].I &= 0xFFFFFFFC;\
1475 armNextPC = reg[15].I;\
1476 reg[15].I += 4;\
1477 ARM_PREFETCH;\
1478 } else {\
1479 reg[15].I &= 0xFFFFFFFE;\
1480 armNextPC = reg[15].I;\
1481 reg[15].I += 2;\
1482 THUMB_PREFETCH;\
1484 } else {\
1485 OPCODE \
1488 break;\
1489 case BASE+0x200:\
1490 case BASE+0x201:\
1491 case BASE+0x202:\
1492 case BASE+0x203:\
1493 case BASE+0x204:\
1494 case BASE+0x205:\
1495 case BASE+0x206:\
1496 case BASE+0x207:\
1497 case BASE+0x208:\
1498 case BASE+0x209:\
1499 case BASE+0x20a:\
1500 case BASE+0x20b:\
1501 case BASE+0x20c:\
1502 case BASE+0x20d:\
1503 case BASE+0x20e:\
1504 case BASE+0x20f:\
1506 int shift = (opcode & 0xF00) >> 7;\
1507 int base = (opcode >> 16) & 0x0F;\
1508 int dest = (opcode >> 12) & 0x0F;\
1509 bool C_OUT = C_FLAG;\
1510 u32 value;\
1511 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1513 clockTicks = 1+codeTicksAccess32(armNextPC);\
1514 if ((opcode & 0x02000010)==0x10)\
1515 clockTicks++;\
1517 if(shift) {\
1518 LOGICAL_ROR_IMM\
1519 } else {\
1520 value = opcode & 0xff;\
1522 if(dest == 15) {\
1523 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1524 OPCODE2\
1525 /* todo */\
1526 if(opcode & 0x00100000) {\
1527 CPUSwitchMode(reg[17].I & 0x1f, false);\
1529 if(armState) {\
1530 reg[15].I &= 0xFFFFFFFC;\
1531 armNextPC = reg[15].I;\
1532 reg[15].I += 4;\
1533 ARM_PREFETCH;\
1534 } else {\
1535 reg[15].I &= 0xFFFFFFFE;\
1536 armNextPC = reg[15].I;\
1537 reg[15].I += 2;\
1538 THUMB_PREFETCH;\
1540 } else {\
1541 OPCODE \
1544 break;
1546 #define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \
1547 case BASE: \
1548 case BASE+8:\
1550 /* OP Rd,Rb,Rm LSL # */ \
1551 int shift = (opcode >> 7) & 0x1F;\
1552 int dest = (opcode>>12) & 15;\
1553 bool C_OUT = C_FLAG;\
1554 u32 value;\
1555 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1557 clockTicks = 1+codeTicksAccess32(armNextPC);\
1558 if ((opcode & 0x02000010)==0x10)\
1559 clockTicks++;\
1562 if(shift) {\
1563 LOGICAL_LSL_REG\
1564 } else {\
1565 value = reg[opcode & 0x0F].I;\
1567 if(dest == 15) {\
1568 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1569 OPCODE2\
1570 /* todo */\
1571 if(opcode & 0x00100000) {\
1572 CPUSwitchMode(reg[17].I & 0x1f, false);\
1574 if(armState) {\
1575 reg[15].I &= 0xFFFFFFFC;\
1576 armNextPC = reg[15].I;\
1577 reg[15].I += 4;\
1578 ARM_PREFETCH;\
1579 } else {\
1580 reg[15].I &= 0xFFFFFFFE;\
1581 armNextPC = reg[15].I;\
1582 reg[15].I += 2;\
1583 THUMB_PREFETCH;\
1585 } else {\
1586 OPCODE \
1589 break;\
1590 case BASE+2:\
1591 case BASE+10:\
1593 /* OP Rd,Rb,Rm LSR # */ \
1594 int shift = (opcode >> 7) & 0x1F;\
1595 int dest = (opcode>>12) & 15;\
1596 bool C_OUT = C_FLAG;\
1597 u32 value;\
1598 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1600 clockTicks = 1+codeTicksAccess32(armNextPC);\
1601 if ((opcode & 0x02000010)==0x10)\
1602 clockTicks++;\
1604 if(shift) {\
1605 LOGICAL_LSR_REG\
1606 } else {\
1607 value = 0;\
1608 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
1611 if(dest == 15) {\
1612 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1613 OPCODE2\
1614 /* todo */\
1615 if(opcode & 0x00100000) {\
1616 CPUSwitchMode(reg[17].I & 0x1f, false);\
1618 if(armState) {\
1619 reg[15].I &= 0xFFFFFFFC;\
1620 armNextPC = reg[15].I;\
1621 reg[15].I += 4;\
1622 ARM_PREFETCH;\
1623 } else {\
1624 reg[15].I &= 0xFFFFFFFE;\
1625 armNextPC = reg[15].I;\
1626 reg[15].I += 2;\
1627 THUMB_PREFETCH;\
1629 } else {\
1630 OPCODE \
1633 break;\
1634 case BASE+4:\
1635 case BASE+12:\
1637 /* OP Rd,Rb,Rm ASR # */\
1638 int shift = (opcode >> 7) & 0x1F;\
1639 int dest = (opcode>>12) & 15;\
1640 bool C_OUT = C_FLAG;\
1641 u32 value;\
1642 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1644 clockTicks = 1+codeTicksAccess32(armNextPC);\
1645 if ((opcode & 0x02000010)==0x10)\
1646 clockTicks++;\
1648 if(shift) {\
1649 LOGICAL_ASR_REG\
1650 } else {\
1651 if(reg[opcode & 0x0F].I & 0x80000000){\
1652 value = 0xFFFFFFFF;\
1653 C_OUT = true;\
1654 } else {\
1655 value = 0;\
1656 C_OUT = false;\
1660 if(dest == 15) {\
1661 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1662 OPCODE2\
1663 /* todo */\
1664 if(opcode & 0x00100000) {\
1665 CPUSwitchMode(reg[17].I & 0x1f, false);\
1667 if(armState) {\
1668 reg[15].I &= 0xFFFFFFFC;\
1669 armNextPC = reg[15].I;\
1670 reg[15].I += 4;\
1671 ARM_PREFETCH;\
1672 } else {\
1673 reg[15].I &= 0xFFFFFFFE;\
1674 armNextPC = reg[15].I;\
1675 reg[15].I += 2;\
1676 THUMB_PREFETCH;\
1678 } else {\
1679 OPCODE \
1682 break;\
1683 case BASE+6:\
1684 case BASE+14:\
1686 /* OP Rd,Rb,Rm ROR # */\
1687 int shift = (opcode >> 7) & 0x1F;\
1688 int dest = (opcode>>12) & 15;\
1689 bool C_OUT = C_FLAG;\
1690 u32 value;\
1691 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1693 clockTicks = 1+codeTicksAccess32(armNextPC);\
1694 if ((opcode & 0x02000010)==0x10)\
1695 clockTicks++;\
1697 if(shift) {\
1698 LOGICAL_ROR_REG\
1699 } else {\
1700 LOGICAL_RRX_REG\
1702 if(dest == 15) {\
1703 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1704 OPCODE2\
1705 /* todo */\
1706 if(opcode & 0x00100000) {\
1707 CPUSwitchMode(reg[17].I & 0x1f, false);\
1709 if(armState) {\
1710 reg[15].I &= 0xFFFFFFFC;\
1711 armNextPC = reg[15].I;\
1712 reg[15].I += 4;\
1713 ARM_PREFETCH;\
1714 } else {\
1715 reg[15].I &= 0xFFFFFFFE;\
1716 armNextPC = reg[15].I;\
1717 reg[15].I += 2;\
1718 THUMB_PREFETCH;\
1720 } else {\
1721 OPCODE \
1724 break;\
1725 case BASE+1:\
1727 /* OP Rd,Rb,Rm LSL Rs */\
1728 int shift = reg[(opcode >> 8)&15].B.B0;\
1729 int dest = (opcode>>12) & 15;\
1730 bool C_OUT = C_FLAG;\
1731 u32 value;\
1732 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1734 clockTicks = 1+codeTicksAccess32(armNextPC);\
1735 if ((opcode & 0x02000010)==0x10)\
1736 clockTicks++;\
1738 if(shift) {\
1739 if(shift == 32) {\
1740 value = 0;\
1741 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
1742 } else if(shift < 32) {\
1743 LOGICAL_LSL_REG\
1744 } else {\
1745 value = 0;\
1746 C_OUT = false;\
1748 } else {\
1749 value = reg[opcode & 0x0F].I;\
1751 if(dest == 15) {\
1752 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1753 OPCODE2\
1754 /* todo */\
1755 if(opcode & 0x00100000) {\
1756 CPUSwitchMode(reg[17].I & 0x1f, false);\
1758 if(armState) {\
1759 reg[15].I &= 0xFFFFFFFC;\
1760 armNextPC = reg[15].I;\
1761 reg[15].I += 4;\
1762 ARM_PREFETCH;\
1763 } else {\
1764 reg[15].I &= 0xFFFFFFFE;\
1765 armNextPC = reg[15].I;\
1766 reg[15].I += 2;\
1767 THUMB_PREFETCH;\
1769 } else {\
1770 OPCODE \
1773 break;\
1774 case BASE+3:\
1776 /* OP Rd,Rb,Rm LSR Rs */ \
1777 int shift = reg[(opcode >> 8)&15].B.B0;\
1778 int dest = (opcode>>12) & 15;\
1779 bool C_OUT = C_FLAG;\
1780 u32 value;\
1781 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1783 clockTicks = 1+codeTicksAccess32(armNextPC);\
1784 if ((opcode & 0x02000010)==0x10)\
1785 clockTicks++;\
1787 if(shift) {\
1788 if(shift == 32) {\
1789 value = 0;\
1790 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
1791 } else if(shift < 32) {\
1792 LOGICAL_LSR_REG\
1793 } else {\
1794 value = 0;\
1795 C_OUT = false;\
1797 } else {\
1798 value = reg[opcode & 0x0F].I;\
1800 if(dest == 15) {\
1801 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1802 OPCODE2\
1803 /* todo */\
1804 if(opcode & 0x00100000) {\
1805 CPUSwitchMode(reg[17].I & 0x1f, false);\
1807 if(armState) {\
1808 reg[15].I &= 0xFFFFFFFC;\
1809 armNextPC = reg[15].I;\
1810 reg[15].I += 4;\
1811 ARM_PREFETCH;\
1812 } else {\
1813 reg[15].I &= 0xFFFFFFFE;\
1814 armNextPC = reg[15].I;\
1815 reg[15].I += 2;\
1816 THUMB_PREFETCH;\
1818 } else {\
1819 OPCODE \
1822 break;\
1823 case BASE+5:\
1825 /* OP Rd,Rb,Rm ASR Rs */ \
1826 int shift = reg[(opcode >> 8)&15].B.B0;\
1827 int dest = (opcode>>12) & 15;\
1828 bool C_OUT = C_FLAG;\
1829 u32 value;\
1830 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1832 clockTicks = 1+codeTicksAccess32(armNextPC);\
1833 if ((opcode & 0x02000010)==0x10)\
1834 clockTicks++;\
1836 if(shift < 32) {\
1837 if(shift) {\
1838 LOGICAL_ASR_REG\
1839 } else {\
1840 value = reg[opcode & 0x0F].I;\
1842 } else {\
1843 if(reg[opcode & 0x0F].I & 0x80000000){\
1844 value = 0xFFFFFFFF;\
1845 C_OUT = true;\
1846 } else {\
1847 value = 0;\
1848 C_OUT = false;\
1851 if(dest == 15) {\
1852 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1853 OPCODE2\
1854 /* todo */\
1855 if(opcode & 0x00100000) {\
1856 CPUSwitchMode(reg[17].I & 0x1f, false);\
1858 if(armState) {\
1859 reg[15].I &= 0xFFFFFFFC;\
1860 armNextPC = reg[15].I;\
1861 reg[15].I += 4;\
1862 ARM_PREFETCH;\
1863 } else {\
1864 reg[15].I &= 0xFFFFFFFE;\
1865 armNextPC = reg[15].I;\
1866 reg[15].I += 2;\
1867 THUMB_PREFETCH;\
1869 } else {\
1870 OPCODE \
1873 break;\
1874 case BASE+7:\
1876 /* OP Rd,Rb,Rm ROR Rs */\
1877 int shift = reg[(opcode >> 8)&15].B.B0;\
1878 int dest = (opcode>>12) & 15;\
1879 bool C_OUT = C_FLAG;\
1880 u32 value;\
1881 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1883 clockTicks = 1+codeTicksAccess32(armNextPC);\
1884 if ((opcode & 0x02000010)==0x10)\
1885 clockTicks++;\
1887 if(shift) {\
1888 shift &= 0x1f;\
1889 if(shift) {\
1890 LOGICAL_ROR_REG\
1891 } else {\
1892 value = reg[opcode & 0x0F].I;\
1893 C_OUT = (value & 0x80000000 ? true : false);\
1895 } else {\
1896 value = reg[opcode & 0x0F].I;\
1897 C_OUT = (value & 0x80000000 ? true : false);\
1899 if(dest == 15) {\
1900 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1901 OPCODE2\
1902 /* todo */\
1903 if(opcode & 0x00100000) {\
1904 CPUSwitchMode(reg[17].I & 0x1f, false);\
1906 if(armState) {\
1907 reg[15].I &= 0xFFFFFFFC;\
1908 armNextPC = reg[15].I;\
1909 reg[15].I += 4;\
1910 ARM_PREFETCH;\
1911 } else {\
1912 reg[15].I &= 0xFFFFFFFE;\
1913 armNextPC = reg[15].I;\
1914 reg[15].I += 2;\
1915 THUMB_PREFETCH;\
1917 } else {\
1918 OPCODE \
1921 break;\
1922 case BASE+0x200:\
1923 case BASE+0x201:\
1924 case BASE+0x202:\
1925 case BASE+0x203:\
1926 case BASE+0x204:\
1927 case BASE+0x205:\
1928 case BASE+0x206:\
1929 case BASE+0x207:\
1930 case BASE+0x208:\
1931 case BASE+0x209:\
1932 case BASE+0x20a:\
1933 case BASE+0x20b:\
1934 case BASE+0x20c:\
1935 case BASE+0x20d:\
1936 case BASE+0x20e:\
1937 case BASE+0x20f:\
1939 int shift = (opcode & 0xF00) >> 7;\
1940 int dest = (opcode >> 12) & 0x0F;\
1941 bool C_OUT = C_FLAG;\
1942 u32 value;\
1943 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1945 clockTicks = 1+codeTicksAccess32(armNextPC);\
1946 if ((opcode & 0x02000010)==0x10)\
1947 clockTicks++;\
1949 if(shift) {\
1950 LOGICAL_ROR_IMM\
1951 } else {\
1952 value = opcode & 0xff;\
1954 if(dest == 15) {\
1955 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1956 OPCODE2\
1957 /* todo */\
1958 if(opcode & 0x00100000) {\
1959 CPUSwitchMode(reg[17].I & 0x1f, false);\
1961 if(armState) {\
1962 reg[15].I &= 0xFFFFFFFC;\
1963 armNextPC = reg[15].I;\
1964 reg[15].I += 4;\
1965 ARM_PREFETCH;\
1966 } else {\
1967 reg[15].I &= 0xFFFFFFFE;\
1968 armNextPC = reg[15].I;\
1969 reg[15].I += 2;\
1970 THUMB_PREFETCH;\
1972 } else {\
1973 OPCODE \
1976 break;
1978 #define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
1979 case BASE:\
1980 case BASE+8:\
1982 /* OP Rd,Rb,Rm LSL # */\
1983 int base = (opcode >> 16) & 0x0F;\
1984 int shift = (opcode >> 7) & 0x1F;\
1985 int dest = (opcode>>12) & 15;\
1986 u32 value;\
1987 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1989 clockTicks = 1+codeTicksAccess32(armNextPC);\
1990 if ((opcode & 0x02000010)==0x10)\
1991 clockTicks++;\
1993 if(shift) {\
1994 ARITHMETIC_LSL_REG\
1995 } else {\
1996 value = reg[opcode & 0x0F].I;\
1998 if(dest == 15) {\
1999 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2000 OPCODE2\
2001 /* todo */\
2002 if(opcode & 0x00100000) {\
2003 CPUSwitchMode(reg[17].I & 0x1f, false);\
2005 if(armState) {\
2006 reg[15].I &= 0xFFFFFFFC;\
2007 armNextPC = reg[15].I;\
2008 reg[15].I += 4;\
2009 ARM_PREFETCH;\
2010 } else {\
2011 reg[15].I &= 0xFFFFFFFE;\
2012 armNextPC = reg[15].I;\
2013 reg[15].I += 2;\
2014 THUMB_PREFETCH;\
2016 } else {\
2017 OPCODE \
2020 break;\
2021 case BASE+2:\
2022 case BASE+10:\
2024 /* OP Rd,Rb,Rm LSR # */\
2025 int base = (opcode >> 16) & 0x0F;\
2026 int shift = (opcode >> 7) & 0x1F;\
2027 int dest = (opcode>>12) & 15;\
2028 u32 value;\
2029 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2031 clockTicks = 1+codeTicksAccess32(armNextPC);\
2032 if ((opcode & 0x02000010)==0x10)\
2033 clockTicks++;\
2035 if(shift) {\
2036 ARITHMETIC_LSR_REG\
2037 } else {\
2038 value = 0;\
2040 if(dest == 15) {\
2041 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2042 OPCODE2\
2043 /* todo */\
2044 if(opcode & 0x00100000) {\
2045 CPUSwitchMode(reg[17].I & 0x1f, false);\
2047 if(armState) {\
2048 reg[15].I &= 0xFFFFFFFC;\
2049 armNextPC = reg[15].I;\
2050 reg[15].I += 4;\
2051 ARM_PREFETCH;\
2052 } else {\
2053 reg[15].I &= 0xFFFFFFFE;\
2054 armNextPC = reg[15].I;\
2055 reg[15].I += 2;\
2056 THUMB_PREFETCH;\
2058 } else {\
2059 OPCODE \
2062 break;\
2063 case BASE+4:\
2064 case BASE+12:\
2066 /* OP Rd,Rb,Rm ASR # */\
2067 int base = (opcode >> 16) & 0x0F;\
2068 int shift = (opcode >> 7) & 0x1F;\
2069 int dest = (opcode>>12) & 15;\
2070 u32 value;\
2071 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2073 clockTicks = 1+codeTicksAccess32(armNextPC);\
2074 if ((opcode & 0x02000010)==0x10)\
2075 clockTicks++;\
2077 if(shift) {\
2078 ARITHMETIC_ASR_REG\
2079 } else {\
2080 if(reg[opcode & 0x0F].I & 0x80000000){\
2081 value = 0xFFFFFFFF;\
2082 } else value = 0;\
2084 if(dest == 15) {\
2085 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2086 OPCODE2\
2087 /* todo */\
2088 if(opcode & 0x00100000) {\
2089 CPUSwitchMode(reg[17].I & 0x1f, false);\
2091 if(armState) {\
2092 reg[15].I &= 0xFFFFFFFC;\
2093 armNextPC = reg[15].I;\
2094 reg[15].I += 4;\
2095 ARM_PREFETCH;\
2096 } else {\
2097 reg[15].I &= 0xFFFFFFFE;\
2098 armNextPC = reg[15].I;\
2099 reg[15].I += 2;\
2100 THUMB_PREFETCH;\
2102 } else {\
2103 OPCODE \
2106 break;\
2107 case BASE+6:\
2108 case BASE+14:\
2110 /* OP Rd,Rb,Rm ROR # */\
2111 int base = (opcode >> 16) & 0x0F;\
2112 int shift = (opcode >> 7) & 0x1F;\
2113 int dest = (opcode>>12) & 15;\
2114 u32 value;\
2115 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2117 clockTicks = 1+codeTicksAccess32(armNextPC);\
2118 if ((opcode & 0x02000010)==0x10)\
2119 clockTicks++;\
2121 if(shift) {\
2122 ARITHMETIC_ROR_REG\
2123 } else {\
2124 ARITHMETIC_RRX_REG\
2126 if(dest == 15) {\
2127 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2128 OPCODE2\
2129 /* todo */\
2130 if(opcode & 0x00100000) {\
2131 CPUSwitchMode(reg[17].I & 0x1f, false);\
2133 if(armState) {\
2134 reg[15].I &= 0xFFFFFFFC;\
2135 armNextPC = reg[15].I;\
2136 reg[15].I += 4;\
2137 ARM_PREFETCH;\
2138 } else {\
2139 reg[15].I &= 0xFFFFFFFE;\
2140 armNextPC = reg[15].I;\
2141 reg[15].I += 2;\
2142 THUMB_PREFETCH;\
2144 } else {\
2145 OPCODE \
2148 break;\
2149 case BASE+1:\
2151 /* OP Rd,Rb,Rm LSL Rs */\
2152 int base = (opcode >> 16) & 0x0F;\
2153 int shift = reg[(opcode >> 8)&15].B.B0;\
2154 int dest = (opcode>>12) & 15;\
2155 u32 value;\
2156 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2158 clockTicks = 1+codeTicksAccess32(armNextPC);\
2159 if ((opcode & 0x02000010)==0x10)\
2160 clockTicks++;\
2162 if(shift) {\
2163 if(shift == 32) {\
2164 value = 0;\
2165 } else if(shift < 32) {\
2166 ARITHMETIC_LSL_REG\
2167 } else value = 0;\
2168 } else {\
2169 value = reg[opcode & 0x0F].I;\
2171 if(dest == 15) {\
2172 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2173 OPCODE2\
2174 /* todo */\
2175 if(opcode & 0x00100000) {\
2176 CPUSwitchMode(reg[17].I & 0x1f, false);\
2178 if(armState) {\
2179 reg[15].I &= 0xFFFFFFFC;\
2180 armNextPC = reg[15].I;\
2181 reg[15].I += 4;\
2182 ARM_PREFETCH;\
2183 } else {\
2184 reg[15].I &= 0xFFFFFFFE;\
2185 armNextPC = reg[15].I;\
2186 reg[15].I += 2;\
2187 THUMB_PREFETCH;\
2189 } else {\
2190 OPCODE \
2193 break;\
2194 case BASE+3:\
2196 /* OP Rd,Rb,Rm LSR Rs */\
2197 int base = (opcode >> 16) & 0x0F;\
2198 int shift = reg[(opcode >> 8)&15].B.B0;\
2199 int dest = (opcode>>12) & 15;\
2200 u32 value;\
2201 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2203 clockTicks = 1+codeTicksAccess32(armNextPC);\
2204 if ((opcode & 0x02000010)==0x10)\
2205 clockTicks++;\
2207 if(shift) {\
2208 if(shift == 32) {\
2209 value = 0;\
2210 } else if(shift < 32) {\
2211 ARITHMETIC_LSR_REG\
2212 } else value = 0;\
2213 } else {\
2214 value = reg[opcode & 0x0F].I;\
2216 if(dest == 15) {\
2217 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2218 OPCODE2\
2219 /* todo */\
2220 if(opcode & 0x00100000) {\
2221 CPUSwitchMode(reg[17].I & 0x1f, false);\
2223 if(armState) {\
2224 reg[15].I &= 0xFFFFFFFC;\
2225 armNextPC = reg[15].I;\
2226 reg[15].I += 4;\
2227 ARM_PREFETCH;\
2228 } else {\
2229 reg[15].I &= 0xFFFFFFFE;\
2230 armNextPC = reg[15].I;\
2231 reg[15].I += 2;\
2232 THUMB_PREFETCH;\
2234 } else {\
2235 OPCODE \
2238 break;\
2239 case BASE+5:\
2241 /* OP Rd,Rb,Rm ASR Rs */\
2242 int base = (opcode >> 16) & 0x0F;\
2243 int shift = reg[(opcode >> 8)&15].B.B0;\
2244 int dest = (opcode>>12) & 15;\
2245 u32 value;\
2246 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2248 clockTicks = 1+codeTicksAccess32(armNextPC);\
2249 if ((opcode & 0x02000010)==0x10)\
2250 clockTicks++;\
2252 if(shift < 32) {\
2253 if(shift) {\
2254 ARITHMETIC_ASR_REG\
2255 } else {\
2256 value = reg[opcode & 0x0F].I;\
2258 } else {\
2259 if(reg[opcode & 0x0F].I & 0x80000000){\
2260 value = 0xFFFFFFFF;\
2261 } else value = 0;\
2263 if(dest == 15) {\
2264 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2265 OPCODE2\
2266 /* todo */\
2267 if(opcode & 0x00100000) {\
2268 CPUSwitchMode(reg[17].I & 0x1f, false);\
2270 if(armState) {\
2271 reg[15].I &= 0xFFFFFFFC;\
2272 armNextPC = reg[15].I;\
2273 reg[15].I += 4;\
2274 ARM_PREFETCH;\
2275 } else {\
2276 reg[15].I &= 0xFFFFFFFE;\
2277 armNextPC = reg[15].I;\
2278 reg[15].I += 2;\
2279 THUMB_PREFETCH;\
2281 } else {\
2282 OPCODE \
2285 break;\
2286 case BASE+7:\
2288 /* OP Rd,Rb,Rm ROR Rs */\
2289 int base = (opcode >> 16) & 0x0F;\
2290 int shift = reg[(opcode >> 8)&15].B.B0;\
2291 int dest = (opcode>>12) & 15;\
2292 u32 value;\
2293 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2295 clockTicks = 1+codeTicksAccess32(armNextPC);\
2296 if ((opcode & 0x02000010)==0x10)\
2297 clockTicks++;\
2299 if(shift) {\
2300 shift &= 0x1f;\
2301 if(shift) {\
2302 ARITHMETIC_ROR_REG\
2303 } else {\
2304 value = reg[opcode & 0x0F].I;\
2306 } else {\
2307 value = reg[opcode & 0x0F].I;\
2309 if(dest == 15) {\
2310 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2311 OPCODE2\
2312 /* todo */\
2313 if(opcode & 0x00100000) {\
2314 CPUSwitchMode(reg[17].I & 0x1f, false);\
2316 if(armState) {\
2317 reg[15].I &= 0xFFFFFFFC;\
2318 armNextPC = reg[15].I;\
2319 reg[15].I += 4;\
2320 ARM_PREFETCH;\
2321 } else {\
2322 reg[15].I &= 0xFFFFFFFE;\
2323 armNextPC = reg[15].I;\
2324 reg[15].I += 2;\
2325 THUMB_PREFETCH;\
2327 } else {\
2328 OPCODE \
2331 break;\
2332 case BASE+0x200:\
2333 case BASE+0x201:\
2334 case BASE+0x202:\
2335 case BASE+0x203:\
2336 case BASE+0x204:\
2337 case BASE+0x205:\
2338 case BASE+0x206:\
2339 case BASE+0x207:\
2340 case BASE+0x208:\
2341 case BASE+0x209:\
2342 case BASE+0x20a:\
2343 case BASE+0x20b:\
2344 case BASE+0x20c:\
2345 case BASE+0x20d:\
2346 case BASE+0x20e:\
2347 case BASE+0x20f:\
2349 int shift = (opcode & 0xF00) >> 7;\
2350 int base = (opcode >> 16) & 0x0F;\
2351 int dest = (opcode >> 12) & 0x0F;\
2352 u32 value;\
2353 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
2355 clockTicks = 1+codeTicksAccess32(armNextPC);\
2356 if ((opcode & 0x02000010)==0x10)\
2357 clockTicks++;\
2360 ARITHMETIC_ROR_IMM\
2362 if(dest == 15) {\
2363 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
2364 OPCODE2\
2365 /* todo */\
2366 if(opcode & 0x00100000) {\
2367 CPUSwitchMode(reg[17].I & 0x1f, false);\
2369 if(armState) {\
2370 reg[15].I &= 0xFFFFFFFC;\
2371 armNextPC = reg[15].I;\
2372 reg[15].I += 4;\
2373 ARM_PREFETCH;\
2374 } else {\
2375 reg[15].I &= 0xFFFFFFFE;\
2376 armNextPC = reg[15].I;\
2377 reg[15].I += 2;\
2378 THUMB_PREFETCH;\
2380 } else {\
2381 OPCODE \
2384 break;
2386 u32 opcode = cpuPrefetch[0];
2387 cpuPrefetch[0] = cpuPrefetch[1];
2389 busPrefetch = false;
2390 if (busPrefetchCount & 0xFFFFFE00)
2391 busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
2394 clockTicks = 0;//codeTicksAccessSeq32(armNextPC)+1;
2395 int oldArmNextPC = armNextPC;
2397 #ifndef FINAL_VERSION
2398 if(armNextPC == stop) {
2399 armNextPC++;
2401 #endif
2403 armNextPC = reg[15].I;
2404 reg[15].I += 4;
2405 ARM_PREFETCH_NEXT;
2407 int cond = opcode >> 28;
2408 // suggested optimization for frequent cases
2409 bool cond_res;
2410 if(cond == 0x0e) {
2411 cond_res = true;
2412 } else {
2413 switch(cond) {
2414 case 0x00: // EQ
2415 cond_res = Z_FLAG;
2416 break;
2417 case 0x01: // NE
2418 cond_res = !Z_FLAG;
2419 break;
2420 case 0x02: // CS
2421 cond_res = C_FLAG;
2422 break;
2423 case 0x03: // CC
2424 cond_res = !C_FLAG;
2425 break;
2426 case 0x04: // MI
2427 cond_res = N_FLAG;
2428 break;
2429 case 0x05: // PL
2430 cond_res = !N_FLAG;
2431 break;
2432 case 0x06: // VS
2433 cond_res = V_FLAG;
2434 break;
2435 case 0x07: // VC
2436 cond_res = !V_FLAG;
2437 break;
2438 case 0x08: // HI
2439 cond_res = C_FLAG && !Z_FLAG;
2440 break;
2441 case 0x09: // LS
2442 cond_res = !C_FLAG || Z_FLAG;
2443 break;
2444 case 0x0A: // GE
2445 cond_res = N_FLAG == V_FLAG;
2446 break;
2447 case 0x0B: // LT
2448 cond_res = N_FLAG != V_FLAG;
2449 break;
2450 case 0x0C: // GT
2451 cond_res = !Z_FLAG &&(N_FLAG == V_FLAG);
2452 break;
2453 case 0x0D: // LE
2454 cond_res = Z_FLAG || (N_FLAG != V_FLAG);
2455 break;
2456 case 0x0E:
2457 cond_res = true;
2458 break;
2459 case 0x0F:
2460 default:
2461 // ???
2462 cond_res = false;
2463 break;
2467 if(cond_res) {
2468 switch(((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)) {
2469 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND, OP_AND, 0x000);
2470 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010);
2471 case 0x009:
2473 // MUL Rd, Rm, Rs
2474 int dest = (opcode >> 16) & 0x0F;
2475 int mult = (opcode & 0x0F);
2476 clockTicks = 1;
2477 u32 rs = reg[(opcode >> 8) & 0x0F].I;
2478 reg[dest].I = reg[mult].I * rs;
2479 if(((s32)rs)<0)
2480 rs = ~rs;
2481 if((rs & 0xFFFFFF00) == 0)
2482 clockTicks += 0;
2483 else if ((rs & 0xFFFF0000) == 0)
2484 clockTicks += 1;
2485 else if ((rs & 0xFF000000) == 0)
2486 clockTicks += 2;
2487 else
2488 clockTicks += 3;
2489 if (!busPrefetchCount)
2490 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
2491 clockTicks += codeTicksAccess32(armNextPC) + 1;
2494 break;
2495 case 0x019:
2497 // MULS Rd, Rm, Rs
2498 int dest = (opcode >> 16) & 0x0F;
2499 int mult = (opcode & 0x0F);
2500 clockTicks = 1;
2501 u32 rs = reg[(opcode >> 8) & 0x0F].I;
2502 reg[dest].I = reg[mult].I * rs;
2503 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
2504 Z_FLAG = (reg[dest].I) ? false : true;
2505 if(((s32)rs)<0)
2506 rs = ~rs;
2507 if((rs & 0xFFFFFF00) == 0)
2508 clockTicks += 0;
2509 else if ((rs & 0xFFFF0000) == 0)
2510 clockTicks += 1;
2511 else if ((rs & 0xFF000000) == 0)
2512 clockTicks += 2;
2513 else
2514 clockTicks += 3;
2515 if (!busPrefetchCount)
2516 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
2517 clockTicks += codeTicksAccess32(armNextPC) + 1;
2519 break;
2520 case 0x00b:
2521 case 0x02b:
2523 // STRH Rd, [Rn], -Rm
2524 if (!busPrefetchCount)
2525 busPrefetch = busPrefetchEnable;
2526 int base = (opcode >> 16) & 0x0F;
2527 int dest = (opcode >> 12) & 0x0F;
2528 u32 address = reg[base].I;
2529 int offset = reg[opcode & 0x0F].I;
2530 clockTicks = 2 + dataTicksAccess16(address) +
2531 codeTicksAccess32(armNextPC);
2532 CPUWriteHalfWord(address, reg[dest].W.W0);
2533 address -= offset;
2534 reg[base].I = address;
2536 break;
2537 case 0x04b:
2538 case 0x06b:
2540 // STRH Rd, [Rn], #-offset
2541 if (!busPrefetchCount)
2542 busPrefetch = busPrefetchEnable;
2543 int base = (opcode >> 16) & 0x0F;
2544 int dest = (opcode >> 12) & 0x0F;
2545 u32 address = reg[base].I;
2546 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2547 clockTicks = 2 + dataTicksAccess16(address)
2548 + codeTicksAccess32(armNextPC);
2549 CPUWriteHalfWord(address, reg[dest].W.W0);
2550 address -= offset;
2551 reg[base].I = address;
2553 break;
2554 case 0x08b:
2555 case 0x0ab:
2557 // STRH Rd, [Rn], Rm
2558 if (!busPrefetchCount)
2559 busPrefetch = busPrefetchEnable;
2560 int base = (opcode >> 16) & 0x0F;
2561 int dest = (opcode >> 12) & 0x0F;
2562 u32 address = reg[base].I;
2563 int offset = reg[opcode & 0x0F].I;
2564 clockTicks = 2 + dataTicksAccess16(address) +
2565 codeTicksAccess32(armNextPC);
2566 CPUWriteHalfWord(address, reg[dest].W.W0);
2567 address += offset;
2568 reg[base].I = address;
2570 break;
2571 case 0x0cb:
2572 case 0x0eb:
2574 // STRH Rd, [Rn], #offset
2575 if (!busPrefetchCount)
2576 busPrefetch = busPrefetchEnable;
2577 int base = (opcode >> 16) & 0x0F;
2578 int dest = (opcode >> 12) & 0x0F;
2579 u32 address = reg[base].I;
2580 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2581 clockTicks = 2 + dataTicksAccess16(address) +
2582 codeTicksAccess32(armNextPC);
2583 CPUWriteHalfWord(address, reg[dest].W.W0);
2584 address += offset;
2585 reg[base].I = address;
2587 break;
2588 case 0x10b:
2590 // STRH Rd, [Rn, -Rm]
2591 if (!busPrefetchCount)
2592 busPrefetch = busPrefetchEnable;
2593 int base = (opcode >> 16) & 0x0F;
2594 int dest = (opcode >> 12) & 0x0F;
2595 u32 address = reg[base].I - reg[opcode & 0x0F].I;
2596 clockTicks = 2 + dataTicksAccess16(address) +
2597 codeTicksAccess32(armNextPC);
2598 CPUWriteHalfWord(address, reg[dest].W.W0);
2600 break;
2601 case 0x12b:
2603 // STRH Rd, [Rn, -Rm]!
2604 if (!busPrefetchCount)
2605 busPrefetch = busPrefetchEnable;
2606 int base = (opcode >> 16) & 0x0F;
2607 int dest = (opcode >> 12) & 0x0F;
2608 u32 address = reg[base].I - reg[opcode & 0x0F].I;
2609 clockTicks = 2 + dataTicksAccess16(address) +
2610 codeTicksAccess32(armNextPC);
2611 CPUWriteHalfWord(address, reg[dest].W.W0);
2612 reg[base].I = address;
2614 break;
2615 case 0x14b:
2617 // STRH Rd, [Rn, -#offset]
2618 if (!busPrefetchCount)
2619 busPrefetch = busPrefetchEnable;
2620 int base = (opcode >> 16) & 0x0F;
2621 int dest = (opcode >> 12) & 0x0F;
2622 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2623 clockTicks = 2 + dataTicksAccess16(address) +
2624 codeTicksAccess32(armNextPC);
2625 CPUWriteHalfWord(address, reg[dest].W.W0);
2627 break;
2628 case 0x16b:
2630 // STRH Rd, [Rn, -#offset]!
2631 if (!busPrefetchCount)
2632 busPrefetch = busPrefetchEnable;
2633 int base = (opcode >> 16) & 0x0F;
2634 int dest = (opcode >> 12) & 0x0F;
2635 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2636 clockTicks = 2 + dataTicksAccess16(address) +
2637 codeTicksAccess32(armNextPC);
2638 CPUWriteHalfWord(address, reg[dest].W.W0);
2639 reg[base].I = address;
2641 break;
2642 case 0x18b:
2644 // STRH Rd, [Rn, Rm]
2645 if (!busPrefetchCount)
2646 busPrefetch = busPrefetchEnable;
2647 int base = (opcode >> 16) & 0x0F;
2648 int dest = (opcode >> 12) & 0x0F;
2649 u32 address = reg[base].I + reg[opcode & 0x0F].I;
2650 clockTicks = 2 + dataTicksAccess16(address) +
2651 codeTicksAccess32(armNextPC);
2652 CPUWriteHalfWord(address, reg[dest].W.W0);
2654 break;
2655 case 0x1ab:
2657 // STRH Rd, [Rn, Rm]!
2658 if (!busPrefetchCount)
2659 busPrefetch = busPrefetchEnable;
2660 int base = (opcode >> 16) & 0x0F;
2661 int dest = (opcode >> 12) & 0x0F;
2662 u32 address = reg[base].I + reg[opcode & 0x0F].I;
2663 clockTicks = 2 + dataTicksAccess16(address) +
2664 codeTicksAccess32(armNextPC);
2665 CPUWriteHalfWord(address, reg[dest].W.W0);
2666 reg[base].I = address;
2668 break;
2669 case 0x1cb:
2671 // STRH Rd, [Rn, #offset]
2672 if (!busPrefetchCount)
2673 busPrefetch = busPrefetchEnable;
2674 int base = (opcode >> 16) & 0x0F;
2675 int dest = (opcode >> 12) & 0x0F;
2676 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2677 clockTicks = 2 + dataTicksAccess16(address) +
2678 codeTicksAccess32(armNextPC);
2679 CPUWriteHalfWord(address, reg[dest].W.W0);
2681 break;
2682 case 0x1eb:
2684 // STRH Rd, [Rn, #offset]!
2685 if (!busPrefetchCount)
2686 busPrefetch = busPrefetchEnable;
2687 int base = (opcode >> 16) & 0x0F;
2688 int dest = (opcode >> 12) & 0x0F;
2689 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2690 clockTicks = 2 + dataTicksAccess16(address) +
2691 codeTicksAccess32(armNextPC);
2692 CPUWriteHalfWord(address, reg[dest].W.W0);
2693 reg[base].I = address;
2695 break;
2696 case 0x01b:
2697 case 0x03b:
2699 // LDRH Rd, [Rn], -Rm
2700 if (!busPrefetchCount)
2701 busPrefetch = busPrefetchEnable;
2702 int base = (opcode >> 16) & 0x0F;
2703 int dest = (opcode >> 12) & 0x0F;
2704 u32 address = reg[base].I;
2705 int offset = reg[opcode & 0x0F].I;
2706 reg[dest].I = CPUReadHalfWord(address);
2707 if(dest != base) {
2708 address -= offset;
2709 reg[base].I = address;
2711 clockTicks = 0;
2712 if(dest == 15) {
2713 reg[15].I &= 0xFFFFFFFC;
2714 armNextPC = reg[15].I;
2715 reg[15].I += 4;
2716 ARM_PREFETCH;
2717 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2719 clockTicks += 3 + dataTicksAccess16(address) +
2720 codeTicksAccess32(armNextPC);
2722 break;
2723 case 0x05b:
2724 case 0x07b:
2726 // LDRH Rd, [Rn], #-offset
2727 if (!busPrefetchCount)
2728 busPrefetch = busPrefetchEnable;
2729 int base = (opcode >> 16) & 0x0F;
2730 int dest = (opcode >> 12) & 0x0F;
2731 u32 address = reg[base].I;
2732 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2733 reg[dest].I = CPUReadHalfWord(address);
2734 if(dest != base) {
2735 address -= offset;
2736 reg[base].I = address;
2738 clockTicks=0;
2739 if(dest == 15) {
2740 reg[15].I &= 0xFFFFFFFC;
2741 armNextPC = reg[15].I;
2742 reg[15].I += 4;
2743 ARM_PREFETCH;
2744 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2746 clockTicks += 3 + dataTicksAccess16(address) +
2747 codeTicksAccess32(armNextPC);
2749 break;
2750 case 0x09b:
2751 case 0x0bb:
2753 // LDRH Rd, [Rn], Rm
2754 if (!busPrefetchCount)
2755 busPrefetch = busPrefetchEnable;
2756 int base = (opcode >> 16) & 0x0F;
2757 int dest = (opcode >> 12) & 0x0F;
2758 u32 address = reg[base].I;
2759 int offset = reg[opcode & 0x0F].I;
2760 reg[dest].I = CPUReadHalfWord(address);
2761 if(dest != base) {
2762 address += offset;
2763 reg[base].I = address;
2765 clockTicks = 0;
2766 if(dest == 15) {
2767 reg[15].I &= 0xFFFFFFFC;
2768 armNextPC = reg[15].I;
2769 reg[15].I += 4;
2770 ARM_PREFETCH;
2771 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2773 clockTicks += 3 + dataTicksAccess16(address) +
2774 codeTicksAccess32(armNextPC);
2776 break;
2777 case 0x0db:
2778 case 0x0fb:
2780 // LDRH Rd, [Rn], #offset
2781 if (!busPrefetchCount)
2782 busPrefetch = busPrefetchEnable;
2783 int base = (opcode >> 16) & 0x0F;
2784 int dest = (opcode >> 12) & 0x0F;
2785 u32 address = reg[base].I;
2786 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2787 reg[dest].I = CPUReadHalfWord(address);
2788 if(dest != base) {
2789 address += offset;
2790 reg[base].I = address;
2792 clockTicks = 0;
2793 if(dest == 15) {
2794 reg[15].I &= 0xFFFFFFFC;
2795 armNextPC = reg[15].I;
2796 reg[15].I += 4;
2797 ARM_PREFETCH;
2798 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2800 clockTicks += 3 + dataTicksAccess16(address) +
2801 codeTicksAccess32(armNextPC);
2803 break;
2804 case 0x11b:
2806 // LDRH Rd, [Rn, -Rm]
2807 if (!busPrefetchCount)
2808 busPrefetch = busPrefetchEnable;
2809 int base = (opcode >> 16) & 0x0F;
2810 int dest = (opcode >> 12) & 0x0F;
2811 u32 address = reg[base].I - reg[opcode & 0x0F].I;
2812 reg[dest].I = CPUReadHalfWord(address);
2813 clockTicks = 0;
2814 if(dest == 15) {
2815 reg[15].I &= 0xFFFFFFFC;
2816 armNextPC = reg[15].I;
2817 reg[15].I += 4;
2818 ARM_PREFETCH;
2819 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2821 clockTicks += 3 + dataTicksAccess16(address) +
2822 codeTicksAccess32(armNextPC);
2824 break;
2825 case 0x13b:
2827 // LDRH Rd, [Rn, -Rm]!
2828 if (!busPrefetchCount)
2829 busPrefetch = busPrefetchEnable;
2830 int base = (opcode >> 16) & 0x0F;
2831 int dest = (opcode >> 12) & 0x0F;
2832 u32 address = reg[base].I - reg[opcode & 0x0F].I;
2833 reg[dest].I = CPUReadHalfWord(address);
2834 if(dest != base)
2835 reg[base].I = address;
2836 clockTicks = 0;
2837 if(dest == 15) {
2838 reg[15].I &= 0xFFFFFFFC;
2839 armNextPC = reg[15].I;
2840 reg[15].I += 4;
2841 ARM_PREFETCH;
2842 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2844 clockTicks += 3 + dataTicksAccess16(address) +
2845 codeTicksAccess32(armNextPC);
2847 break;
2848 case 0x15b:
2850 // LDRH Rd, [Rn, -#offset]
2851 if (!busPrefetchCount)
2852 busPrefetch = busPrefetchEnable;
2853 int base = (opcode >> 16) & 0x0F;
2854 int dest = (opcode >> 12) & 0x0F;
2855 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2856 reg[dest].I = CPUReadHalfWord(address);
2857 clockTicks = 0;
2858 if(dest == 15) {
2859 reg[15].I &= 0xFFFFFFFC;
2860 armNextPC = reg[15].I;
2861 reg[15].I += 4;
2862 ARM_PREFETCH;
2863 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2865 clockTicks += 3 + dataTicksAccess16(address) +
2866 codeTicksAccess32(armNextPC);
2868 break;
2869 case 0x17b:
2871 // LDRH Rd, [Rn, -#offset]!
2872 if (!busPrefetchCount)
2873 busPrefetch = busPrefetchEnable;
2874 int base = (opcode >> 16) & 0x0F;
2875 int dest = (opcode >> 12) & 0x0F;
2876 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2877 reg[dest].I = CPUReadHalfWord(address);
2878 if(dest != base)
2879 reg[base].I = address;
2880 clockTicks = 0;
2881 if(dest == 15) {
2882 reg[15].I &= 0xFFFFFFFC;
2883 armNextPC = reg[15].I;
2884 reg[15].I += 4;
2885 ARM_PREFETCH;
2886 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2888 clockTicks += 3 + dataTicksAccess16(address) +
2889 codeTicksAccess32(armNextPC);
2891 break;
2892 case 0x19b:
2894 // LDRH Rd, [Rn, Rm]
2895 if (!busPrefetchCount)
2896 busPrefetch = busPrefetchEnable;
2897 int base = (opcode >> 16) & 0x0F;
2898 int dest = (opcode >> 12) & 0x0F;
2899 u32 address = reg[base].I + reg[opcode & 0x0F].I;
2900 reg[dest].I = CPUReadHalfWord(address);
2901 clockTicks = 0;
2902 if(dest == 15) {
2903 reg[15].I &= 0xFFFFFFFC;
2904 armNextPC = reg[15].I;
2905 reg[15].I += 4;
2906 ARM_PREFETCH;
2907 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2909 clockTicks += 3 + dataTicksAccess16(address) +
2910 codeTicksAccess32(armNextPC);
2912 break;
2913 case 0x1bb:
2915 // LDRH Rd, [Rn, Rm]!
2916 if (!busPrefetchCount)
2917 busPrefetch = busPrefetchEnable;
2918 int base = (opcode >> 16) & 0x0F;
2919 int dest = (opcode >> 12) & 0x0F;
2920 u32 address = reg[base].I + reg[opcode & 0x0F].I;
2921 reg[dest].I = CPUReadHalfWord(address);
2922 if(dest != base)
2923 reg[base].I = address;
2924 clockTicks = 0;
2925 if(dest == 15) {
2926 reg[15].I &= 0xFFFFFFFC;
2927 armNextPC = reg[15].I;
2928 reg[15].I += 4;
2929 ARM_PREFETCH;
2930 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2932 clockTicks += 3 + dataTicksAccess16(address) +
2933 codeTicksAccess32(armNextPC);
2935 break;
2936 case 0x1db:
2938 // LDRH Rd, [Rn, #offset]
2939 if (!busPrefetchCount)
2940 busPrefetch = busPrefetchEnable;
2941 int base = (opcode >> 16) & 0x0F;
2942 int dest = (opcode >> 12) & 0x0F;
2943 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2944 reg[dest].I = CPUReadHalfWord(address);
2945 clockTicks = 0;
2946 if(dest == 15) {
2947 reg[15].I &= 0xFFFFFFFC;
2948 armNextPC = reg[15].I;
2949 reg[15].I += 4;
2950 ARM_PREFETCH;
2951 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2953 clockTicks += 3 + dataTicksAccess16(address) +
2954 codeTicksAccess32(armNextPC);
2956 break;
2957 case 0x1fb:
2959 // LDRH Rd, [Rn, #offset]!
2960 if (!busPrefetchCount)
2961 busPrefetch = busPrefetchEnable;
2962 int base = (opcode >> 16) & 0x0F;
2963 int dest = (opcode >> 12) & 0x0F;
2964 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2965 reg[dest].I = CPUReadHalfWord(address);
2966 if(dest != base)
2967 reg[base].I = address;
2968 clockTicks = 0;
2969 if(dest == 15) {
2970 reg[15].I &= 0xFFFFFFFC;
2971 armNextPC = reg[15].I;
2972 reg[15].I += 4;
2973 ARM_PREFETCH;
2974 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2976 clockTicks += 3 + dataTicksAccess16(address) +
2977 codeTicksAccess32(armNextPC);
2979 break;
2980 case 0x01d:
2981 case 0x03d:
2983 // LDRSB Rd, [Rn], -Rm
2984 if (!busPrefetchCount)
2985 busPrefetch = busPrefetchEnable;
2986 int base = (opcode >> 16) & 0x0F;
2987 int dest = (opcode >> 12) & 0x0F;
2988 u32 address = reg[base].I;
2989 int offset = reg[opcode & 0x0F].I;
2990 reg[dest].I = (s8)CPUReadByte(address);
2991 if(dest != base) {
2992 address -= offset;
2993 reg[base].I = address;
2995 clockTicks = 0;
2996 if(dest == 15) {
2997 reg[15].I &= 0xFFFFFFFC;
2998 armNextPC = reg[15].I;
2999 reg[15].I += 4;
3000 ARM_PREFETCH;
3001 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3003 clockTicks += 3 + dataTicksAccess16(address) +
3004 codeTicksAccess32(armNextPC);
3006 break;
3007 case 0x05d:
3008 case 0x07d:
3010 // LDRSB Rd, [Rn], #-offset
3011 if (!busPrefetchCount)
3012 busPrefetch = busPrefetchEnable;
3013 int base = (opcode >> 16) & 0x0F;
3014 int dest = (opcode >> 12) & 0x0F;
3015 u32 address = reg[base].I;
3016 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
3017 reg[dest].I = (s8)CPUReadByte(address);
3018 if(dest != base) {
3019 address -= offset;
3020 reg[base].I = address;
3022 clockTicks = 0;
3023 if(dest == 15) {
3024 reg[15].I &= 0xFFFFFFFC;
3025 armNextPC = reg[15].I;
3026 reg[15].I += 4;
3027 ARM_PREFETCH;
3028 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3030 clockTicks += 3 + dataTicksAccess16(address) +
3031 codeTicksAccess32(armNextPC);
3033 break;
3034 case 0x09d:
3035 case 0x0bd:
3037 // LDRSB Rd, [Rn], Rm
3038 if (!busPrefetchCount)
3039 busPrefetch = busPrefetchEnable;
3040 int base = (opcode >> 16) & 0x0F;
3041 int dest = (opcode >> 12) & 0x0F;
3042 u32 address = reg[base].I;
3043 int offset = reg[opcode & 0x0F].I;
3044 reg[dest].I = (s8)CPUReadByte(address);
3045 if(dest != base) {
3046 address += offset;
3047 reg[base].I = address;
3049 clockTicks = 0;
3050 if(dest == 15) {
3051 reg[15].I &= 0xFFFFFFFC;
3052 armNextPC = reg[15].I;
3053 reg[15].I += 4;
3054 ARM_PREFETCH;
3055 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3057 clockTicks += 3 + dataTicksAccess16(address) +
3058 codeTicksAccess32(armNextPC);
3060 break;
3061 case 0x0dd:
3062 case 0x0fd:
3064 // LDRSB Rd, [Rn], #offset
3065 if (!busPrefetchCount)
3066 busPrefetch = busPrefetchEnable;
3067 int base = (opcode >> 16) & 0x0F;
3068 int dest = (opcode >> 12) & 0x0F;
3069 u32 address = reg[base].I;
3070 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
3071 reg[dest].I = (s8)CPUReadByte(address);
3072 if(dest != base) {
3073 address += offset;
3074 reg[base].I = address;
3076 clockTicks = 0;
3077 if(dest == 15) {
3078 reg[15].I &= 0xFFFFFFFC;
3079 armNextPC = reg[15].I;
3080 reg[15].I += 4;
3081 ARM_PREFETCH;
3082 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3084 clockTicks += 3 + dataTicksAccess16(address) +
3085 codeTicksAccess32(armNextPC);
3087 break;
3088 case 0x11d:
3090 // LDRSB Rd, [Rn, -Rm]
3091 if (!busPrefetchCount)
3092 busPrefetch = busPrefetchEnable;
3093 int base = (opcode >> 16) & 0x0F;
3094 int dest = (opcode >> 12) & 0x0F;
3095 u32 address = reg[base].I - reg[opcode & 0x0F].I;
3096 reg[dest].I = (s8)CPUReadByte(address);
3097 clockTicks = 0;
3098 if(dest == 15) {
3099 reg[15].I &= 0xFFFFFFFC;
3100 armNextPC = reg[15].I;
3101 reg[15].I += 4;
3102 ARM_PREFETCH;
3103 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3105 clockTicks += 3 + dataTicksAccess16(address) +
3106 codeTicksAccess32(armNextPC);
3108 break;
3109 case 0x13d:
3111 // LDRSB Rd, [Rn, -Rm]!
3112 if (!busPrefetchCount)
3113 busPrefetch = busPrefetchEnable;
3114 int base = (opcode >> 16) & 0x0F;
3115 int dest = (opcode >> 12) & 0x0F;
3116 u32 address = reg[base].I - reg[opcode & 0x0F].I;
3117 reg[dest].I = (s8)CPUReadByte(address);
3118 if(dest != base)
3119 reg[base].I = address;
3120 clockTicks = 0;
3121 if(dest == 15) {
3122 reg[15].I &= 0xFFFFFFFC;
3123 armNextPC = reg[15].I;
3124 reg[15].I += 4;
3125 ARM_PREFETCH;
3126 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3128 clockTicks += 3 + dataTicksAccess16(address) +
3129 codeTicksAccess32(armNextPC);
3131 break;
3132 case 0x15d:
3134 // LDRSB Rd, [Rn, -#offset]
3135 if (!busPrefetchCount)
3136 busPrefetch = busPrefetchEnable;
3137 int base = (opcode >> 16) & 0x0F;
3138 int dest = (opcode >> 12) & 0x0F;
3139 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
3140 reg[dest].I = (s8)CPUReadByte(address);
3141 clockTicks = 0;
3142 if(dest == 15) {
3143 reg[15].I &= 0xFFFFFFFC;
3144 armNextPC = reg[15].I;
3145 reg[15].I += 4;
3146 ARM_PREFETCH;
3147 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3149 clockTicks += 3 + dataTicksAccess16(address) +
3150 codeTicksAccess32(armNextPC);
3152 break;
3153 case 0x17d:
3155 // LDRSB Rd, [Rn, -#offset]!
3156 if (!busPrefetchCount)
3157 busPrefetch = busPrefetchEnable;
3158 int base = (opcode >> 16) & 0x0F;
3159 int dest = (opcode >> 12) & 0x0F;
3160 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
3161 reg[dest].I = (s8)CPUReadByte(address);
3162 if(dest != base)
3163 reg[base].I = address;
3164 clockTicks = 0;
3165 if(dest == 15) {
3166 reg[15].I &= 0xFFFFFFFC;
3167 armNextPC = reg[15].I;
3168 reg[15].I += 4;
3169 ARM_PREFETCH;
3170 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3172 clockTicks += 3 + dataTicksAccess16(address) +
3173 codeTicksAccess32(armNextPC);
3175 break;
3176 case 0x19d:
3178 // LDRSB Rd, [Rn, Rm]
3179 if (!busPrefetchCount)
3180 busPrefetch = busPrefetchEnable;
3181 int base = (opcode >> 16) & 0x0F;
3182 int dest = (opcode >> 12) & 0x0F;
3183 u32 address = reg[base].I + reg[opcode & 0x0F].I;
3184 reg[dest].I = (s8)CPUReadByte(address);
3185 clockTicks = 0;
3186 if(dest == 15) {
3187 reg[15].I &= 0xFFFFFFFC;
3188 armNextPC = reg[15].I;
3189 reg[15].I += 4;
3190 ARM_PREFETCH;
3191 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3193 clockTicks += 3 + dataTicksAccess16(address) +
3194 codeTicksAccess32(armNextPC);
3196 break;
3197 case 0x1bd:
3199 // LDRSB Rd, [Rn, Rm]!
3200 if (!busPrefetchCount)
3201 busPrefetch = busPrefetchEnable;
3202 int base = (opcode >> 16) & 0x0F;
3203 int dest = (opcode >> 12) & 0x0F;
3204 u32 address = reg[base].I + reg[opcode & 0x0F].I;
3205 reg[dest].I = (s8)CPUReadByte(address);
3206 if(dest != base)
3207 reg[base].I = address;
3208 clockTicks = 0;
3209 if(dest == 15) {
3210 reg[15].I &= 0xFFFFFFFC;
3211 armNextPC = reg[15].I;
3212 reg[15].I += 4;
3213 ARM_PREFETCH;
3214 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3216 clockTicks += 3 + dataTicksAccess16(address) +
3217 codeTicksAccess32(armNextPC);
3219 break;
3220 case 0x1dd:
3222 // LDRSB Rd, [Rn, #offset]
3223 if (!busPrefetchCount)
3224 busPrefetch = busPrefetchEnable;
3225 int base = (opcode >> 16) & 0x0F;
3226 int dest = (opcode >> 12) & 0x0F;
3227 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
3228 reg[dest].I = (s8)CPUReadByte(address);
3229 clockTicks = 0;
3230 if(dest == 15) {
3231 reg[15].I &= 0xFFFFFFFC;
3232 armNextPC = reg[15].I;
3233 reg[15].I += 4;
3234 ARM_PREFETCH;
3235 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3237 clockTicks += 3 + dataTicksAccess16(address) +
3238 codeTicksAccess32(armNextPC);
3240 break;
3241 case 0x1fd:
3243 // LDRSB Rd, [Rn, #offset]!
3244 if (!busPrefetchCount)
3245 busPrefetch = busPrefetchEnable;
3246 int base = (opcode >> 16) & 0x0F;
3247 int dest = (opcode >> 12) & 0x0F;
3248 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
3249 reg[dest].I = (s8)CPUReadByte(address);
3250 if(dest != base)
3251 reg[base].I = address;
3252 clockTicks = 0;
3253 if(dest == 15) {
3254 reg[15].I &= 0xFFFFFFFC;
3255 armNextPC = reg[15].I;
3256 reg[15].I += 4;
3257 ARM_PREFETCH;
3258 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3260 clockTicks += 3 + dataTicksAccess16(address) +
3261 codeTicksAccess32(armNextPC);
3263 break;
3264 case 0x01f:
3265 case 0x03f:
3267 // LDRSH Rd, [Rn], -Rm
3268 if (!busPrefetchCount)
3269 busPrefetch = busPrefetchEnable;
3270 int base = (opcode >> 16) & 0x0F;
3271 int dest = (opcode >> 12) & 0x0F;
3272 u32 address = reg[base].I;
3273 int offset = reg[opcode & 0x0F].I;
3274 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3275 if(dest != base) {
3276 address -= offset;
3277 reg[base].I = address;
3279 clockTicks = 0;
3280 if(dest == 15) {
3281 reg[15].I &= 0xFFFFFFFC;
3282 armNextPC = reg[15].I;
3283 reg[15].I += 4;
3284 ARM_PREFETCH;
3285 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3287 clockTicks += 3 + dataTicksAccess16(address) +
3288 codeTicksAccess32(armNextPC);
3290 break;
3291 case 0x05f:
3292 case 0x07f:
3294 // LDRSH Rd, [Rn], #-offset
3295 if (!busPrefetchCount)
3296 busPrefetch = busPrefetchEnable;
3297 int base = (opcode >> 16) & 0x0F;
3298 int dest = (opcode >> 12) & 0x0F;
3299 u32 address = reg[base].I;
3300 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
3301 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3302 if(dest != base) {
3303 address -= offset;
3304 reg[base].I = address;
3306 clockTicks = 0;
3307 if(dest == 15) {
3308 reg[15].I &= 0xFFFFFFFC;
3309 armNextPC = reg[15].I;
3310 reg[15].I += 4;
3311 ARM_PREFETCH;
3312 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3314 clockTicks += 3 + dataTicksAccess16(address) +
3315 codeTicksAccess32(armNextPC);
3317 break;
3318 case 0x09f:
3319 case 0x0bf:
3321 // LDRSH Rd, [Rn], Rm
3322 if (!busPrefetchCount)
3323 busPrefetch = busPrefetchEnable;
3324 int base = (opcode >> 16) & 0x0F;
3325 int dest = (opcode >> 12) & 0x0F;
3326 u32 address = reg[base].I;
3327 int offset = reg[opcode & 0x0F].I;
3328 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3329 if(dest != base) {
3330 address += offset;
3331 reg[base].I = address;
3333 clockTicks = 0;
3334 if(dest == 15) {
3335 reg[15].I &= 0xFFFFFFFC;
3336 armNextPC = reg[15].I;
3337 reg[15].I += 4;
3338 ARM_PREFETCH;
3339 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3341 clockTicks += 3 + dataTicksAccess16(address) +
3342 codeTicksAccess32(armNextPC);
3344 break;
3345 case 0x0df:
3346 case 0x0ff:
3348 // LDRSH Rd, [Rn], #offset
3349 if (!busPrefetchCount)
3350 busPrefetch = busPrefetchEnable;
3351 int base = (opcode >> 16) & 0x0F;
3352 int dest = (opcode >> 12) & 0x0F;
3353 u32 address = reg[base].I;
3354 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
3355 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3356 if(dest != base) {
3357 address += offset;
3358 reg[base].I = address;
3360 clockTicks = 0;
3361 if(dest == 15) {
3362 reg[15].I &= 0xFFFFFFFC;
3363 armNextPC = reg[15].I;
3364 reg[15].I += 4;
3365 ARM_PREFETCH;
3366 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3368 clockTicks += 3 + dataTicksAccess16(address) +
3369 codeTicksAccess32(armNextPC);
3371 break;
3372 case 0x11f:
3374 // LDRSH Rd, [Rn, -Rm]
3375 if (!busPrefetchCount)
3376 busPrefetch = busPrefetchEnable;
3377 int base = (opcode >> 16) & 0x0F;
3378 int dest = (opcode >> 12) & 0x0F;
3379 u32 address = reg[base].I - reg[opcode & 0x0F].I;
3380 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3381 clockTicks = 0;
3382 if(dest == 15) {
3383 reg[15].I &= 0xFFFFFFFC;
3384 armNextPC = reg[15].I;
3385 reg[15].I += 4;
3386 ARM_PREFETCH;
3387 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3389 clockTicks += 3 + dataTicksAccess16(address) +
3390 codeTicksAccess32(armNextPC);
3392 break;
3393 case 0x13f:
3395 // LDRSH Rd, [Rn, -Rm]!
3396 if (!busPrefetchCount)
3397 busPrefetch = busPrefetchEnable;
3398 int base = (opcode >> 16) & 0x0F;
3399 int dest = (opcode >> 12) & 0x0F;
3400 u32 address = reg[base].I - reg[opcode & 0x0F].I;
3401 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3402 if(dest != base)
3403 reg[base].I = address;
3404 clockTicks = 0;
3405 if(dest == 15) {
3406 reg[15].I &= 0xFFFFFFFC;
3407 armNextPC = reg[15].I;
3408 reg[15].I += 4;
3409 ARM_PREFETCH;
3410 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3412 clockTicks += 3 + dataTicksAccess16(address) +
3413 codeTicksAccess32(armNextPC);
3415 break;
3416 case 0x15f:
3418 // LDRSH Rd, [Rn, -#offset]
3419 if (!busPrefetchCount)
3420 busPrefetch = busPrefetchEnable;
3421 int base = (opcode >> 16) & 0x0F;
3422 int dest = (opcode >> 12) & 0x0F;
3423 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
3424 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3425 clockTicks = 0;
3426 if(dest == 15) {
3427 reg[15].I &= 0xFFFFFFFC;
3428 armNextPC = reg[15].I;
3429 reg[15].I += 4;
3430 ARM_PREFETCH;
3431 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3433 clockTicks += 3 + dataTicksAccess16(address) +
3434 codeTicksAccess32(armNextPC);
3436 break;
3437 case 0x17f:
3439 // LDRSH Rd, [Rn, -#offset]!
3440 if (!busPrefetchCount)
3441 busPrefetch = busPrefetchEnable;
3442 int base = (opcode >> 16) & 0x0F;
3443 int dest = (opcode >> 12) & 0x0F;
3444 u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
3445 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3446 if(dest != base)
3447 reg[base].I = address;
3448 clockTicks = 0;
3449 if(dest == 15) {
3450 reg[15].I &= 0xFFFFFFFC;
3451 armNextPC = reg[15].I;
3452 reg[15].I += 4;
3453 ARM_PREFETCH;
3454 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3456 clockTicks += 3 + dataTicksAccess16(address) +
3457 codeTicksAccess32(armNextPC);
3459 break;
3460 case 0x19f:
3462 // LDRSH Rd, [Rn, Rm]
3463 if (!busPrefetchCount)
3464 busPrefetch = busPrefetchEnable;
3465 int base = (opcode >> 16) & 0x0F;
3466 int dest = (opcode >> 12) & 0x0F;
3467 u32 address = reg[base].I + reg[opcode & 0x0F].I;
3468 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3469 clockTicks = 0;
3470 if(dest == 15) {
3471 reg[15].I &= 0xFFFFFFFC;
3472 armNextPC = reg[15].I;
3473 reg[15].I += 4;
3474 ARM_PREFETCH;
3475 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3477 clockTicks += 3 + dataTicksAccess16(address) +
3478 codeTicksAccess32(armNextPC);
3480 break;
3481 case 0x1bf:
3483 // LDRSH Rd, [Rn, Rm]!
3484 if (!busPrefetchCount)
3485 busPrefetch = busPrefetchEnable;
3486 int base = (opcode >> 16) & 0x0F;
3487 int dest = (opcode >> 12) & 0x0F;
3488 u32 address = reg[base].I + reg[opcode & 0x0F].I;
3489 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3490 if(dest != base)
3491 reg[base].I = address;
3492 clockTicks = 0;
3493 if(dest == 15) {
3494 reg[15].I &= 0xFFFFFFFC;
3495 armNextPC = reg[15].I;
3496 reg[15].I += 4;
3497 ARM_PREFETCH;
3498 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3500 clockTicks += 3 + dataTicksAccess16(address) +
3501 codeTicksAccess32(armNextPC);
3503 break;
3504 case 0x1df:
3506 // LDRSH Rd, [Rn, #offset]
3507 if (!busPrefetchCount)
3508 busPrefetch = busPrefetchEnable;
3509 int base = (opcode >> 16) & 0x0F;
3510 int dest = (opcode >> 12) & 0x0F;
3511 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
3512 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3513 clockTicks = 0;
3514 if(dest == 15) {
3515 reg[15].I &= 0xFFFFFFFC;
3516 armNextPC = reg[15].I;
3517 reg[15].I += 4;
3518 ARM_PREFETCH;
3519 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3521 clockTicks += 3 + dataTicksAccess16(address) +
3522 codeTicksAccess32(armNextPC);
3524 break;
3525 case 0x1ff:
3527 // LDRSH Rd, [Rn, #offset]!
3528 if (!busPrefetchCount)
3529 busPrefetch = busPrefetchEnable;
3530 int base = (opcode >> 16) & 0x0F;
3531 int dest = (opcode >> 12) & 0x0F;
3532 u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
3533 reg[dest].I = (s16)CPUReadHalfWordSigned(address);
3534 if(dest != base)
3535 reg[base].I = address;
3536 clockTicks = 0;
3537 if(dest == 15) {
3538 reg[15].I &= 0xFFFFFFFC;
3539 armNextPC = reg[15].I;
3540 reg[15].I += 4;
3541 ARM_PREFETCH;
3542 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3544 clockTicks += 3 + dataTicksAccess16(address) +
3545 codeTicksAccess32(armNextPC);
3547 break;
3548 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR, OP_EOR, 0x020);
3549 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030);
3550 case 0x029:
3552 // MLA Rd, Rm, Rs, Rn
3553 clockTicks = 2;
3554 int dest = (opcode >> 16) & 0x0F;
3555 int mult = (opcode & 0x0F);
3556 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3557 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
3558 if((rs & 0xFFFFFF00) == 0)
3559 clockTicks += 0;
3560 else if ((rs & 0xFFFF0000) == 0)
3561 clockTicks += 1;
3562 else if ((rs & 0xFF000000) == 0)
3563 clockTicks += 2;
3564 else
3565 clockTicks += 3;
3566 if (!busPrefetchCount)
3567 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3568 clockTicks += codeTicksAccess32(armNextPC) + 1;
3570 break;
3571 case 0x039:
3573 // MLAS Rd, Rm, Rs, Rn
3574 clockTicks = 2;
3575 int dest = (opcode >> 16) & 0x0F;
3576 int mult = (opcode & 0x0F);
3577 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3578 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
3579 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
3580 Z_FLAG = (reg[dest].I) ? false : true;
3581 if(((s32)rs)<0)
3582 rs = ~rs;
3583 if((rs & 0xFFFFFF00) == 0)
3584 clockTicks += 0;
3585 else if ((rs & 0xFFFF0000) == 0)
3586 clockTicks += 1;
3587 else if ((rs & 0xFF000000) == 0)
3588 clockTicks += 2;
3589 else
3590 clockTicks += 3;
3591 if (!busPrefetchCount)
3592 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3593 clockTicks += codeTicksAccess32(armNextPC) + 1;
3595 break;
3596 ARITHMETIC_DATA_OPCODE(OP_SUB, OP_SUB, 0x040);
3597 ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050);
3598 ARITHMETIC_DATA_OPCODE(OP_RSB, OP_RSB, 0x060);
3599 ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070);
3600 ARITHMETIC_DATA_OPCODE(OP_ADD, OP_ADD, 0x080);
3601 ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090);
3602 case 0x089:
3604 // UMULL RdLo, RdHi, Rn, Rs
3605 clockTicks = 2;
3606 u32 umult = reg[(opcode & 0x0F)].I;
3607 u32 usource = reg[(opcode >> 8) & 0x0F].I;
3608 int destLo = (opcode >> 12) & 0x0F;
3609 int destHi = (opcode >> 16) & 0x0F;
3610 u64 uTemp = ((u64)umult)*((u64)usource);
3611 reg[destLo].I = (u32)uTemp;
3612 reg[destHi].I = (u32)(uTemp >> 32);
3613 if ((usource & 0xFFFFFF00) == 0)
3614 clockTicks += 0;
3615 else if ((usource & 0xFFFF0000) == 0)
3616 clockTicks += 1;
3617 else if ((usource & 0xFF000000) == 0)
3618 clockTicks += 2;
3619 else
3620 clockTicks += 3;
3621 if (!busPrefetchCount)
3622 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3623 clockTicks += codeTicksAccess32(armNextPC) + 1;
3625 break;
3626 case 0x099:
3628 // UMULLS RdLo, RdHi, Rn, Rs
3629 clockTicks = 2;
3630 u32 umult = reg[(opcode & 0x0F)].I;
3631 u32 usource = reg[(opcode >> 8) & 0x0F].I;
3632 int destLo = (opcode >> 12) & 0x0F;
3633 int destHi = (opcode >> 16) & 0x0F;
3634 u64 uTemp = ((u64)umult)*((u64)usource);
3635 reg[destLo].I = (u32)uTemp;
3636 reg[destHi].I = (u32)(uTemp >> 32);
3637 Z_FLAG = (uTemp) ? false : true;
3638 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
3639 if ((usource & 0xFFFFFF00) == 0)
3640 clockTicks += 0;
3641 else if ((usource & 0xFFFF0000) == 0)
3642 clockTicks += 1;
3643 else if ((usource & 0xFF000000) == 0)
3644 clockTicks += 2;
3645 else
3646 clockTicks += 3;
3647 if (!busPrefetchCount)
3648 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3649 clockTicks += codeTicksAccess32(armNextPC) + 1;
3651 break;
3652 ARITHMETIC_DATA_OPCODE(OP_ADC, OP_ADC, 0x0a0);
3653 ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0);
3654 case 0x0a9:
3656 // UMLAL RdLo, RdHi, Rn, Rs
3657 clockTicks = 3;
3658 u32 umult = reg[(opcode & 0x0F)].I;
3659 u32 usource = reg[(opcode >> 8) & 0x0F].I;
3660 int destLo = (opcode >> 12) & 0x0F;
3661 int destHi = (opcode >> 16) & 0x0F;
3662 u64 uTemp = (u64)reg[destHi].I;
3663 uTemp <<= 32;
3664 uTemp |= (u64)reg[destLo].I;
3665 uTemp += ((u64)umult)*((u64)usource);
3666 reg[destLo].I = (u32)uTemp;
3667 reg[destHi].I = (u32)(uTemp >> 32);
3668 if ((usource & 0xFFFFFF00) == 0)
3669 clockTicks += 0;
3670 else if ((usource & 0xFFFF0000) == 0)
3671 clockTicks += 1;
3672 else if ((usource & 0xFF000000) == 0)
3673 clockTicks += 2;
3674 else
3675 clockTicks += 3;
3676 if (!busPrefetchCount)
3677 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3678 clockTicks += codeTicksAccess32(armNextPC) + 1;
3680 break;
3681 case 0x0b9:
3683 // UMLALS RdLo, RdHi, Rn, Rs
3684 clockTicks = 3;
3685 u32 umult = reg[(opcode & 0x0F)].I;
3686 u32 usource = reg[(opcode >> 8) & 0x0F].I;
3687 int destLo = (opcode >> 12) & 0x0F;
3688 int destHi = (opcode >> 16) & 0x0F;
3689 u64 uTemp = (u64)reg[destHi].I;
3690 uTemp <<= 32;
3691 uTemp |= (u64)reg[destLo].I;
3692 uTemp += ((u64)umult)*((u64)usource);
3693 reg[destLo].I = (u32)uTemp;
3694 reg[destHi].I = (u32)(uTemp >> 32);
3695 Z_FLAG = (uTemp) ? false : true;
3696 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
3697 if ((usource & 0xFFFFFF00) == 0)
3698 clockTicks += 0;
3699 else if ((usource & 0xFFFF0000) == 0)
3700 clockTicks += 1;
3701 else if ((usource & 0xFF000000) == 0)
3702 clockTicks += 2;
3703 else
3704 clockTicks += 3;
3705 if (!busPrefetchCount)
3706 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3707 clockTicks += codeTicksAccess32(armNextPC) + 1;
3709 break;
3710 ARITHMETIC_DATA_OPCODE(OP_SBC, OP_SBC, 0x0c0);
3711 ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0);
3712 case 0x0c9:
3714 // SMULL RdLo, RdHi, Rm, Rs
3715 clockTicks = 2;
3716 int destLo = (opcode >> 12) & 0x0F;
3717 int destHi = (opcode >> 16) & 0x0F;
3718 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3719 s64 m = (s32)reg[(opcode & 0x0F)].I;
3720 s64 s = (s32)rs;
3721 s64 sTemp = m*s;
3722 reg[destLo].I = (u32)sTemp;
3723 reg[destHi].I = (u32)(sTemp >> 32);
3724 if(((s32)rs) < 0)
3725 rs = ~rs;
3726 if((rs & 0xFFFFFF00) == 0)
3727 clockTicks += 0;
3728 else if((rs & 0xFFFF0000) == 0)
3729 clockTicks += 1;
3730 else if((rs & 0xFF000000) == 0)
3731 clockTicks += 2;
3732 else
3733 clockTicks += 3;
3734 if (!busPrefetchCount)
3735 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3736 clockTicks += codeTicksAccess32(armNextPC) + 1;
3738 break;
3739 case 0x0d9:
3741 // SMULLS RdLo, RdHi, Rm, Rs
3742 clockTicks = 2;
3743 int destLo = (opcode >> 12) & 0x0F;
3744 int destHi = (opcode >> 16) & 0x0F;
3745 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3746 s64 m = (s32)reg[(opcode & 0x0F)].I;
3747 s64 s = (s32)rs;
3748 s64 sTemp = m*s;
3749 reg[destLo].I = (u32)sTemp;
3750 reg[destHi].I = (u32)(sTemp >> 32);
3751 Z_FLAG = (sTemp) ? false : true;
3752 N_FLAG = (sTemp < 0) ? true : false;
3753 if(((s32)rs) < 0)
3754 rs = ~rs;
3755 if((rs & 0xFFFFFF00) == 0)
3756 clockTicks += 0;
3757 else if((rs & 0xFFFF0000) == 0)
3758 clockTicks += 1;
3759 else if((rs & 0xFF000000) == 0)
3760 clockTicks += 2;
3761 else
3762 clockTicks += 3;
3763 if (!busPrefetchCount)
3764 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3765 clockTicks += codeTicksAccess32(armNextPC) + 1;
3767 break;
3768 ARITHMETIC_DATA_OPCODE(OP_RSC, OP_RSC, 0x0e0);
3769 ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0);
3770 case 0x0e9:
3772 // SMLAL RdLo, RdHi, Rm, Rs
3773 clockTicks = codeTicksAccess32(armNextPC) + 4;
3774 int destLo = (opcode >> 12) & 0x0F;
3775 int destHi = (opcode >> 16) & 0x0F;
3776 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3777 s64 m = (s32)reg[(opcode & 0x0F)].I;
3778 s64 s = (s32)rs;
3779 s64 sTemp = (u64)reg[destHi].I;
3780 sTemp <<= 32;
3781 sTemp |= (u64)reg[destLo].I;
3782 sTemp += m*s;
3783 reg[destLo].I = (u32)sTemp;
3784 reg[destHi].I = (u32)(sTemp >> 32);
3785 if(((s32)rs) < 0)
3786 rs = ~rs;
3787 if((rs & 0xFFFFFF00) == 0)
3788 clockTicks += 0;
3789 else if((rs & 0xFFFF0000) == 0)
3790 clockTicks += 1;
3791 else if((rs & 0xFF000000) == 0)
3792 clockTicks += 2;
3793 else
3794 clockTicks += 3;
3795 if (!busPrefetchCount)
3796 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3798 break;
3799 case 0x0f9:
3801 // SMLALS RdLo, RdHi, Rm, Rs
3802 clockTicks = codeTicksAccess32(armNextPC) + 4;
3803 int destLo = (opcode >> 12) & 0x0F;
3804 int destHi = (opcode >> 16) & 0x0F;
3805 u32 rs = reg[(opcode >> 8) & 0x0F].I;
3806 s64 m = (s32)reg[(opcode & 0x0F)].I;
3807 s64 s = (s32)rs;
3808 s64 sTemp = (u64)reg[destHi].I;
3809 sTemp <<= 32;
3810 sTemp |= (u64)reg[destLo].I;
3811 sTemp += m*s;
3812 reg[destLo].I = (u32)sTemp;
3813 reg[destHi].I = (u32)(sTemp >> 32);
3814 Z_FLAG = (sTemp) ? false : true;
3815 N_FLAG = (sTemp < 0) ? true : false;
3816 if(((s32)rs) < 0)
3817 rs = ~rs;
3818 if((rs & 0xFFFFFF00) == 0)
3819 clockTicks += 0;
3820 else if((rs & 0xFFFF0000) == 0)
3821 clockTicks += 1;
3822 else if((rs & 0xFF000000) == 0)
3823 clockTicks += 2;
3824 else
3825 clockTicks += 3;
3826 if (!busPrefetchCount)
3827 busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
3829 break;
3830 LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110);
3831 case 0x100:
3832 // MRS Rd, CPSR
3833 // TODO: check if right instruction....
3834 CPUUpdateCPSR();
3835 reg[(opcode >> 12) & 0x0F].I = reg[16].I;
3836 break;
3837 case 0x109:
3839 // SWP Rd, Rm, [Rn]
3840 u32 address = reg[(opcode >> 16) & 15].I;
3841 u32 temp = CPUReadMemory(address);
3842 CPUWriteMemory(address, reg[opcode&15].I);
3843 reg[(opcode >> 12) & 15].I = temp;
3844 clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) +
3845 codeTicksAccess32(armNextPC);
3847 break;
3848 LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130);
3849 case 0x120:
3851 // MSR CPSR_fields, Rm
3852 CPUUpdateCPSR();
3853 u32 value = reg[opcode & 15].I;
3854 u32 newValue = reg[16].I;
3855 if(armMode > 0x10) {
3856 if(opcode & 0x00010000)
3857 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
3858 if(opcode & 0x00020000)
3859 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
3860 if(opcode & 0x00040000)
3861 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
3863 if(opcode & 0x00080000)
3864 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
3865 newValue |= 0x10;
3866 CPUSwitchMode(newValue & 0x1f, false);
3867 reg[16].I = newValue;
3868 CPUUpdateFlags();
3869 if(!armState) { // this should not be allowed, but it seems to work
3870 THUMB_PREFETCH;
3871 reg[15].I = armNextPC + 2;
3874 break;
3875 case 0x121:
3877 // BX Rm
3878 // TODO: check if right instruction...
3879 int base = opcode & 0x0F;
3880 busPrefetchCount=0;
3881 armState = reg[base].I & 1 ? false : true;
3882 if(armState) {
3883 reg[15].I = reg[base].I & 0xFFFFFFFC;
3884 armNextPC = reg[15].I;
3885 reg[15].I += 4;
3886 ARM_PREFETCH;
3887 clockTicks = codeTicksAccessSeq32(armNextPC) +
3888 codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3;
3889 } else {
3890 reg[15].I = reg[base].I & 0xFFFFFFFE;
3891 armNextPC = reg[15].I;
3892 reg[15].I += 2;
3893 THUMB_PREFETCH;
3894 clockTicks = codeTicksAccessSeq16(armNextPC) +
3895 codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
3898 break;
3899 ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150);
3900 case 0x140:
3901 // MRS Rd, SPSR
3902 // TODO: check if right instruction...
3903 reg[(opcode >> 12) & 0x0F].I = reg[17].I;
3904 break;
3905 case 0x149:
3907 // SWPB Rd, Rm, [Rn]
3908 u32 address = reg[(opcode >> 16) & 15].I;
3909 u32 temp = CPUReadByte(address);
3910 CPUWriteByte(address, reg[opcode&15].B.B0);
3911 reg[(opcode>>12)&15].I = temp;
3912 clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) +
3913 codeTicksAccess32(armNextPC);
3915 break;
3916 ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170);
3917 case 0x160:
3919 // MSR SPSR_fields, Rm
3920 u32 value = reg[opcode & 15].I;
3921 if(armMode > 0x10 && armMode < 0x1f) {
3922 if(opcode & 0x00010000)
3923 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
3924 if(opcode & 0x00020000)
3925 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
3926 if(opcode & 0x00040000)
3927 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
3928 if(opcode & 0x00080000)
3929 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
3932 break;
3933 LOGICAL_DATA_OPCODE (OP_ORR, OP_ORR, 0x180);
3934 LOGICAL_DATA_OPCODE (OP_ORRS, OP_ORR, 0x190);
3935 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV, OP_MOV, 0x1a0);
3936 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0);
3937 LOGICAL_DATA_OPCODE (OP_BIC, OP_BIC, 0x1c0);
3938 LOGICAL_DATA_OPCODE (OP_BICS, OP_BIC, 0x1d0);
3939 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN, OP_MVN, 0x1e0);
3940 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0);
3941 #ifdef BKPT_SUPPORT
3942 case 0x127:
3943 case 0x7ff: // for GDB support
3944 extern void (*dbgSignal)(int,int);
3945 reg[15].I -= 4;
3946 armNextPC -= 4;
3947 dbgSignal(5, (opcode & 0x0f)|((opcode>>4) & 0xfff0));
3948 return;
3949 #endif
3950 case 0x320:
3951 case 0x321:
3952 case 0x322:
3953 case 0x323:
3954 case 0x324:
3955 case 0x325:
3956 case 0x326:
3957 case 0x327:
3958 case 0x328:
3959 case 0x329:
3960 case 0x32a:
3961 case 0x32b:
3962 case 0x32c:
3963 case 0x32d:
3964 case 0x32e:
3965 case 0x32f:
3967 // MSR CPSR_fields, #
3968 CPUUpdateCPSR();
3969 u32 value = opcode & 0xFF;
3970 int shift = (opcode & 0xF00) >> 7;
3971 if(shift) {
3972 ROR_IMM_MSR;
3974 u32 newValue = reg[16].I;
3975 if(armMode > 0x10) {
3976 if(opcode & 0x00010000)
3977 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
3978 if(opcode & 0x00020000)
3979 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
3980 if(opcode & 0x00040000)
3981 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
3983 if(opcode & 0x00080000)
3984 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
3986 newValue |= 0x10;
3988 CPUSwitchMode(newValue & 0x1f, false);
3989 reg[16].I = newValue;
3990 CPUUpdateFlags();
3991 if(!armState) { // this should not be allowed, but it seems to work
3992 THUMB_PREFETCH;
3993 reg[15].I = armNextPC + 2;
3996 break;
3997 case 0x360:
3998 case 0x361:
3999 case 0x362:
4000 case 0x363:
4001 case 0x364:
4002 case 0x365:
4003 case 0x366:
4004 case 0x367:
4005 case 0x368:
4006 case 0x369:
4007 case 0x36a:
4008 case 0x36b:
4009 case 0x36c:
4010 case 0x36d:
4011 case 0x36e:
4012 case 0x36f:
4014 // MSR SPSR_fields, #
4015 if(armMode > 0x10 && armMode < 0x1f) {
4016 u32 value = opcode & 0xFF;
4017 int shift = (opcode & 0xF00) >> 7;
4018 if(shift) {
4019 ROR_IMM_MSR;
4021 if(opcode & 0x00010000)
4022 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
4023 if(opcode & 0x00020000)
4024 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
4025 if(opcode & 0x00040000)
4026 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
4027 if(opcode & 0x00080000)
4028 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
4031 break;
4032 CASE_16(0x400)
4033 // T versions shouldn't be different on GBA
4034 CASE_16(0x420)
4036 // STR Rd, [Rn], -#
4037 if (!busPrefetchCount)
4038 busPrefetch = busPrefetchEnable;
4039 int offset = opcode & 0xFFF;
4040 int dest = (opcode >> 12) & 15;
4041 int base = (opcode >> 16) & 15;
4042 u32 address = reg[base].I;
4043 CPUWriteMemory(address, reg[dest].I);
4044 reg[base].I = address - offset;
4045 clockTicks = 2 + dataTicksAccess32(address) +
4046 codeTicksAccess32(armNextPC);
4048 break;
4049 CASE_16(0x480)
4050 // T versions shouldn't be different on GBA
4051 CASE_16(0x4a0)
4053 // STR Rd, [Rn], #
4054 if (!busPrefetchCount)
4055 busPrefetch = busPrefetchEnable;
4056 int offset = opcode & 0xFFF;
4057 int dest = (opcode >> 12) & 15;
4058 int base = (opcode >> 16) & 15;
4059 u32 address = reg[base].I;
4060 CPUWriteMemory(address, reg[dest].I);
4061 reg[base].I = address + offset;
4062 clockTicks = 2 + dataTicksAccess32(address) +
4063 codeTicksAccess32(armNextPC);
4065 break;
4066 CASE_16(0x500)
4068 // STR Rd, [Rn, -#]
4069 if (!busPrefetchCount)
4070 busPrefetch = busPrefetchEnable;
4071 int offset = opcode & 0xFFF;
4072 int dest = (opcode >> 12) & 15;
4073 int base = (opcode >> 16) & 15;
4074 u32 address = reg[base].I - offset;
4075 CPUWriteMemory(address, reg[dest].I);
4076 clockTicks = 2 + dataTicksAccess32(address) +
4077 codeTicksAccess32(armNextPC);
4079 break;
4080 CASE_16(0x520)
4082 // STR Rd, [Rn, -#]!
4083 if (!busPrefetchCount)
4084 busPrefetch = busPrefetchEnable;
4085 int offset = opcode & 0xFFF;
4086 int dest = (opcode >> 12) & 15;
4087 int base = (opcode >> 16) & 15;
4088 u32 address = reg[base].I - offset;
4089 reg[base].I = address;
4090 CPUWriteMemory(address, reg[dest].I);
4091 clockTicks = 2 + dataTicksAccess32(address) +
4092 codeTicksAccess32(armNextPC);
4094 break;
4095 CASE_16(0x580)
4097 // STR Rd, [Rn, #]
4098 if (!busPrefetchCount)
4099 busPrefetch = busPrefetchEnable;
4100 int offset = opcode & 0xFFF;
4101 int dest = (opcode >> 12) & 15;
4102 int base = (opcode >> 16) & 15;
4103 u32 address = reg[base].I + offset;
4104 CPUWriteMemory(address, reg[dest].I);
4105 clockTicks = 2 + dataTicksAccess32(address) +
4106 codeTicksAccess32(armNextPC);
4108 break;
4109 CASE_16(0x5a0)
4111 // STR Rd, [Rn, #]!
4112 if (!busPrefetchCount)
4113 busPrefetch = busPrefetchEnable;
4114 int offset = opcode & 0xFFF;
4115 int dest = (opcode >> 12) & 15;
4116 int base = (opcode >> 16) & 15;
4117 u32 address = reg[base].I + offset;
4118 reg[base].I = address;
4119 CPUWriteMemory(address, reg[dest].I);
4120 clockTicks = 2 + dataTicksAccess32(address) +
4121 codeTicksAccess32(armNextPC);
4123 break;
4124 CASE_16(0x410)
4126 // LDR Rd, [Rn], -#
4127 if (!busPrefetchCount)
4128 busPrefetch = busPrefetchEnable;
4129 int offset = opcode & 0xFFF;
4130 int dest = (opcode >> 12) & 15;
4131 int base = (opcode >> 16) & 15;
4132 u32 address = reg[base].I;
4133 reg[dest].I = CPUReadMemory(address);
4134 if(dest != base)
4135 reg[base].I -= offset;
4136 clockTicks = 0;
4137 if(dest == 15) {
4138 reg[15].I &= 0xFFFFFFFC;
4139 armNextPC = reg[15].I;
4140 reg[15].I += 4;
4141 ARM_PREFETCH;
4142 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4144 clockTicks += 3 + dataTicksAccess32(address) +
4145 codeTicksAccess32(armNextPC);
4147 break;
4148 CASE_16(0x430)
4150 // LDRT Rd, [Rn], -#
4151 if (!busPrefetchCount)
4152 busPrefetch = busPrefetchEnable;
4153 int offset = opcode & 0xFFF;
4154 int dest = (opcode >> 12) & 15;
4155 int base = (opcode >> 16) & 15;
4156 u32 address = reg[base].I;
4157 reg[dest].I = CPUReadMemory(address);
4158 if(dest != base)
4159 reg[base].I -= offset;
4160 clockTicks = 0;
4161 if(dest == 15) {
4162 reg[15].I &= 0xFFFFFFFC;
4163 armNextPC = reg[15].I;
4164 reg[15].I += 4;
4165 ARM_PREFETCH;
4166 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4168 clockTicks += 3 + dataTicksAccess32(address) +
4169 codeTicksAccess32(armNextPC);
4171 break;
4172 CASE_16(0x490)
4174 // LDR Rd, [Rn], #
4175 if (!busPrefetchCount)
4176 busPrefetch = busPrefetchEnable;
4177 int offset = opcode & 0xFFF;
4178 int dest = (opcode >> 12) & 15;
4179 int base = (opcode >> 16) & 15;
4180 u32 address = reg[base].I;
4181 reg[dest].I = CPUReadMemory(address);
4182 if(dest != base)
4183 reg[base].I += offset;
4184 clockTicks = 0;
4185 if(dest == 15) {
4186 reg[15].I &= 0xFFFFFFFC;
4187 armNextPC = reg[15].I;
4188 reg[15].I += 4;
4189 ARM_PREFETCH;
4190 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4192 clockTicks += 3 + dataTicksAccess32(address) +
4193 codeTicksAccess32(armNextPC);
4195 break;
4196 CASE_16(0x4b0)
4198 // LDRT Rd, [Rn], #
4199 if (!busPrefetchCount)
4200 busPrefetch = busPrefetchEnable;
4201 int offset = opcode & 0xFFF;
4202 int dest = (opcode >> 12) & 15;
4203 int base = (opcode >> 16) & 15;
4204 u32 address = reg[base].I;
4205 reg[dest].I = CPUReadMemory(address);
4206 if(dest != base)
4207 reg[base].I += offset;
4208 clockTicks = 0;
4209 if(dest == 15) {
4210 reg[15].I &= 0xFFFFFFFC;
4211 armNextPC = reg[15].I;
4212 reg[15].I += 4;
4213 ARM_PREFETCH;
4214 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4216 clockTicks += 3 + dataTicksAccess32(address) +
4217 codeTicksAccess32(armNextPC);
4219 break;
4220 CASE_16(0x510)
4222 // LDR Rd, [Rn, -#]
4223 if (!busPrefetchCount)
4224 busPrefetch = busPrefetchEnable;
4225 int offset = opcode & 0xFFF;
4226 int dest = (opcode >> 12) & 15;
4227 int base = (opcode >> 16) & 15;
4228 u32 address = reg[base].I - offset;
4229 reg[dest].I = CPUReadMemory(address);
4230 clockTicks = 0;
4231 if(dest == 15) {
4232 reg[15].I &= 0xFFFFFFFC;
4233 armNextPC = reg[15].I;
4234 reg[15].I += 4;
4235 ARM_PREFETCH;
4236 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4238 clockTicks += 3 + dataTicksAccess32(address) +
4239 codeTicksAccess32(armNextPC);
4241 break;
4242 CASE_16(0x530)
4244 // LDR Rd, [Rn, -#]!
4245 if (!busPrefetchCount)
4246 busPrefetch = busPrefetchEnable;
4247 int offset = opcode & 0xFFF;
4248 int dest = (opcode >> 12) & 15;
4249 int base = (opcode >> 16) & 15;
4250 u32 address = reg[base].I - offset;
4251 reg[dest].I = CPUReadMemory(address);
4252 if(dest != base)
4253 reg[base].I = address;
4254 clockTicks = 0;
4255 if(dest == 15) {
4256 reg[15].I &= 0xFFFFFFFC;
4257 armNextPC = reg[15].I;
4258 reg[15].I += 4;
4259 ARM_PREFETCH;
4260 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4262 clockTicks += 3 + dataTicksAccess32(address) +
4263 codeTicksAccess32(armNextPC);
4265 break;
4266 CASE_16(0x590)
4268 // LDR Rd, [Rn, #]
4269 if (!busPrefetchCount)
4270 busPrefetch = busPrefetchEnable;
4271 int offset = opcode & 0xFFF;
4272 int dest = (opcode >> 12) & 15;
4273 int base = (opcode >> 16) & 15;
4274 u32 address = reg[base].I + offset;
4275 reg[dest].I = CPUReadMemory(address);
4276 clockTicks = 0;
4277 if(dest == 15) {
4278 reg[15].I &= 0xFFFFFFFC;
4279 armNextPC = reg[15].I;
4280 reg[15].I += 4;
4281 ARM_PREFETCH;
4282 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4284 clockTicks += 3 + dataTicksAccess32(address) +
4285 codeTicksAccess32(armNextPC);
4287 break;
4288 CASE_16(0x5b0)
4290 // LDR Rd, [Rn, #]!
4291 if (!busPrefetchCount)
4292 busPrefetch = busPrefetchEnable;
4293 int offset = opcode & 0xFFF;
4294 int dest = (opcode >> 12) & 15;
4295 int base = (opcode >> 16) & 15;
4296 u32 address = reg[base].I + offset;
4297 reg[dest].I = CPUReadMemory(address);
4298 if(dest != base)
4299 reg[base].I = address;
4300 clockTicks = 0;
4301 if(dest == 15) {
4302 reg[15].I &= 0xFFFFFFFC;
4303 armNextPC = reg[15].I;
4304 reg[15].I += 4;
4305 ARM_PREFETCH;
4306 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4308 clockTicks += 3 + dataTicksAccess32(address) +
4309 codeTicksAccess32(armNextPC);
4311 break;
4312 CASE_16(0x440)
4313 // T versions shouldn't be different on GBA
4314 CASE_16(0x460)
4316 // STRB Rd, [Rn], -#
4317 if (!busPrefetchCount)
4318 busPrefetch = busPrefetchEnable;
4319 int offset = opcode & 0xFFF;
4320 int dest = (opcode >> 12) & 15;
4321 int base = (opcode >> 16) & 15;
4322 u32 address = reg[base].I;
4323 CPUWriteByte(address, reg[dest].B.B0);
4324 reg[base].I = address - offset;
4325 clockTicks = 2 + dataTicksAccess16(address) +
4326 codeTicksAccess32(armNextPC);
4328 break;
4329 CASE_16(0x4c0)
4330 // T versions shouldn't be different on GBA
4331 CASE_16(0x4e0)
4333 // STRB Rd, [Rn], #
4334 if (!busPrefetchCount)
4335 busPrefetch = busPrefetchEnable;
4336 int offset = opcode & 0xFFF;
4337 int dest = (opcode >> 12) & 15;
4338 int base = (opcode >> 16) & 15;
4339 u32 address = reg[base].I;
4340 CPUWriteByte(address, reg[dest].B.B0);
4341 reg[base].I = address + offset;
4342 clockTicks = 2 + dataTicksAccess16(address) +
4343 codeTicksAccess32(armNextPC);
4345 break;
4346 CASE_16(0x540)
4348 // STRB Rd, [Rn, -#]
4349 if (!busPrefetchCount)
4350 busPrefetch = busPrefetchEnable;
4351 int offset = opcode & 0xFFF;
4352 int dest = (opcode >> 12) & 15;
4353 int base = (opcode >> 16) & 15;
4354 u32 address = reg[base].I - offset;
4355 CPUWriteByte(address, reg[dest].B.B0);
4356 clockTicks = 2 + dataTicksAccess16(address) +
4357 codeTicksAccess32(armNextPC);
4359 break;
4360 CASE_16(0x560)
4362 // STRB Rd, [Rn, -#]!
4363 if (!busPrefetchCount)
4364 busPrefetch = busPrefetchEnable;
4365 int offset = opcode & 0xFFF;
4366 int dest = (opcode >> 12) & 15;
4367 int base = (opcode >> 16) & 15;
4368 u32 address = reg[base].I - offset;
4369 reg[base].I = address;
4370 CPUWriteByte(address, reg[dest].B.B0);
4371 clockTicks = 2 + dataTicksAccess16(address) +
4372 codeTicksAccess32(armNextPC);
4374 break;
4375 CASE_16(0x5c0)
4377 // STRB Rd, [Rn, #]
4378 if (!busPrefetchCount)
4379 busPrefetch = busPrefetchEnable;
4380 int offset = opcode & 0xFFF;
4381 int dest = (opcode >> 12) & 15;
4382 int base = (opcode >> 16) & 15;
4383 u32 address = reg[base].I + offset;
4384 CPUWriteByte(address, reg[dest].B.B0);
4385 clockTicks = 2 + dataTicksAccess16(address) +
4386 codeTicksAccess32(armNextPC);
4388 break;
4389 CASE_16(0x5e0)
4391 // STRB Rd, [Rn, #]!
4392 if (!busPrefetchCount)
4393 busPrefetch = busPrefetchEnable;
4394 int offset = opcode & 0xFFF;
4395 int dest = (opcode >> 12) & 15;
4396 int base = (opcode >> 16) & 15;
4397 u32 address = reg[base].I + offset;
4398 reg[base].I = address;
4399 CPUWriteByte(address, reg[dest].I);
4400 clockTicks = 2 + dataTicksAccess16(address) +
4401 codeTicksAccess32(armNextPC);
4403 break;
4404 CASE_16(0x450)
4405 // T versions shouldn't be different
4406 CASE_16(0x470)
4408 // LDRB Rd, [Rn], -#
4409 if (!busPrefetchCount)
4410 busPrefetch = busPrefetchEnable;
4411 int offset = opcode & 0xFFF;
4412 int dest = (opcode >> 12) & 15;
4413 int base = (opcode >> 16) & 15;
4414 u32 address = reg[base].I;
4415 reg[dest].I = CPUReadByte(address);
4416 if(dest != base)
4417 reg[base].I -= offset;
4418 clockTicks = 0;
4419 if(dest == 15) {
4420 reg[15].I &= 0xFFFFFFFC;
4421 armNextPC = reg[15].I;
4422 reg[15].I += 4;
4423 ARM_PREFETCH;
4424 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4426 clockTicks += 3 + dataTicksAccess16(address) +
4427 codeTicksAccess32(armNextPC);
4429 break;
4430 CASE_16(0x4d0)
4431 CASE_16(0x4f0) // T versions should not be different
4433 // LDRB Rd, [Rn], #
4434 if (!busPrefetchCount)
4435 busPrefetch = busPrefetchEnable;
4436 int offset = opcode & 0xFFF;
4437 int dest = (opcode >> 12) & 15;
4438 int base = (opcode >> 16) & 15;
4439 u32 address = reg[base].I;
4440 reg[dest].I = CPUReadByte(address);
4441 if(dest != base)
4442 reg[base].I += offset;
4443 clockTicks = 0;
4444 if(dest == 15) {
4445 reg[15].I &= 0xFFFFFFFC;
4446 armNextPC = reg[15].I;
4447 reg[15].I += 4;
4448 ARM_PREFETCH;
4449 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4451 clockTicks += 3 + dataTicksAccess16(address) +
4452 codeTicksAccess32(armNextPC);
4454 break;
4455 CASE_16(0x550)
4457 // LDRB Rd, [Rn, -#]
4458 if (!busPrefetchCount)
4459 busPrefetch = busPrefetchEnable;
4460 int offset = opcode & 0xFFF;
4461 int dest = (opcode >> 12) & 15;
4462 int base = (opcode >> 16) & 15;
4463 u32 address = reg[base].I - offset;
4464 reg[dest].I = CPUReadByte(address);
4465 clockTicks = 0;
4466 if(dest == 15) {
4467 reg[15].I &= 0xFFFFFFFC;
4468 armNextPC = reg[15].I;
4469 reg[15].I += 4;
4470 ARM_PREFETCH;
4471 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4473 clockTicks += 3 + dataTicksAccess16(address) +
4474 codeTicksAccess32(armNextPC);
4476 break;
4477 CASE_16(0x570)
4479 // LDRB Rd, [Rn, -#]!
4480 if (!busPrefetchCount)
4481 busPrefetch = busPrefetchEnable;
4482 int offset = opcode & 0xFFF;
4483 int dest = (opcode >> 12) & 15;
4484 int base = (opcode >> 16) & 15;
4485 u32 address = reg[base].I - offset;
4486 reg[dest].I = CPUReadByte(address);
4487 if(dest != base)
4488 reg[base].I = address;
4489 clockTicks = 0;
4490 if(dest == 15) {
4491 reg[15].I &= 0xFFFFFFFC;
4492 armNextPC = reg[15].I;
4493 reg[15].I += 4;
4494 ARM_PREFETCH;
4495 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4497 clockTicks += 3 + dataTicksAccess16(address) +
4498 codeTicksAccess32(armNextPC);
4500 break;
4501 CASE_16(0x5d0)
4503 // LDRB Rd, [Rn, #]
4504 if (!busPrefetchCount)
4505 busPrefetch = busPrefetchEnable;
4506 int offset = opcode & 0xFFF;
4507 int dest = (opcode >> 12) & 15;
4508 int base = (opcode >> 16) & 15;
4509 u32 address = reg[base].I + offset;
4510 reg[dest].I = CPUReadByte(address);
4511 clockTicks = 0;
4512 if(dest == 15) {
4513 reg[15].I &= 0xFFFFFFFC;
4514 armNextPC = reg[15].I;
4515 reg[15].I += 4;
4516 ARM_PREFETCH;
4517 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4519 clockTicks += 3 + dataTicksAccess16(address) +
4520 codeTicksAccess32(armNextPC);
4522 break;
4523 CASE_16(0x5f0)
4525 // LDRB Rd, [Rn, #]!
4526 if (!busPrefetchCount)
4527 busPrefetch = busPrefetchEnable;
4528 int offset = opcode & 0xFFF;
4529 int dest = (opcode >> 12) & 15;
4530 int base = (opcode >> 16) & 15;
4531 u32 address = reg[base].I + offset;
4532 reg[dest].I = CPUReadByte(address);
4533 if(dest != base)
4534 reg[base].I = address;
4535 clockTicks = 0;
4536 if(dest == 15) {
4537 reg[15].I &= 0xFFFFFFFC;
4538 armNextPC = reg[15].I;
4539 reg[15].I += 4;
4540 ARM_PREFETCH;
4541 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4543 clockTicks += 3 + dataTicksAccess16(address) +
4544 codeTicksAccess32(armNextPC);
4546 break;
4547 case 0x600:
4548 case 0x608:
4549 // T versions are the same
4550 case 0x620:
4551 case 0x628:
4553 // STR Rd, [Rn], -Rm, LSL #
4554 if (!busPrefetchCount)
4555 busPrefetch = busPrefetchEnable;
4556 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4557 int dest = (opcode >> 12) & 15;
4558 int base = (opcode >> 16) & 15;
4559 u32 address = reg[base].I;
4560 CPUWriteMemory(address, reg[dest].I);
4561 reg[base].I = address - offset;
4562 clockTicks = 2 + dataTicksAccess32(address) +
4563 codeTicksAccess32(armNextPC);
4565 break;
4566 case 0x602:
4567 case 0x60a:
4568 // T versions are the same
4569 case 0x622:
4570 case 0x62a:
4572 // STR Rd, [Rn], -Rm, LSR #
4573 if (!busPrefetchCount)
4574 busPrefetch = busPrefetchEnable;
4575 int shift = (opcode >> 7) & 31;
4576 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4577 int dest = (opcode >> 12) & 15;
4578 int base = (opcode >> 16) & 15;
4579 u32 address = reg[base].I;
4580 CPUWriteMemory(address, reg[dest].I);
4581 reg[base].I = address - offset;
4582 clockTicks = 2 + dataTicksAccess32(address) +
4583 codeTicksAccess32(armNextPC);
4585 break;
4586 case 0x604:
4587 case 0x60c:
4588 // T versions are the same
4589 case 0x624:
4590 case 0x62c:
4592 // STR Rd, [Rn], -Rm, ASR #
4593 if (!busPrefetchCount)
4594 busPrefetch = busPrefetchEnable;
4595 int shift = (opcode >> 7) & 31;
4596 int offset;
4597 if(shift)
4598 offset = (int)((s32)reg[opcode & 15].I >> shift);
4599 else if(reg[opcode & 15].I & 0x80000000)
4600 offset = 0xFFFFFFFF;
4601 else
4602 offset = 0;
4603 int dest = (opcode >> 12) & 15;
4604 int base = (opcode >> 16) & 15;
4605 u32 address = reg[base].I;
4606 CPUWriteMemory(address, reg[dest].I);
4607 reg[base].I = address - offset;
4608 clockTicks = 2 + dataTicksAccess32(address) +
4609 codeTicksAccess32(armNextPC);
4611 break;
4612 case 0x606:
4613 case 0x60e:
4614 // T versions are the same
4615 case 0x626:
4616 case 0x62e:
4618 // STR Rd, [Rn], -Rm, ROR #
4619 if (!busPrefetchCount)
4620 busPrefetch = busPrefetchEnable;
4621 int shift = (opcode >> 7) & 31;
4622 u32 value = reg[opcode & 15].I;
4623 if(shift) {
4624 ROR_VALUE;
4625 } else {
4626 RCR_VALUE;
4628 int dest = (opcode >> 12) & 15;
4629 int base = (opcode >> 16) & 15;
4630 u32 address = reg[base].I;
4631 CPUWriteMemory(address, reg[dest].I);
4632 reg[base].I = address - value;
4633 clockTicks = 2 + dataTicksAccess32(address) +
4634 codeTicksAccess32(armNextPC);
4636 break;
4637 case 0x680:
4638 case 0x688:
4639 // T versions are the same
4640 case 0x6a0:
4641 case 0x6a8:
4643 // STR Rd, [Rn], Rm, LSL #
4644 if (!busPrefetchCount)
4645 busPrefetch = busPrefetchEnable;
4646 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4647 int dest = (opcode >> 12) & 15;
4648 int base = (opcode >> 16) & 15;
4649 u32 address = reg[base].I;
4650 CPUWriteMemory(address, reg[dest].I);
4651 reg[base].I = address + offset;
4652 clockTicks = 2 + dataTicksAccess32(address) +
4653 codeTicksAccess32(armNextPC);
4655 break;
4656 case 0x682:
4657 case 0x68a:
4658 // T versions are the same
4659 case 0x6a2:
4660 case 0x6aa:
4662 // STR Rd, [Rn], Rm, LSR #
4663 if (!busPrefetchCount)
4664 busPrefetch = busPrefetchEnable;
4665 int shift = (opcode >> 7) & 31;
4666 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4667 int dest = (opcode >> 12) & 15;
4668 int base = (opcode >> 16) & 15;
4669 u32 address = reg[base].I;
4670 CPUWriteMemory(address, reg[dest].I);
4671 reg[base].I = address + offset;
4672 clockTicks = 2 + dataTicksAccess32(address) +
4673 codeTicksAccess32(armNextPC);
4675 break;
4676 case 0x684:
4677 case 0x68c:
4678 // T versions are the same
4679 case 0x6a4:
4680 case 0x6ac:
4682 // STR Rd, [Rn], Rm, ASR #
4683 if (!busPrefetchCount)
4684 busPrefetch = busPrefetchEnable;
4685 int shift = (opcode >> 7) & 31;
4686 int offset;
4687 if(shift)
4688 offset = (int)((s32)reg[opcode & 15].I >> shift);
4689 else if(reg[opcode & 15].I & 0x80000000)
4690 offset = 0xFFFFFFFF;
4691 else
4692 offset = 0;
4693 int dest = (opcode >> 12) & 15;
4694 int base = (opcode >> 16) & 15;
4695 u32 address = reg[base].I;
4696 CPUWriteMemory(address, reg[dest].I);
4697 reg[base].I = address + offset;
4698 clockTicks = 2 + dataTicksAccess32(address) +
4699 codeTicksAccess32(armNextPC);
4701 break;
4702 case 0x686:
4703 case 0x68e:
4704 // T versions are the same
4705 case 0x6a6:
4706 case 0x6ae:
4708 // STR Rd, [Rn], Rm, ROR #
4709 if (!busPrefetchCount)
4710 busPrefetch = busPrefetchEnable;
4711 int shift = (opcode >> 7) & 31;
4712 u32 value = reg[opcode & 15].I;
4713 if(shift) {
4714 ROR_VALUE;
4715 } else {
4716 RCR_VALUE;
4718 int dest = (opcode >> 12) & 15;
4719 int base = (opcode >> 16) & 15;
4720 u32 address = reg[base].I;
4721 CPUWriteMemory(address, reg[dest].I);
4722 reg[base].I = address + value;
4723 clockTicks = 2 + dataTicksAccess32(address) +
4724 codeTicksAccess32(armNextPC);
4726 break;
4727 case 0x700:
4728 case 0x708:
4730 // STR Rd, [Rn, -Rm, LSL #]
4731 if (!busPrefetchCount)
4732 busPrefetch = busPrefetchEnable;
4733 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4734 int dest = (opcode >> 12) & 15;
4735 int base = (opcode >> 16) & 15;
4736 u32 address = reg[base].I - offset;
4737 CPUWriteMemory(address, reg[dest].I);
4738 clockTicks = 2 + dataTicksAccess32(address) +
4739 codeTicksAccess32(armNextPC);
4741 break;
4742 case 0x702:
4743 case 0x70a:
4745 // STR Rd, [Rn, -Rm, LSR #]
4746 if (!busPrefetchCount)
4747 busPrefetch = busPrefetchEnable;
4748 int shift = (opcode >> 7) & 31;
4749 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4750 int dest = (opcode >> 12) & 15;
4751 int base = (opcode >> 16) & 15;
4752 u32 address = reg[base].I - offset;
4753 CPUWriteMemory(address, reg[dest].I);
4754 clockTicks = 2 + dataTicksAccess32(address) +
4755 codeTicksAccess32(armNextPC);
4757 break;
4758 case 0x704:
4759 case 0x70c:
4761 // STR Rd, [Rn, -Rm, ASR #]
4762 if (!busPrefetchCount)
4763 busPrefetch = busPrefetchEnable;
4764 int shift = (opcode >> 7) & 31;
4765 int offset;
4766 if(shift)
4767 offset = (int)((s32)reg[opcode & 15].I >> shift);
4768 else if(reg[opcode & 15].I & 0x80000000)
4769 offset = 0xFFFFFFFF;
4770 else
4771 offset = 0;
4772 int dest = (opcode >> 12) & 15;
4773 int base = (opcode >> 16) & 15;
4774 u32 address = reg[base].I - offset;
4775 CPUWriteMemory(address, reg[dest].I);
4776 clockTicks = 2 + dataTicksAccess32(address) +
4777 codeTicksAccess32(armNextPC);
4779 break;
4780 case 0x706:
4781 case 0x70e:
4783 // STR Rd, [Rn, -Rm, ROR #]
4784 if (!busPrefetchCount)
4785 busPrefetch = busPrefetchEnable;
4786 int shift = (opcode >> 7) & 31;
4787 u32 value = reg[opcode & 15].I;
4788 if(shift) {
4789 ROR_VALUE;
4790 } else {
4791 RCR_VALUE;
4793 int dest = (opcode >> 12) & 15;
4794 int base = (opcode >> 16) & 15;
4795 u32 address = reg[base].I - value;
4796 CPUWriteMemory(address, reg[dest].I);
4797 clockTicks = 2 + dataTicksAccess32(address) +
4798 codeTicksAccess32(armNextPC);
4800 break;
4801 case 0x720:
4802 case 0x728:
4804 // STR Rd, [Rn, -Rm, LSL #]!
4805 if (!busPrefetchCount)
4806 busPrefetch = busPrefetchEnable;
4807 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4808 int dest = (opcode >> 12) & 15;
4809 int base = (opcode >> 16) & 15;
4810 u32 address = reg[base].I - offset;
4811 reg[base].I = address;
4812 CPUWriteMemory(address, reg[dest].I);
4813 clockTicks = 2 + dataTicksAccess32(address) +
4814 codeTicksAccess32(armNextPC);
4816 break;
4817 case 0x722:
4818 case 0x72a:
4820 // STR Rd, [Rn, -Rm, LSR #]!
4821 if (!busPrefetchCount)
4822 busPrefetch = busPrefetchEnable;
4823 int shift = (opcode >> 7) & 31;
4824 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4825 int dest = (opcode >> 12) & 15;
4826 int base = (opcode >> 16) & 15;
4827 u32 address = reg[base].I - offset;
4828 reg[base].I = address;
4829 CPUWriteMemory(address, reg[dest].I);
4830 clockTicks = 2 + dataTicksAccess32(address) +
4831 codeTicksAccess32(armNextPC);
4833 break;
4834 case 0x724:
4835 case 0x72c:
4837 // STR Rd, [Rn, -Rm, ASR #]!
4838 if (!busPrefetchCount)
4839 busPrefetch = busPrefetchEnable;
4840 int shift = (opcode >> 7) & 31;
4841 int offset;
4842 if(shift)
4843 offset = (int)((s32)reg[opcode & 15].I >> shift);
4844 else if(reg[opcode & 15].I & 0x80000000)
4845 offset = 0xFFFFFFFF;
4846 else
4847 offset = 0;
4848 int dest = (opcode >> 12) & 15;
4849 int base = (opcode >> 16) & 15;
4850 u32 address = reg[base].I - offset;
4851 reg[base].I = address;
4852 CPUWriteMemory(address, reg[dest].I);
4853 clockTicks = 2 + dataTicksAccess32(address) +
4854 codeTicksAccess32(armNextPC);
4856 break;
4857 case 0x726:
4858 case 0x72e:
4860 // STR Rd, [Rn, -Rm, ROR #]!
4861 if (!busPrefetchCount)
4862 busPrefetch = busPrefetchEnable;
4863 int shift = (opcode >> 7) & 31;
4864 u32 value = reg[opcode & 15].I;
4865 if(shift) {
4866 ROR_VALUE;
4867 } else {
4868 RCR_VALUE;
4870 int dest = (opcode >> 12) & 15;
4871 int base = (opcode >> 16) & 15;
4872 u32 address = reg[base].I - value;
4873 reg[base].I = address;
4874 CPUWriteMemory(address, reg[dest].I);
4875 clockTicks = 2 + dataTicksAccess32(address) +
4876 codeTicksAccess32(armNextPC);
4878 break;
4879 case 0x780:
4880 case 0x788:
4882 // STR Rd, [Rn, Rm, LSL #]
4883 if (!busPrefetchCount)
4884 busPrefetch = busPrefetchEnable;
4885 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4886 int dest = (opcode >> 12) & 15;
4887 int base = (opcode >> 16) & 15;
4888 u32 address = reg[base].I + offset;
4889 CPUWriteMemory(address, reg[dest].I);
4890 clockTicks = 2 + dataTicksAccess32(address) +
4891 codeTicksAccess32(armNextPC);
4893 break;
4894 case 0x782:
4895 case 0x78a:
4897 // STR Rd, [Rn, Rm, LSR #]
4898 if (!busPrefetchCount)
4899 busPrefetch = busPrefetchEnable;
4900 int shift = (opcode >> 7) & 31;
4901 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4902 int dest = (opcode >> 12) & 15;
4903 int base = (opcode >> 16) & 15;
4904 u32 address = reg[base].I + offset;
4905 CPUWriteMemory(address, reg[dest].I);
4906 clockTicks = 2 + dataTicksAccess32(address) +
4907 codeTicksAccess32(armNextPC);
4909 break;
4910 case 0x784:
4911 case 0x78c:
4913 // STR Rd, [Rn, Rm, ASR #]
4914 if (!busPrefetchCount)
4915 busPrefetch = busPrefetchEnable;
4916 int shift = (opcode >> 7) & 31;
4917 int offset;
4918 if(shift)
4919 offset = (int)((s32)reg[opcode & 15].I >> shift);
4920 else if(reg[opcode & 15].I & 0x80000000)
4921 offset = 0xFFFFFFFF;
4922 else
4923 offset = 0;
4924 int dest = (opcode >> 12) & 15;
4925 int base = (opcode >> 16) & 15;
4926 u32 address = reg[base].I + offset;
4927 CPUWriteMemory(address, reg[dest].I);
4928 clockTicks = 2 + dataTicksAccess32(address) +
4929 codeTicksAccess32(armNextPC);
4931 break;
4932 case 0x786:
4933 case 0x78e:
4935 // STR Rd, [Rn, Rm, ROR #]
4936 if (!busPrefetchCount)
4937 busPrefetch = busPrefetchEnable;
4938 int shift = (opcode >> 7) & 31;
4939 u32 value = reg[opcode & 15].I;
4940 if(shift) {
4941 ROR_VALUE;
4942 } else {
4943 RCR_VALUE;
4945 int dest = (opcode >> 12) & 15;
4946 int base = (opcode >> 16) & 15;
4947 u32 address = reg[base].I + value;
4948 CPUWriteMemory(address, reg[dest].I);
4949 clockTicks = 2 + dataTicksAccess32(address) +
4950 codeTicksAccess32(armNextPC);
4952 break;
4953 case 0x7a0:
4954 case 0x7a8:
4956 // STR Rd, [Rn, Rm, LSL #]!
4957 if (!busPrefetchCount)
4958 busPrefetch = busPrefetchEnable;
4959 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4960 int dest = (opcode >> 12) & 15;
4961 int base = (opcode >> 16) & 15;
4962 u32 address = reg[base].I + offset;
4963 reg[base].I = address;
4964 CPUWriteMemory(address, reg[dest].I);
4965 clockTicks = 2 + dataTicksAccess32(address) +
4966 codeTicksAccess32(armNextPC);
4968 break;
4969 case 0x7a2:
4970 case 0x7aa:
4972 // STR Rd, [Rn, Rm, LSR #]!
4973 if (!busPrefetchCount)
4974 busPrefetch = busPrefetchEnable;
4975 int shift = (opcode >> 7) & 31;
4976 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4977 int dest = (opcode >> 12) & 15;
4978 int base = (opcode >> 16) & 15;
4979 u32 address = reg[base].I + offset;
4980 reg[base].I = address;
4981 CPUWriteMemory(address, reg[dest].I);
4982 clockTicks = 2 + dataTicksAccess32(address) +
4983 codeTicksAccess32(armNextPC);
4985 break;
4986 case 0x7a4:
4987 case 0x7ac:
4989 // STR Rd, [Rn, Rm, ASR #]!
4990 if (!busPrefetchCount)
4991 busPrefetch = busPrefetchEnable;
4992 int shift = (opcode >> 7) & 31;
4993 int offset;
4994 if(shift)
4995 offset = (int)((s32)reg[opcode & 15].I >> shift);
4996 else if(reg[opcode & 15].I & 0x80000000)
4997 offset = 0xFFFFFFFF;
4998 else
4999 offset = 0;
5000 int dest = (opcode >> 12) & 15;
5001 int base = (opcode >> 16) & 15;
5002 u32 address = reg[base].I + offset;
5003 reg[base].I = address;
5004 CPUWriteMemory(address, reg[dest].I);
5005 clockTicks = 2 + dataTicksAccess32(address) +
5006 codeTicksAccess32(armNextPC);
5008 break;
5009 case 0x7a6:
5010 case 0x7ae:
5012 // STR Rd, [Rn, Rm, ROR #]!
5013 if (!busPrefetchCount)
5014 busPrefetch = busPrefetchEnable;
5015 int shift = (opcode >> 7) & 31;
5016 u32 value = reg[opcode & 15].I;
5017 if(shift) {
5018 ROR_VALUE;
5019 } else {
5020 RCR_VALUE;
5022 int dest = (opcode >> 12) & 15;
5023 int base = (opcode >> 16) & 15;
5024 u32 address = reg[base].I + value;
5025 reg[base].I = address;
5026 CPUWriteMemory(address, reg[dest].I);
5027 clockTicks = 2 + dataTicksAccess32(address) +
5028 codeTicksAccess32(armNextPC);
5030 break;
5031 case 0x610:
5032 case 0x618:
5033 // T versions are the same
5034 case 0x630:
5035 case 0x638:
5037 // LDR Rd, [Rn], -Rm, LSL #
5038 if (!busPrefetchCount)
5039 busPrefetch = busPrefetchEnable;
5040 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5041 int dest = (opcode >> 12) & 15;
5042 int base = (opcode >> 16) & 15;
5043 u32 address = reg[base].I;
5044 reg[dest].I = CPUReadMemory(address);
5045 if(dest != base)
5046 reg[base].I = address - offset;
5047 clockTicks = 0;
5048 if(dest == 15) {
5049 reg[15].I &= 0xFFFFFFFC;
5050 armNextPC = reg[15].I;
5051 reg[15].I += 4;
5052 ARM_PREFETCH;
5053 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5055 clockTicks += 3 + dataTicksAccess32(address) +
5056 codeTicksAccess32(armNextPC);
5058 break;
5059 case 0x612:
5060 case 0x61a:
5061 // T versions are the same
5062 case 0x632:
5063 case 0x63a:
5065 // LDR Rd, [Rn], -Rm, LSR #
5066 if (!busPrefetchCount)
5067 busPrefetch = busPrefetchEnable;
5068 int shift = (opcode >> 7) & 31;
5069 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5070 int dest = (opcode >> 12) & 15;
5071 int base = (opcode >> 16) & 15;
5072 u32 address = reg[base].I;
5073 reg[dest].I = CPUReadMemory(address);
5074 if(dest != base)
5075 reg[base].I = address - offset;
5076 clockTicks = 0;
5077 if(dest == 15) {
5078 reg[15].I &= 0xFFFFFFFC;
5079 armNextPC = reg[15].I;
5080 reg[15].I += 4;
5081 ARM_PREFETCH;
5082 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5084 clockTicks += 3 + dataTicksAccess32(address) +
5085 codeTicksAccess32(armNextPC);
5087 break;
5088 case 0x614:
5089 case 0x61c:
5090 // T versions are the same
5091 case 0x634:
5092 case 0x63c:
5094 // LDR Rd, [Rn], -Rm, ASR #
5095 if (!busPrefetchCount)
5096 busPrefetch = busPrefetchEnable;
5097 int shift = (opcode >> 7) & 31;
5098 int offset;
5099 if(shift)
5100 offset = (int)((s32)reg[opcode & 15].I >> shift);
5101 else if(reg[opcode & 15].I & 0x80000000)
5102 offset = 0xFFFFFFFF;
5103 else
5104 offset = 0;
5105 int dest = (opcode >> 12) & 15;
5106 int base = (opcode >> 16) & 15;
5107 u32 address = reg[base].I;
5108 reg[dest].I = CPUReadMemory(address);
5109 if(dest != base)
5110 reg[base].I = address - offset;
5111 clockTicks = 0;
5112 if(dest == 15) {
5113 reg[15].I &= 0xFFFFFFFC;
5114 armNextPC = reg[15].I;
5115 reg[15].I += 4;
5116 ARM_PREFETCH;
5117 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5119 clockTicks += 3 + dataTicksAccess32(address) +
5120 codeTicksAccess32(armNextPC);
5122 break;
5123 case 0x616:
5124 case 0x61e:
5125 // T versions are the same
5126 case 0x636:
5127 case 0x63e:
5129 // LDR Rd, [Rn], -Rm, ROR #
5130 if (!busPrefetchCount)
5131 busPrefetch = busPrefetchEnable;
5132 int shift = (opcode >> 7) & 31;
5133 u32 value = reg[opcode & 15].I;
5134 if(shift) {
5135 ROR_VALUE;
5136 } else {
5137 RCR_VALUE;
5139 int dest = (opcode >> 12) & 15;
5140 int base = (opcode >> 16) & 15;
5141 u32 address = reg[base].I;
5142 reg[dest].I = CPUReadMemory(address);
5143 if(dest != base)
5144 reg[base].I = address - value;
5145 clockTicks = 0;
5146 if(dest == 15) {
5147 reg[15].I &= 0xFFFFFFFC;
5148 armNextPC = reg[15].I;
5149 reg[15].I += 4;
5150 ARM_PREFETCH;
5151 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5153 clockTicks += 3 + dataTicksAccess32(address) +
5154 codeTicksAccess32(armNextPC);
5156 break;
5157 case 0x690:
5158 case 0x698:
5159 // T versions are the same
5160 case 0x6b0:
5161 case 0x6b8:
5163 // LDR Rd, [Rn], Rm, LSL #
5164 if (!busPrefetchCount)
5165 busPrefetch = busPrefetchEnable;
5166 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5167 int dest = (opcode >> 12) & 15;
5168 int base = (opcode >> 16) & 15;
5169 u32 address = reg[base].I;
5170 reg[dest].I = CPUReadMemory(address);
5171 if(dest != base)
5172 reg[base].I = address + offset;
5173 clockTicks = 0;
5174 if(dest == 15) {
5175 reg[15].I &= 0xFFFFFFFC;
5176 armNextPC = reg[15].I;
5177 reg[15].I += 4;
5178 ARM_PREFETCH;
5179 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5181 clockTicks += 3 + dataTicksAccess32(address) +
5182 codeTicksAccess32(armNextPC);
5184 break;
5185 case 0x692:
5186 case 0x69a:
5187 // T versions are the same
5188 case 0x6b2:
5189 case 0x6ba:
5191 // LDR Rd, [Rn], Rm, LSR #
5192 if (!busPrefetchCount)
5193 busPrefetch = busPrefetchEnable;
5194 int shift = (opcode >> 7) & 31;
5195 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5196 int dest = (opcode >> 12) & 15;
5197 int base = (opcode >> 16) & 15;
5198 u32 address = reg[base].I;
5199 reg[dest].I = CPUReadMemory(address);
5200 if(dest != base)
5201 reg[base].I = address + offset;
5202 clockTicks = 0;
5203 if(dest == 15) {
5204 reg[15].I &= 0xFFFFFFFC;
5205 armNextPC = reg[15].I;
5206 reg[15].I += 4;
5207 ARM_PREFETCH;
5208 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5210 clockTicks += 3 + dataTicksAccess32(address) +
5211 codeTicksAccess32(armNextPC);
5213 break;
5214 case 0x694:
5215 case 0x69c:
5216 // T versions are the same
5217 case 0x6b4:
5218 case 0x6bc:
5220 // LDR Rd, [Rn], Rm, ASR #
5221 if (!busPrefetchCount)
5222 busPrefetch = busPrefetchEnable;
5223 int shift = (opcode >> 7) & 31;
5224 int offset;
5225 if(shift)
5226 offset = (int)((s32)reg[opcode & 15].I >> shift);
5227 else if(reg[opcode & 15].I & 0x80000000)
5228 offset = 0xFFFFFFFF;
5229 else
5230 offset = 0;
5231 int dest = (opcode >> 12) & 15;
5232 int base = (opcode >> 16) & 15;
5233 u32 address = reg[base].I;
5234 reg[dest].I = CPUReadMemory(address);
5235 if(dest != base)
5236 reg[base].I = address + offset;
5237 clockTicks = 0;
5238 if(dest == 15) {
5239 reg[15].I &= 0xFFFFFFFC;
5240 armNextPC = reg[15].I;
5241 reg[15].I += 4;
5242 ARM_PREFETCH;
5243 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5245 clockTicks += 3 + dataTicksAccess32(address) +
5246 codeTicksAccess32(armNextPC);
5248 break;
5249 case 0x696:
5250 case 0x69e:
5251 // T versions are the same
5252 case 0x6b6:
5253 case 0x6be:
5255 // LDR Rd, [Rn], Rm, ROR #
5256 if (!busPrefetchCount)
5257 busPrefetch = busPrefetchEnable;
5258 int shift = (opcode >> 7) & 31;
5259 u32 value = reg[opcode & 15].I;
5260 if(shift) {
5261 ROR_VALUE;
5262 } else {
5263 RCR_VALUE;
5265 int dest = (opcode >> 12) & 15;
5266 int base = (opcode >> 16) & 15;
5267 u32 address = reg[base].I;
5268 reg[dest].I = CPUReadMemory(address);
5269 if(dest != base)
5270 reg[base].I = address + value;
5271 clockTicks = 0;
5272 if(dest == 15) {
5273 reg[15].I &= 0xFFFFFFFC;
5274 armNextPC = reg[15].I;
5275 reg[15].I += 4;
5276 ARM_PREFETCH;
5277 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5279 clockTicks += 3 + dataTicksAccess32(address) +
5280 codeTicksAccess32(armNextPC);
5282 break;
5283 case 0x710:
5284 case 0x718:
5286 // LDR Rd, [Rn, -Rm, LSL #]
5287 if (!busPrefetchCount)
5288 busPrefetch = busPrefetchEnable;
5289 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5290 int dest = (opcode >> 12) & 15;
5291 int base = (opcode >> 16) & 15;
5292 u32 address = reg[base].I - offset;
5293 reg[dest].I = CPUReadMemory(address);
5294 clockTicks = 0;
5295 if(dest == 15) {
5296 reg[15].I &= 0xFFFFFFFC;
5297 armNextPC = reg[15].I;
5298 reg[15].I += 4;
5299 ARM_PREFETCH;
5300 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5302 clockTicks += 3 + dataTicksAccess32(address) +
5303 codeTicksAccess32(armNextPC);
5305 break;
5306 case 0x712:
5307 case 0x71a:
5309 // LDR Rd, [Rn, -Rm, LSR #]
5310 if (!busPrefetchCount)
5311 busPrefetch = busPrefetchEnable;
5312 int shift = (opcode >> 7) & 31;
5313 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5314 int dest = (opcode >> 12) & 15;
5315 int base = (opcode >> 16) & 15;
5316 u32 address = reg[base].I - offset;
5317 reg[dest].I = CPUReadMemory(address);
5318 clockTicks = 0;
5319 if(dest == 15) {
5320 reg[15].I &= 0xFFFFFFFC;
5321 armNextPC = reg[15].I;
5322 reg[15].I += 4;
5323 ARM_PREFETCH;
5324 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5326 clockTicks += 3 + dataTicksAccess32(address) +
5327 codeTicksAccess32(armNextPC);
5329 break;
5330 case 0x714:
5331 case 0x71c:
5333 // LDR Rd, [Rn, -Rm, ASR #]
5334 if (!busPrefetchCount)
5335 busPrefetch = busPrefetchEnable;
5336 int shift = (opcode >> 7) & 31;
5337 int offset;
5338 if(shift)
5339 offset = (int)((s32)reg[opcode & 15].I >> shift);
5340 else if(reg[opcode & 15].I & 0x80000000)
5341 offset = 0xFFFFFFFF;
5342 else
5343 offset = 0;
5344 int dest = (opcode >> 12) & 15;
5345 int base = (opcode >> 16) & 15;
5346 u32 address = reg[base].I - offset;
5347 reg[dest].I = CPUReadMemory(address);
5348 clockTicks = 0;
5349 if(dest == 15) {
5350 reg[15].I &= 0xFFFFFFFC;
5351 armNextPC = reg[15].I;
5352 reg[15].I += 4;
5353 ARM_PREFETCH;
5354 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5356 clockTicks += 3 + dataTicksAccess32(address) +
5357 codeTicksAccess32(armNextPC);
5359 break;
5360 case 0x716:
5361 case 0x71e:
5363 // LDR Rd, [Rn, -Rm, ROR #]
5364 if (!busPrefetchCount)
5365 busPrefetch = busPrefetchEnable;
5366 int shift = (opcode >> 7) & 31;
5367 u32 value = reg[opcode & 15].I;
5368 if(shift) {
5369 ROR_VALUE;
5370 } else {
5371 RCR_VALUE;
5373 int dest = (opcode >> 12) & 15;
5374 int base = (opcode >> 16) & 15;
5375 u32 address = reg[base].I - value;
5376 reg[dest].I = CPUReadMemory(address);
5377 clockTicks = 0;
5378 if(dest == 15) {
5379 reg[15].I &= 0xFFFFFFFC;
5380 armNextPC = reg[15].I;
5381 reg[15].I += 4;
5382 ARM_PREFETCH;
5383 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5385 clockTicks += 3 + dataTicksAccess32(address) +
5386 codeTicksAccess32(armNextPC);
5388 break;
5389 case 0x730:
5390 case 0x738:
5392 // LDR Rd, [Rn, -Rm, LSL #]!
5393 if (!busPrefetchCount)
5394 busPrefetch = busPrefetchEnable;
5395 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5396 int dest = (opcode >> 12) & 15;
5397 int base = (opcode >> 16) & 15;
5398 u32 address = reg[base].I - offset;
5399 reg[dest].I = CPUReadMemory(address);
5400 if(dest != base)
5401 reg[base].I = address;
5402 clockTicks = 0;
5403 if(dest == 15) {
5404 reg[15].I &= 0xFFFFFFFC;
5405 armNextPC = reg[15].I;
5406 reg[15].I += 4;
5407 ARM_PREFETCH;
5408 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5410 clockTicks += 3 + dataTicksAccess32(address) +
5411 codeTicksAccess32(armNextPC);
5413 break;
5414 case 0x732:
5415 case 0x73a:
5417 // LDR Rd, [Rn, -Rm, LSR #]!
5418 if (!busPrefetchCount)
5419 busPrefetch = busPrefetchEnable;
5420 int shift = (opcode >> 7) & 31;
5421 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5422 int dest = (opcode >> 12) & 15;
5423 int base = (opcode >> 16) & 15;
5424 u32 address = reg[base].I - offset;
5425 reg[dest].I = CPUReadMemory(address);
5426 if(dest != base)
5427 reg[base].I = address;
5428 clockTicks = 0;
5429 if(dest == 15) {
5430 reg[15].I &= 0xFFFFFFFC;
5431 armNextPC = reg[15].I;
5432 reg[15].I += 4;
5433 ARM_PREFETCH;
5434 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5436 clockTicks += 3 + dataTicksAccess32(address) +
5437 codeTicksAccess32(armNextPC);
5439 break;
5440 case 0x734:
5441 case 0x73c:
5443 // LDR Rd, [Rn, -Rm, ASR #]!
5444 if (!busPrefetchCount)
5445 busPrefetch = busPrefetchEnable;
5446 int shift = (opcode >> 7) & 31;
5447 int offset;
5448 if(shift)
5449 offset = (int)((s32)reg[opcode & 15].I >> shift);
5450 else if(reg[opcode & 15].I & 0x80000000)
5451 offset = 0xFFFFFFFF;
5452 else
5453 offset = 0;
5454 int dest = (opcode >> 12) & 15;
5455 int base = (opcode >> 16) & 15;
5456 u32 address = reg[base].I - offset;
5457 reg[dest].I = CPUReadMemory(address);
5458 if(dest != base)
5459 reg[base].I = address;
5460 clockTicks = 0;
5461 if(dest == 15) {
5462 reg[15].I &= 0xFFFFFFFC;
5463 armNextPC = reg[15].I;
5464 reg[15].I += 4;
5465 ARM_PREFETCH;
5466 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5468 clockTicks += 3 + dataTicksAccess32(address) +
5469 codeTicksAccess32(armNextPC);
5471 break;
5472 case 0x736:
5473 case 0x73e:
5475 // LDR Rd, [Rn, -Rm, ROR #]!
5476 if (!busPrefetchCount)
5477 busPrefetch = busPrefetchEnable;
5478 int shift = (opcode >> 7) & 31;
5479 u32 value = reg[opcode & 15].I;
5480 if(shift) {
5481 ROR_VALUE;
5482 } else {
5483 RCR_VALUE;
5485 int dest = (opcode >> 12) & 15;
5486 int base = (opcode >> 16) & 15;
5487 u32 address = reg[base].I - value;
5488 reg[dest].I = CPUReadMemory(address);
5489 if(dest != base)
5490 reg[base].I = address;
5491 clockTicks = 0;
5492 if(dest == 15) {
5493 reg[15].I &= 0xFFFFFFFC;
5494 armNextPC = reg[15].I;
5495 reg[15].I += 4;
5496 ARM_PREFETCH;
5497 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5499 clockTicks += 3 + dataTicksAccess32(address) +
5500 codeTicksAccess32(armNextPC);
5502 break;
5503 case 0x790:
5504 case 0x798:
5506 // LDR Rd, [Rn, Rm, LSL #]
5507 if (!busPrefetchCount)
5508 busPrefetch = busPrefetchEnable;
5509 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5510 int dest = (opcode >> 12) & 15;
5511 int base = (opcode >> 16) & 15;
5512 u32 address = reg[base].I + offset;
5513 reg[dest].I = CPUReadMemory(address);
5514 clockTicks = 0;
5515 if(dest == 15) {
5516 reg[15].I &= 0xFFFFFFFC;
5517 armNextPC = reg[15].I;
5518 reg[15].I += 4;
5519 ARM_PREFETCH;
5520 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5522 clockTicks += 3 + dataTicksAccess32(address) +
5523 codeTicksAccess32(armNextPC);
5525 break;
5526 case 0x792:
5527 case 0x79a:
5529 // LDR Rd, [Rn, Rm, LSR #]
5530 if (!busPrefetchCount)
5531 busPrefetch = busPrefetchEnable;
5532 int shift = (opcode >> 7) & 31;
5533 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5534 int dest = (opcode >> 12) & 15;
5535 int base = (opcode >> 16) & 15;
5536 u32 address = reg[base].I + offset;
5537 reg[dest].I = CPUReadMemory(address);
5538 clockTicks = 0;
5539 if(dest == 15) {
5540 reg[15].I &= 0xFFFFFFFC;
5541 armNextPC = reg[15].I;
5542 reg[15].I += 4;
5543 ARM_PREFETCH;
5544 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5546 clockTicks += 3 + dataTicksAccess32(address) +
5547 codeTicksAccess32(armNextPC);
5549 break;
5550 case 0x794:
5551 case 0x79c:
5553 // LDR Rd, [Rn, Rm, ASR #]
5554 if (!busPrefetchCount)
5555 busPrefetch = busPrefetchEnable;
5556 int shift = (opcode >> 7) & 31;
5557 int offset;
5558 if(shift)
5559 offset = (int)((s32)reg[opcode & 15].I >> shift);
5560 else if(reg[opcode & 15].I & 0x80000000)
5561 offset = 0xFFFFFFFF;
5562 else
5563 offset = 0;
5564 int dest = (opcode >> 12) & 15;
5565 int base = (opcode >> 16) & 15;
5566 u32 address = reg[base].I + offset;
5567 reg[dest].I = CPUReadMemory(address);
5568 clockTicks = 0;
5569 if(dest == 15) {
5570 reg[15].I &= 0xFFFFFFFC;
5571 armNextPC = reg[15].I;
5572 reg[15].I += 4;
5573 ARM_PREFETCH;
5574 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5576 clockTicks += 3 + dataTicksAccess32(address) +
5577 codeTicksAccess32(armNextPC);
5579 break;
5580 case 0x796:
5581 case 0x79e:
5583 // LDR Rd, [Rn, Rm, ROR #]
5584 if (!busPrefetchCount)
5585 busPrefetch = busPrefetchEnable;
5586 int shift = (opcode >> 7) & 31;
5587 u32 value = reg[opcode & 15].I;
5588 if(shift) {
5589 ROR_VALUE;
5590 } else {
5591 RCR_VALUE;
5593 int dest = (opcode >> 12) & 15;
5594 int base = (opcode >> 16) & 15;
5595 u32 address = reg[base].I + value;
5596 reg[dest].I = CPUReadMemory(address);
5597 clockTicks = 0;
5598 if(dest == 15) {
5599 reg[15].I &= 0xFFFFFFFC;
5600 armNextPC = reg[15].I;
5601 reg[15].I += 4;
5602 ARM_PREFETCH;
5603 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5605 clockTicks += 3 + dataTicksAccess32(address) +
5606 codeTicksAccess32(armNextPC);
5608 break;
5609 case 0x7b0:
5610 case 0x7b8:
5612 // LDR Rd, [Rn, Rm, LSL #]!
5613 if (!busPrefetchCount)
5614 busPrefetch = busPrefetchEnable;
5615 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5616 int dest = (opcode >> 12) & 15;
5617 int base = (opcode >> 16) & 15;
5618 u32 address = reg[base].I + offset;
5619 reg[dest].I = CPUReadMemory(address);
5620 if(dest != base)
5621 reg[base].I = address;
5622 clockTicks = 0;
5623 if(dest == 15) {
5624 reg[15].I &= 0xFFFFFFFC;
5625 armNextPC = reg[15].I;
5626 reg[15].I += 4;
5627 ARM_PREFETCH;
5628 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5630 clockTicks += 3 + dataTicksAccess32(address) +
5631 codeTicksAccess32(armNextPC);
5633 break;
5634 case 0x7b2:
5635 case 0x7ba:
5637 // LDR Rd, [Rn, Rm, LSR #]!
5638 if (!busPrefetchCount)
5639 busPrefetch = busPrefetchEnable;
5640 int shift = (opcode >> 7) & 31;
5641 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5642 int dest = (opcode >> 12) & 15;
5643 int base = (opcode >> 16) & 15;
5644 u32 address = reg[base].I + offset;
5645 reg[dest].I = CPUReadMemory(address);
5646 if(dest != base)
5647 reg[base].I = address;
5648 clockTicks = 0;
5649 if(dest == 15) {
5650 reg[15].I &= 0xFFFFFFFC;
5651 armNextPC = reg[15].I;
5652 reg[15].I += 4;
5653 ARM_PREFETCH;
5654 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5656 clockTicks += 3 + dataTicksAccess32(address) +
5657 codeTicksAccess32(armNextPC);
5659 break;
5660 case 0x7b4:
5661 case 0x7bc:
5663 // LDR Rd, [Rn, Rm, ASR #]!
5664 if (!busPrefetchCount)
5665 busPrefetch = busPrefetchEnable;
5666 int shift = (opcode >> 7) & 31;
5667 int offset;
5668 if(shift)
5669 offset = (int)((s32)reg[opcode & 15].I >> shift);
5670 else if(reg[opcode & 15].I & 0x80000000)
5671 offset = 0xFFFFFFFF;
5672 else
5673 offset = 0;
5674 int dest = (opcode >> 12) & 15;
5675 int base = (opcode >> 16) & 15;
5676 u32 address = reg[base].I + offset;
5677 reg[dest].I = CPUReadMemory(address);
5678 if(dest != base)
5679 reg[base].I = address;
5680 clockTicks = 0;
5681 if(dest == 15) {
5682 reg[15].I &= 0xFFFFFFFC;
5683 armNextPC = reg[15].I;
5684 reg[15].I += 4;
5685 ARM_PREFETCH;
5686 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5688 clockTicks += 3 + dataTicksAccess32(address) +
5689 codeTicksAccess32(armNextPC);
5691 break;
5692 case 0x7b6:
5693 case 0x7be:
5695 // LDR Rd, [Rn, Rm, ROR #]!
5696 if (!busPrefetchCount)
5697 busPrefetch = busPrefetchEnable;
5698 int shift = (opcode >> 7) & 31;
5699 u32 value = reg[opcode & 15].I;
5700 if(shift) {
5701 ROR_VALUE;
5702 } else {
5703 RCR_VALUE;
5705 int dest = (opcode >> 12) & 15;
5706 int base = (opcode >> 16) & 15;
5707 u32 address = reg[base].I + value;
5708 reg[dest].I = CPUReadMemory(address);
5709 if(dest != base)
5710 reg[base].I = address;
5711 clockTicks = 0;
5712 if(dest == 15) {
5713 reg[15].I &= 0xFFFFFFFC;
5714 armNextPC = reg[15].I;
5715 reg[15].I += 4;
5716 ARM_PREFETCH;
5717 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5719 clockTicks += 3 + dataTicksAccess32(address) +
5720 codeTicksAccess32(armNextPC);
5722 break;
5723 case 0x640:
5724 case 0x648:
5725 // T versions are the same
5726 case 0x660:
5727 case 0x668:
5729 // STRB Rd, [Rn], -Rm, LSL #
5730 if (!busPrefetchCount)
5731 busPrefetch = busPrefetchEnable;
5732 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5733 int dest = (opcode >> 12) & 15;
5734 int base = (opcode >> 16) & 15;
5735 u32 address = reg[base].I;
5736 CPUWriteByte(address, reg[dest].B.B0);
5737 reg[base].I = address - offset;
5738 clockTicks = 2 + dataTicksAccess16(address) +
5739 codeTicksAccess32(armNextPC);
5741 break;
5742 case 0x642:
5743 case 0x64a:
5744 // T versions are the same
5745 case 0x662:
5746 case 0x66a:
5748 // STRB Rd, [Rn], -Rm, LSR #
5749 if (!busPrefetchCount)
5750 busPrefetch = busPrefetchEnable;
5751 int shift = (opcode >> 7) & 31;
5752 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5753 int dest = (opcode >> 12) & 15;
5754 int base = (opcode >> 16) & 15;
5755 u32 address = reg[base].I;
5756 CPUWriteByte(address, reg[dest].B.B0);
5757 reg[base].I = address - offset;
5758 clockTicks = 2 + dataTicksAccess16(address) +
5759 codeTicksAccess32(armNextPC);
5761 break;
5762 case 0x644:
5763 case 0x64c:
5764 // T versions are the same
5765 case 0x664:
5766 case 0x66c:
5768 // STRB Rd, [Rn], -Rm, ASR #
5769 if (!busPrefetchCount)
5770 busPrefetch = busPrefetchEnable;
5771 int shift = (opcode >> 7) & 31;
5772 int offset;
5773 if(shift)
5774 offset = (int)((s32)reg[opcode & 15].I >> shift);
5775 else if(reg[opcode & 15].I & 0x80000000)
5776 offset = 0xFFFFFFFF;
5777 else
5778 offset = 0;
5779 int dest = (opcode >> 12) & 15;
5780 int base = (opcode >> 16) & 15;
5781 u32 address = reg[base].I;
5782 CPUWriteByte(address, reg[dest].B.B0);
5783 reg[base].I = address - offset;
5784 clockTicks = 2 + dataTicksAccess16(address) +
5785 codeTicksAccess32(armNextPC);
5787 break;
5788 case 0x646:
5789 case 0x64e:
5790 // T versions are the same
5791 case 0x666:
5792 case 0x66e:
5794 // STRB Rd, [Rn], -Rm, ROR #
5795 if (!busPrefetchCount)
5796 busPrefetch = busPrefetchEnable;
5797 int shift = (opcode >> 7) & 31;
5798 u32 value = reg[opcode & 15].I;
5799 if(shift) {
5800 ROR_VALUE;
5801 } else {
5802 RCR_VALUE;
5804 int dest = (opcode >> 12) & 15;
5805 int base = (opcode >> 16) & 15;
5806 u32 address = reg[base].I;
5807 CPUWriteByte(address, reg[dest].B.B0);
5808 reg[base].I = address - value;
5809 clockTicks = 2 + dataTicksAccess16(address) +
5810 codeTicksAccess32(armNextPC);
5812 break;
5813 case 0x6c0:
5814 case 0x6c8:
5815 // T versions are the same
5816 case 0x6e0:
5817 case 0x6e8:
5819 // STRB Rd, [Rn], Rm, LSL #
5820 if (!busPrefetchCount)
5821 busPrefetch = busPrefetchEnable;
5822 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5823 int dest = (opcode >> 12) & 15;
5824 int base = (opcode >> 16) & 15;
5825 u32 address = reg[base].I;
5826 CPUWriteByte(address, reg[dest].B.B0);
5827 reg[base].I = address + offset;
5828 clockTicks = 2 + dataTicksAccess16(address) +
5829 codeTicksAccess32(armNextPC);
5831 break;
5832 case 0x6c2:
5833 case 0x6ca:
5834 // T versions are the same
5835 case 0x6e2:
5836 case 0x6ea:
5838 // STRB Rd, [Rn], Rm, LSR #
5839 if (!busPrefetchCount)
5840 busPrefetch = busPrefetchEnable;
5841 int shift = (opcode >> 7) & 31;
5842 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5843 int dest = (opcode >> 12) & 15;
5844 int base = (opcode >> 16) & 15;
5845 u32 address = reg[base].I;
5846 CPUWriteByte(address, reg[dest].B.B0);
5847 reg[base].I = address + offset;
5848 clockTicks = 2 + dataTicksAccess16(address) +
5849 codeTicksAccess32(armNextPC);
5851 break;
5852 case 0x6c4:
5853 case 0x6cc:
5854 // T versions are the same
5855 case 0x6e4:
5856 case 0x6ec:
5858 // STRB Rd, [Rn], Rm, ASR #
5859 if (!busPrefetchCount)
5860 busPrefetch = busPrefetchEnable;
5861 int shift = (opcode >> 7) & 31;
5862 int offset;
5863 if(shift)
5864 offset = (int)((s32)reg[opcode & 15].I >> shift);
5865 else if(reg[opcode & 15].I & 0x80000000)
5866 offset = 0xFFFFFFFF;
5867 else
5868 offset = 0;
5869 int dest = (opcode >> 12) & 15;
5870 int base = (opcode >> 16) & 15;
5871 u32 address = reg[base].I;
5872 CPUWriteByte(address, reg[dest].B.B0);
5873 reg[base].I = address + offset;
5874 clockTicks = 2 + dataTicksAccess16(address) +
5875 codeTicksAccess32(armNextPC);
5877 break;
5878 case 0x6c6:
5879 case 0x6ce:
5880 // T versions are the same
5881 case 0x6e6:
5882 case 0x6ee:
5884 // STRB Rd, [Rn], Rm, ROR #
5885 if (!busPrefetchCount)
5886 busPrefetch = busPrefetchEnable;
5887 int shift = (opcode >> 7) & 31;
5888 u32 value = reg[opcode & 15].I;
5889 if(shift) {
5890 ROR_VALUE;
5891 } else {
5892 RCR_VALUE;
5894 int dest = (opcode >> 12) & 15;
5895 int base = (opcode >> 16) & 15;
5896 u32 address = reg[base].I;
5897 CPUWriteByte(address, reg[dest].B.B0);
5898 reg[base].I = address + value;
5899 clockTicks = 2 + dataTicksAccess16(address) +
5900 codeTicksAccess32(armNextPC);
5902 break;
5903 case 0x740:
5904 case 0x748:
5906 // STRB Rd, [Rn, -Rm, LSL #]
5907 if (!busPrefetchCount)
5908 busPrefetch = busPrefetchEnable;
5909 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5910 int dest = (opcode >> 12) & 15;
5911 int base = (opcode >> 16) & 15;
5912 u32 address = reg[base].I - offset;
5913 CPUWriteByte(address, reg[dest].B.B0);
5914 clockTicks = 2 + dataTicksAccess16(address) +
5915 codeTicksAccess32(armNextPC);
5917 break;
5918 case 0x742:
5919 case 0x74a:
5921 // STRB Rd, [Rn, -Rm, LSR #]
5922 if (!busPrefetchCount)
5923 busPrefetch = busPrefetchEnable;
5924 int shift = (opcode >> 7) & 31;
5925 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5926 int dest = (opcode >> 12) & 15;
5927 int base = (opcode >> 16) & 15;
5928 u32 address = reg[base].I - offset;
5929 CPUWriteByte(address, reg[dest].B.B0);
5930 clockTicks = 2 + dataTicksAccess16(address) +
5931 codeTicksAccess32(armNextPC);
5933 break;
5934 case 0x744:
5935 case 0x74c:
5937 // STRB Rd, [Rn, -Rm, ASR #]
5938 if (!busPrefetchCount)
5939 busPrefetch = busPrefetchEnable;
5940 int shift = (opcode >> 7) & 31;
5941 int offset;
5942 if(shift)
5943 offset = (int)((s32)reg[opcode & 15].I >> shift);
5944 else if(reg[opcode & 15].I & 0x80000000)
5945 offset = 0xFFFFFFFF;
5946 else
5947 offset = 0;
5948 int dest = (opcode >> 12) & 15;
5949 int base = (opcode >> 16) & 15;
5950 u32 address = reg[base].I - offset;
5951 CPUWriteByte(address, reg[dest].B.B0);
5952 clockTicks = 2 + dataTicksAccess16(address) +
5953 codeTicksAccess32(armNextPC);
5955 break;
5956 case 0x746:
5957 case 0x74e:
5959 // STRB Rd, [Rn, -Rm, ROR #]
5960 if (!busPrefetchCount)
5961 busPrefetch = busPrefetchEnable;
5962 int shift = (opcode >> 7) & 31;
5963 u32 value = reg[opcode & 15].I;
5964 if(shift) {
5965 ROR_VALUE;
5966 } else {
5967 RCR_VALUE;
5969 int dest = (opcode >> 12) & 15;
5970 int base = (opcode >> 16) & 15;
5971 u32 address = reg[base].I - value;
5972 CPUWriteByte(address, reg[dest].B.B0);
5973 clockTicks = 2 + dataTicksAccess16(address) +
5974 codeTicksAccess32(armNextPC);
5976 break;
5977 case 0x760:
5978 case 0x768:
5980 // STRB Rd, [Rn, -Rm, LSL #]!
5981 if (!busPrefetchCount)
5982 busPrefetch = busPrefetchEnable;
5983 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5984 int dest = (opcode >> 12) & 15;
5985 int base = (opcode >> 16) & 15;
5986 u32 address = reg[base].I - offset;
5987 reg[base].I = address;
5988 CPUWriteByte(address, reg[dest].B.B0);
5989 clockTicks = 2 + dataTicksAccess16(address) +
5990 codeTicksAccess32(armNextPC);
5992 break;
5993 case 0x762:
5994 case 0x76a:
5996 // STRB Rd, [Rn, -Rm, LSR #]!
5997 if (!busPrefetchCount)
5998 busPrefetch = busPrefetchEnable;
5999 int shift = (opcode >> 7) & 31;
6000 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6001 int dest = (opcode >> 12) & 15;
6002 int base = (opcode >> 16) & 15;
6003 u32 address = reg[base].I - offset;
6004 reg[base].I = address;
6005 CPUWriteByte(address, reg[dest].B.B0);
6006 clockTicks = 2 + dataTicksAccess16(address) +
6007 codeTicksAccess32(armNextPC);
6009 break;
6010 case 0x764:
6011 case 0x76c:
6013 // STRB Rd, [Rn, -Rm, ASR #]!
6014 if (!busPrefetchCount)
6015 busPrefetch = busPrefetchEnable;
6016 int shift = (opcode >> 7) & 31;
6017 int offset;
6018 if(shift)
6019 offset = (int)((s32)reg[opcode & 15].I >> shift);
6020 else if(reg[opcode & 15].I & 0x80000000)
6021 offset = 0xFFFFFFFF;
6022 else
6023 offset = 0;
6024 int dest = (opcode >> 12) & 15;
6025 int base = (opcode >> 16) & 15;
6026 u32 address = reg[base].I - offset;
6027 reg[base].I = address;
6028 CPUWriteByte(address, reg[dest].B.B0);
6029 clockTicks = 2 + dataTicksAccess16(address) +
6030 codeTicksAccess32(armNextPC);
6032 break;
6033 case 0x766:
6034 case 0x76e:
6036 // STRB Rd, [Rn, -Rm, ROR #]!
6037 if (!busPrefetchCount)
6038 busPrefetch = busPrefetchEnable;
6039 int shift = (opcode >> 7) & 31;
6040 u32 value = reg[opcode & 15].I;
6041 if(shift) {
6042 ROR_VALUE;
6043 } else {
6044 RCR_VALUE;
6046 int dest = (opcode >> 12) & 15;
6047 int base = (opcode >> 16) & 15;
6048 u32 address = reg[base].I - value;
6049 reg[base].I = address;
6050 CPUWriteByte(address, reg[dest].B.B0);
6051 clockTicks = 2 + dataTicksAccess16(address) +
6052 codeTicksAccess32(armNextPC);
6054 break;
6055 case 0x7c0:
6056 case 0x7c8:
6058 // STRB Rd, [Rn, Rm, LSL #]
6059 if (!busPrefetchCount)
6060 busPrefetch = busPrefetchEnable;
6061 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6062 int dest = (opcode >> 12) & 15;
6063 int base = (opcode >> 16) & 15;
6064 u32 address = reg[base].I + offset;
6065 CPUWriteByte(address, reg[dest].B.B0);
6066 clockTicks = 2 + dataTicksAccess16(address) +
6067 codeTicksAccess32(armNextPC);
6069 break;
6070 case 0x7c2:
6071 case 0x7ca:
6073 // STRB Rd, [Rn, Rm, LSR #]
6074 if (!busPrefetchCount)
6075 busPrefetch = busPrefetchEnable;
6076 int shift = (opcode >> 7) & 31;
6077 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6078 int dest = (opcode >> 12) & 15;
6079 int base = (opcode >> 16) & 15;
6080 u32 address = reg[base].I + offset;
6081 CPUWriteByte(address, reg[dest].B.B0);
6082 clockTicks = 2 + dataTicksAccess16(address) +
6083 codeTicksAccess32(armNextPC);
6085 break;
6086 case 0x7c4:
6087 case 0x7cc:
6089 // STRB Rd, [Rn, Rm, ASR #]
6090 if (!busPrefetchCount)
6091 busPrefetch = busPrefetchEnable;
6092 int shift = (opcode >> 7) & 31;
6093 int offset;
6094 if(shift)
6095 offset = (int)((s32)reg[opcode & 15].I >> shift);
6096 else if(reg[opcode & 15].I & 0x80000000)
6097 offset = 0xFFFFFFFF;
6098 else
6099 offset = 0;
6100 int dest = (opcode >> 12) & 15;
6101 int base = (opcode >> 16) & 15;
6102 u32 address = reg[base].I + offset;
6103 CPUWriteByte(address, reg[dest].B.B0);
6104 clockTicks = 2 + dataTicksAccess16(address) +
6105 codeTicksAccess32(armNextPC);
6107 break;
6108 case 0x7c6:
6109 case 0x7ce:
6111 // STRB Rd, [Rn, Rm, ROR #]
6112 if (!busPrefetchCount)
6113 busPrefetch = busPrefetchEnable;
6114 int shift = (opcode >> 7) & 31;
6115 u32 value = reg[opcode & 15].I;
6116 if(shift) {
6117 ROR_VALUE;
6118 } else {
6119 RCR_VALUE;
6121 int dest = (opcode >> 12) & 15;
6122 int base = (opcode >> 16) & 15;
6123 u32 address = reg[base].I + value;
6124 CPUWriteByte(address, reg[dest].B.B0);
6125 clockTicks = 2 + dataTicksAccess16(address) +
6126 codeTicksAccess32(armNextPC);
6128 break;
6129 case 0x7e0:
6130 case 0x7e8:
6132 // STRB Rd, [Rn, Rm, LSL #]!
6133 if (!busPrefetchCount)
6134 busPrefetch = busPrefetchEnable;
6135 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6136 int dest = (opcode >> 12) & 15;
6137 int base = (opcode >> 16) & 15;
6138 u32 address = reg[base].I + offset;
6139 reg[base].I = address;
6140 CPUWriteByte(address, reg[dest].B.B0);
6141 clockTicks = 2 + dataTicksAccess16(address) +
6142 codeTicksAccess32(armNextPC);
6144 break;
6145 case 0x7e2:
6146 case 0x7ea:
6148 // STRB Rd, [Rn, Rm, LSR #]!
6149 if (!busPrefetchCount)
6150 busPrefetch = busPrefetchEnable;
6151 int shift = (opcode >> 7) & 31;
6152 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6153 int dest = (opcode >> 12) & 15;
6154 int base = (opcode >> 16) & 15;
6155 u32 address = reg[base].I + offset;
6156 reg[base].I = address;
6157 CPUWriteByte(address, reg[dest].B.B0);
6158 clockTicks = 2 + dataTicksAccess16(address) +
6159 codeTicksAccess32(armNextPC);
6161 break;
6162 case 0x7e4:
6163 case 0x7ec:
6165 // STRB Rd, [Rn, Rm, ASR #]!
6166 if (!busPrefetchCount)
6167 busPrefetch = busPrefetchEnable;
6168 int shift = (opcode >> 7) & 31;
6169 int offset;
6170 if(shift)
6171 offset = (int)((s32)reg[opcode & 15].I >> shift);
6172 else if(reg[opcode & 15].I & 0x80000000)
6173 offset = 0xFFFFFFFF;
6174 else
6175 offset = 0;
6176 int dest = (opcode >> 12) & 15;
6177 int base = (opcode >> 16) & 15;
6178 u32 address = reg[base].I + offset;
6179 reg[base].I = address;
6180 CPUWriteByte(address, reg[dest].B.B0);
6181 clockTicks = 2 + dataTicksAccess16(address) +
6182 codeTicksAccess32(armNextPC);
6184 break;
6185 case 0x7e6:
6186 case 0x7ee:
6188 // STRB Rd, [Rn, Rm, ROR #]!
6189 if (!busPrefetchCount)
6190 busPrefetch = busPrefetchEnable;
6191 int shift = (opcode >> 7) & 31;
6192 u32 value = reg[opcode & 15].I;
6193 if(shift) {
6194 ROR_VALUE;
6195 } else {
6196 RCR_VALUE;
6198 int dest = (opcode >> 12) & 15;
6199 int base = (opcode >> 16) & 15;
6200 u32 address = reg[base].I + value;
6201 reg[base].I = address;
6202 CPUWriteByte(address, reg[dest].B.B0);
6203 clockTicks = 2 + dataTicksAccess16(address) +
6204 codeTicksAccess32(armNextPC);
6206 break;
6207 case 0x650:
6208 case 0x658:
6209 // T versions are the same
6210 case 0x670:
6211 case 0x678:
6213 // LDRB Rd, [Rn], -Rm, LSL #
6214 if (!busPrefetchCount)
6215 busPrefetch = busPrefetchEnable;
6216 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6217 int dest = (opcode >> 12) & 15;
6218 int base = (opcode >> 16) & 15;
6219 u32 address = reg[base].I;
6220 reg[dest].I = CPUReadByte(address);
6221 if(dest != base)
6222 reg[base].I = address - offset;
6223 clockTicks = 0;
6224 if(dest == 15) {
6225 reg[15].I &= 0xFFFFFFFC;
6226 armNextPC = reg[15].I;
6227 reg[15].I += 4;
6228 ARM_PREFETCH;
6229 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6231 clockTicks += 3 + dataTicksAccess16(address) +
6232 codeTicksAccess32(armNextPC);
6234 break;
6235 case 0x652:
6236 case 0x65a:
6237 // T versions are the same
6238 case 0x672:
6239 case 0x67a:
6241 // LDRB Rd, [Rn], -Rm, LSR #
6242 if (!busPrefetchCount)
6243 busPrefetch = busPrefetchEnable;
6244 int shift = (opcode >> 7) & 31;
6245 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6246 int dest = (opcode >> 12) & 15;
6247 int base = (opcode >> 16) & 15;
6248 u32 address = reg[base].I;
6249 reg[dest].I = CPUReadByte(address);
6250 if(dest != base)
6251 reg[base].I = address - offset;
6252 clockTicks = 0;
6253 if(dest == 15) {
6254 reg[15].I &= 0xFFFFFFFC;
6255 armNextPC = reg[15].I;
6256 reg[15].I += 4;
6257 ARM_PREFETCH;
6258 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6260 clockTicks += 3 + dataTicksAccess16(address) +
6261 codeTicksAccess32(armNextPC);
6263 break;
6264 case 0x654:
6265 case 0x65c:
6266 // T versions are the same
6267 case 0x674:
6268 case 0x67c:
6270 // LDRB Rd, [Rn], -Rm, ASR #
6271 if (!busPrefetchCount)
6272 busPrefetch = busPrefetchEnable;
6273 int shift = (opcode >> 7) & 31;
6274 int offset;
6275 if(shift)
6276 offset = (int)((s32)reg[opcode & 15].I >> shift);
6277 else if(reg[opcode & 15].I & 0x80000000)
6278 offset = 0xFFFFFFFF;
6279 else
6280 offset = 0;
6281 int dest = (opcode >> 12) & 15;
6282 int base = (opcode >> 16) & 15;
6283 u32 address = reg[base].I;
6284 reg[dest].I = CPUReadByte(address);
6285 if(dest != base)
6286 reg[base].I = address - offset;
6287 clockTicks = 0;
6288 if(dest == 15) {
6289 reg[15].I &= 0xFFFFFFFC;
6290 armNextPC = reg[15].I;
6291 reg[15].I += 4;
6292 ARM_PREFETCH;
6293 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6295 clockTicks += 3 + dataTicksAccess16(address) +
6296 codeTicksAccess32(armNextPC);
6298 break;
6299 case 0x656:
6300 case 0x65e:
6301 // T versions are the same
6302 case 0x676:
6303 case 0x67e:
6305 // LDRB Rd, [Rn], -Rm, ROR #
6306 if (!busPrefetchCount)
6307 busPrefetch = busPrefetchEnable;
6308 int shift = (opcode >> 7) & 31;
6309 u32 value = reg[opcode & 15].I;
6310 if(shift) {
6311 ROR_VALUE;
6312 } else {
6313 RCR_VALUE;
6315 int dest = (opcode >> 12) & 15;
6316 int base = (opcode >> 16) & 15;
6317 u32 address = reg[base].I;
6318 reg[dest].I = CPUReadByte(address);
6319 if(dest != base)
6320 reg[base].I = address - value;
6321 clockTicks = 0;
6322 if(dest == 15) {
6323 reg[15].I &= 0xFFFFFFFC;
6324 armNextPC = reg[15].I;
6325 reg[15].I += 4;
6326 ARM_PREFETCH;
6327 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6329 clockTicks += 3 + dataTicksAccess16(address) +
6330 codeTicksAccess32(armNextPC);
6332 break;
6333 case 0x6d0:
6334 case 0x6d8:
6335 // T versions are the same
6336 case 0x6f0:
6337 case 0x6f8:
6339 // LDRB Rd, [Rn], Rm, LSL #
6340 if (!busPrefetchCount)
6341 busPrefetch = busPrefetchEnable;
6342 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6343 int dest = (opcode >> 12) & 15;
6344 int base = (opcode >> 16) & 15;
6345 u32 address = reg[base].I;
6346 reg[dest].I = CPUReadByte(address);
6347 if(dest != base)
6348 reg[base].I = address + offset;
6349 clockTicks = 0;
6350 if(dest == 15) {
6351 reg[15].I &= 0xFFFFFFFC;
6352 armNextPC = reg[15].I;
6353 reg[15].I += 4;
6354 ARM_PREFETCH;
6355 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6357 clockTicks += 3 + dataTicksAccess16(address) +
6358 codeTicksAccess32(armNextPC);
6360 break;
6361 case 0x6d2:
6362 case 0x6da:
6363 // T versions are the same
6364 case 0x6f2:
6365 case 0x6fa:
6367 // LDRB Rd, [Rn], Rm, LSR #
6368 if (!busPrefetchCount)
6369 busPrefetch = busPrefetchEnable;
6370 int shift = (opcode >> 7) & 31;
6371 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6372 int dest = (opcode >> 12) & 15;
6373 int base = (opcode >> 16) & 15;
6374 u32 address = reg[base].I;
6375 reg[dest].I = CPUReadByte(address);
6376 if(dest != base)
6377 reg[base].I = address + offset;
6378 clockTicks = 0;
6379 if(dest == 15) {
6380 reg[15].I &= 0xFFFFFFFC;
6381 armNextPC = reg[15].I;
6382 reg[15].I += 4;
6383 ARM_PREFETCH;
6384 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6386 clockTicks += 3 + dataTicksAccess16(address) +
6387 codeTicksAccess32(armNextPC);
6389 break;
6390 case 0x6d4:
6391 case 0x6dc:
6392 // T versions are the same
6393 case 0x6f4:
6394 case 0x6fc:
6396 // LDRB Rd, [Rn], Rm, ASR #
6397 if (!busPrefetchCount)
6398 busPrefetch = busPrefetchEnable;
6399 int shift = (opcode >> 7) & 31;
6400 int offset;
6401 if(shift)
6402 offset = (int)((s32)reg[opcode & 15].I >> shift);
6403 else if(reg[opcode & 15].I & 0x80000000)
6404 offset = 0xFFFFFFFF;
6405 else
6406 offset = 0;
6407 int dest = (opcode >> 12) & 15;
6408 int base = (opcode >> 16) & 15;
6409 u32 address = reg[base].I;
6410 reg[dest].I = CPUReadByte(address);
6411 if(dest != base)
6412 reg[base].I = address + offset;
6413 clockTicks = 0;
6414 if(dest == 15) {
6415 reg[15].I &= 0xFFFFFFFC;
6416 armNextPC = reg[15].I;
6417 reg[15].I += 4;
6418 ARM_PREFETCH;
6419 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6421 clockTicks += 3 + dataTicksAccess16(address) +
6422 codeTicksAccess32(armNextPC);
6424 break;
6425 case 0x6d6:
6426 case 0x6de:
6427 // T versions are the same
6428 case 0x6f6:
6429 case 0x6fe:
6431 // LDRB Rd, [Rn], Rm, ROR #
6432 if (!busPrefetchCount)
6433 busPrefetch = busPrefetchEnable;
6434 int shift = (opcode >> 7) & 31;
6435 u32 value = reg[opcode & 15].I;
6436 if(shift) {
6437 ROR_VALUE;
6438 } else {
6439 RCR_VALUE;
6441 int dest = (opcode >> 12) & 15;
6442 int base = (opcode >> 16) & 15;
6443 u32 address = reg[base].I;
6444 reg[dest].I = CPUReadByte(address);
6445 if(dest != base)
6446 reg[base].I = address + value;
6447 clockTicks = 0;
6448 if(dest == 15) {
6449 reg[15].I &= 0xFFFFFFFC;
6450 armNextPC = reg[15].I;
6451 reg[15].I += 4;
6452 ARM_PREFETCH;
6453 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6455 clockTicks += 3 + dataTicksAccess16(address) +
6456 codeTicksAccess32(armNextPC);
6458 break;
6459 case 0x750:
6460 case 0x758:
6462 // LDRB Rd, [Rn, -Rm, LSL #]
6463 if (!busPrefetchCount)
6464 busPrefetch = busPrefetchEnable;
6465 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6466 int dest = (opcode >> 12) & 15;
6467 int base = (opcode >> 16) & 15;
6468 u32 address = reg[base].I - offset;
6469 reg[dest].I = CPUReadByte(address);
6470 clockTicks = 0;
6471 if(dest == 15) {
6472 reg[15].I &= 0xFFFFFFFC;
6473 armNextPC = reg[15].I;
6474 reg[15].I += 4;
6475 ARM_PREFETCH;
6476 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6478 clockTicks += 3 + dataTicksAccess16(address) +
6479 codeTicksAccess32(armNextPC);
6481 break;
6482 case 0x752:
6483 case 0x75a:
6485 // LDRB Rd, [Rn, -Rm, LSR #]
6486 if (!busPrefetchCount)
6487 busPrefetch = busPrefetchEnable;
6488 int shift = (opcode >> 7) & 31;
6489 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6490 int dest = (opcode >> 12) & 15;
6491 int base = (opcode >> 16) & 15;
6492 u32 address = reg[base].I - offset;
6493 reg[dest].I = CPUReadByte(address);
6494 clockTicks = 0;
6495 if(dest == 15) {
6496 reg[15].I &= 0xFFFFFFFC;
6497 armNextPC = reg[15].I;
6498 reg[15].I += 4;
6499 ARM_PREFETCH;
6500 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6502 clockTicks += 3 + dataTicksAccess16(address) +
6503 codeTicksAccess32(armNextPC);
6505 break;
6506 case 0x754:
6507 case 0x75c:
6509 // LDRB Rd, [Rn, -Rm, ASR #]
6510 if (!busPrefetchCount)
6511 busPrefetch = busPrefetchEnable;
6512 int shift = (opcode >> 7) & 31;
6513 int offset;
6514 if(shift)
6515 offset = (int)((s32)reg[opcode & 15].I >> shift);
6516 else if(reg[opcode & 15].I & 0x80000000)
6517 offset = 0xFFFFFFFF;
6518 else
6519 offset = 0;
6520 int dest = (opcode >> 12) & 15;
6521 int base = (opcode >> 16) & 15;
6522 u32 address = reg[base].I - offset;
6523 reg[dest].I = CPUReadByte(address);
6524 clockTicks = 0;
6525 if(dest == 15) {
6526 reg[15].I &= 0xFFFFFFFC;
6527 armNextPC = reg[15].I;
6528 reg[15].I += 4;
6529 ARM_PREFETCH;
6530 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6532 clockTicks += 3 + dataTicksAccess16(address) +
6533 codeTicksAccess32(armNextPC);
6535 break;
6536 case 0x756:
6537 case 0x75e:
6539 // LDRB Rd, [Rn, -Rm, ROR #]
6540 if (!busPrefetchCount)
6541 busPrefetch = busPrefetchEnable;
6542 int shift = (opcode >> 7) & 31;
6543 u32 value = reg[opcode & 15].I;
6544 if(shift) {
6545 ROR_VALUE;
6546 } else {
6547 RCR_VALUE;
6549 int dest = (opcode >> 12) & 15;
6550 int base = (opcode >> 16) & 15;
6551 u32 address = reg[base].I - value;
6552 reg[dest].I = CPUReadByte(address);
6553 clockTicks = 0;
6554 if(dest == 15) {
6555 reg[15].I &= 0xFFFFFFFC;
6556 armNextPC = reg[15].I;
6557 reg[15].I += 4;
6558 ARM_PREFETCH;
6559 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6561 clockTicks += 3 + dataTicksAccess16(address) +
6562 codeTicksAccess32(armNextPC);
6564 break;
6565 case 0x770:
6566 case 0x778:
6568 // LDRB Rd, [Rn, -Rm, LSL #]!
6569 if (!busPrefetchCount)
6570 busPrefetch = busPrefetchEnable;
6571 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6572 int dest = (opcode >> 12) & 15;
6573 int base = (opcode >> 16) & 15;
6574 u32 address = reg[base].I - offset;
6575 reg[dest].I = CPUReadByte(address);
6576 if(dest != base)
6577 reg[base].I = address;
6578 clockTicks = 0;
6579 if(dest == 15) {
6580 reg[15].I &= 0xFFFFFFFC;
6581 armNextPC = reg[15].I;
6582 reg[15].I += 4;
6583 ARM_PREFETCH;
6584 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6586 clockTicks += 3 + dataTicksAccess16(address) +
6587 codeTicksAccess32(armNextPC);
6589 break;
6590 case 0x772:
6591 case 0x77a:
6593 // LDRB Rd, [Rn, -Rm, LSR #]!
6594 if (!busPrefetchCount)
6595 busPrefetch = busPrefetchEnable;
6596 int shift = (opcode >> 7) & 31;
6597 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6598 int dest = (opcode >> 12) & 15;
6599 int base = (opcode >> 16) & 15;
6600 u32 address = reg[base].I - offset;
6601 reg[dest].I = CPUReadByte(address);
6602 if(dest != base)
6603 reg[base].I = address;
6604 clockTicks = 0;
6605 if(dest == 15) {
6606 reg[15].I &= 0xFFFFFFFC;
6607 armNextPC = reg[15].I;
6608 reg[15].I += 4;
6609 ARM_PREFETCH;
6610 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6612 clockTicks += 3 + dataTicksAccess16(address) +
6613 codeTicksAccess32(armNextPC);
6615 break;
6616 case 0x774:
6617 case 0x77c:
6619 // LDRB Rd, [Rn, -Rm, ASR #]!
6620 if (!busPrefetchCount)
6621 busPrefetch = busPrefetchEnable;
6622 int shift = (opcode >> 7) & 31;
6623 int offset;
6624 if(shift)
6625 offset = (int)((s32)reg[opcode & 15].I >> shift);
6626 else if(reg[opcode & 15].I & 0x80000000)
6627 offset = 0xFFFFFFFF;
6628 else
6629 offset = 0;
6630 int dest = (opcode >> 12) & 15;
6631 int base = (opcode >> 16) & 15;
6632 u32 address = reg[base].I - offset;
6633 reg[dest].I = CPUReadByte(address);
6634 if(dest != base)
6635 reg[base].I = address;
6636 clockTicks = 0;
6637 if(dest == 15) {
6638 reg[15].I &= 0xFFFFFFFC;
6639 armNextPC = reg[15].I;
6640 reg[15].I += 4;
6641 ARM_PREFETCH;
6642 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6644 clockTicks += 3 + dataTicksAccess16(address) +
6645 codeTicksAccess32(armNextPC);
6647 break;
6648 case 0x776:
6649 case 0x77e:
6651 // LDRB Rd, [Rn, -Rm, ROR #]!
6652 if (!busPrefetchCount)
6653 busPrefetch = busPrefetchEnable;
6654 int shift = (opcode >> 7) & 31;
6655 u32 value = reg[opcode & 15].I;
6656 if(shift) {
6657 ROR_VALUE;
6658 } else {
6659 RCR_VALUE;
6661 int dest = (opcode >> 12) & 15;
6662 int base = (opcode >> 16) & 15;
6663 u32 address = reg[base].I - value;
6664 reg[dest].I = CPUReadByte(address);
6665 if(dest != base)
6666 reg[base].I = address;
6667 clockTicks = 0;
6668 if(dest == 15) {
6669 reg[15].I &= 0xFFFFFFFC;
6670 armNextPC = reg[15].I;
6671 reg[15].I += 4;
6672 ARM_PREFETCH;
6673 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6675 clockTicks += 3 + dataTicksAccess16(address) +
6676 codeTicksAccess32(armNextPC);
6678 break;
6679 case 0x7d0:
6680 case 0x7d8:
6682 // LDRB Rd, [Rn, Rm, LSL #]
6683 if (!busPrefetchCount)
6684 busPrefetch = busPrefetchEnable;
6685 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6686 int dest = (opcode >> 12) & 15;
6687 int base = (opcode >> 16) & 15;
6688 u32 address = reg[base].I + offset;
6689 reg[dest].I = CPUReadByte(address);
6690 clockTicks = 0;
6691 if(dest == 15) {
6692 reg[15].I &= 0xFFFFFFFC;
6693 armNextPC = reg[15].I;
6694 reg[15].I += 4;
6695 ARM_PREFETCH;
6696 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6698 clockTicks += 3 + dataTicksAccess16(address) +
6699 codeTicksAccess32(armNextPC);
6701 break;
6702 case 0x7d2:
6703 case 0x7da:
6705 // LDRB Rd, [Rn, Rm, LSR #]
6706 if (!busPrefetchCount)
6707 busPrefetch = busPrefetchEnable;
6708 int shift = (opcode >> 7) & 31;
6709 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6710 int dest = (opcode >> 12) & 15;
6711 int base = (opcode >> 16) & 15;
6712 u32 address = reg[base].I + offset;
6713 reg[dest].I = CPUReadByte(address);
6714 clockTicks = 0;
6715 if(dest == 15) {
6716 reg[15].I &= 0xFFFFFFFC;
6717 armNextPC = reg[15].I;
6718 reg[15].I += 4;
6719 ARM_PREFETCH;
6720 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6722 clockTicks += 3 + dataTicksAccess16(address) +
6723 codeTicksAccess32(armNextPC);
6725 break;
6726 case 0x7d4:
6727 case 0x7dc:
6729 // LDRB Rd, [Rn, Rm, ASR #]
6730 if (!busPrefetchCount)
6731 busPrefetch = busPrefetchEnable;
6732 int shift = (opcode >> 7) & 31;
6733 int offset;
6734 if(shift)
6735 offset = (int)((s32)reg[opcode & 15].I >> shift);
6736 else if(reg[opcode & 15].I & 0x80000000)
6737 offset = 0xFFFFFFFF;
6738 else
6739 offset = 0;
6740 int dest = (opcode >> 12) & 15;
6741 int base = (opcode >> 16) & 15;
6742 u32 address = reg[base].I + offset;
6743 reg[dest].I = CPUReadByte(address);
6744 clockTicks = 0;
6745 if(dest == 15) {
6746 reg[15].I &= 0xFFFFFFFC;
6747 armNextPC = reg[15].I;
6748 reg[15].I += 4;
6749 ARM_PREFETCH;
6750 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6752 clockTicks += 3 + dataTicksAccess16(address) +
6753 codeTicksAccess32(armNextPC);
6755 break;
6756 case 0x7d6:
6757 case 0x7de:
6759 // LDRB Rd, [Rn, Rm, ROR #]
6760 if (!busPrefetchCount)
6761 busPrefetch = busPrefetchEnable;
6762 int shift = (opcode >> 7) & 31;
6763 u32 value = reg[opcode & 15].I;
6764 if(shift) {
6765 ROR_VALUE;
6766 } else {
6767 RCR_VALUE;
6769 int dest = (opcode >> 12) & 15;
6770 int base = (opcode >> 16) & 15;
6771 u32 address = reg[base].I + value;
6772 reg[dest].I = CPUReadByte(address);
6773 clockTicks = 0;
6774 if(dest == 15) {
6775 reg[15].I &= 0xFFFFFFFC;
6776 armNextPC = reg[15].I;
6777 reg[15].I += 4;
6778 ARM_PREFETCH;
6779 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6781 clockTicks += 3 + dataTicksAccess16(address) +
6782 codeTicksAccess32(armNextPC);
6784 break;
6785 case 0x7f0:
6786 case 0x7f8:
6788 // LDRB Rd, [Rn, Rm, LSL #]!
6789 if (!busPrefetchCount)
6790 busPrefetch = busPrefetchEnable;
6791 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6792 int dest = (opcode >> 12) & 15;
6793 int base = (opcode >> 16) & 15;
6794 u32 address = reg[base].I + offset;
6795 reg[dest].I = CPUReadByte(address);
6796 if(dest != base)
6797 reg[base].I = address;
6798 clockTicks = 0;
6799 if(dest == 15) {
6800 reg[15].I &= 0xFFFFFFFC;
6801 armNextPC = reg[15].I;
6802 reg[15].I += 4;
6803 ARM_PREFETCH;
6804 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6806 clockTicks += 3 + dataTicksAccess16(address) +
6807 codeTicksAccess32(armNextPC);
6809 break;
6810 case 0x7f2:
6811 case 0x7fa:
6813 // LDRB Rd, [Rn, Rm, LSR #]!
6814 if (!busPrefetchCount)
6815 busPrefetch = busPrefetchEnable;
6816 int shift = (opcode >> 7) & 31;
6817 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6818 int dest = (opcode >> 12) & 15;
6819 int base = (opcode >> 16) & 15;
6820 u32 address = reg[base].I + offset;
6821 reg[dest].I = CPUReadByte(address);
6822 if(dest != base)
6823 reg[base].I = address;
6824 clockTicks = 0;
6825 if(dest == 15) {
6826 reg[15].I &= 0xFFFFFFFC;
6827 armNextPC = reg[15].I;
6828 reg[15].I += 4;
6829 ARM_PREFETCH;
6830 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6832 clockTicks += 3 + dataTicksAccess16(address) +
6833 codeTicksAccess32(armNextPC);
6835 break;
6836 case 0x7f4:
6837 case 0x7fc:
6839 // LDRB Rd, [Rn, Rm, ASR #]!
6840 if (!busPrefetchCount)
6841 busPrefetch = busPrefetchEnable;
6842 int shift = (opcode >> 7) & 31;
6843 int offset;
6844 if(shift)
6845 offset = (int)((s32)reg[opcode & 15].I >> shift);
6846 else if(reg[opcode & 15].I & 0x80000000)
6847 offset = 0xFFFFFFFF;
6848 else
6849 offset = 0;
6850 int dest = (opcode >> 12) & 15;
6851 int base = (opcode >> 16) & 15;
6852 u32 address = reg[base].I + offset;
6853 reg[dest].I = CPUReadByte(address);
6854 if(dest != base)
6855 reg[base].I = address;
6856 clockTicks = 0;
6857 if(dest == 15) {
6858 reg[15].I &= 0xFFFFFFFC;
6859 armNextPC = reg[15].I;
6860 reg[15].I += 4;
6861 ARM_PREFETCH;
6862 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6864 clockTicks += 3 + dataTicksAccess16(address) +
6865 codeTicksAccess32(armNextPC);
6867 break;
6868 case 0x7f6:
6869 case 0x7fe:
6871 // LDRB Rd, [Rn, Rm, ROR #]!
6872 if (!busPrefetchCount)
6873 busPrefetch = busPrefetchEnable;
6874 int shift = (opcode >> 7) & 31;
6875 u32 value = reg[opcode & 15].I;
6876 if(shift) {
6877 ROR_VALUE;
6878 } else {
6879 RCR_VALUE;
6881 int dest = (opcode >> 12) & 15;
6882 int base = (opcode >> 16) & 15;
6883 u32 address = reg[base].I + value;
6884 reg[dest].I = CPUReadByte(address);
6885 if(dest != base)
6886 reg[base].I = address;
6887 clockTicks = 0;
6888 if(dest == 15) {
6889 reg[15].I &= 0xFFFFFFFC;
6890 armNextPC = reg[15].I;
6891 reg[15].I += 4;
6892 ARM_PREFETCH;
6893 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6895 clockTicks += 3 + dataTicksAccess16(address) +
6896 codeTicksAccess32(armNextPC);
6898 break;
6899 #define STMW_REG(val,num) \
6900 if(opcode & (val)) {\
6901 CPUWriteMemory(address, reg[(num)].I);\
6902 if(!offset) {\
6903 reg[base].I = temp;\
6904 clockTicks += 1 + dataTicksAccess32(address);\
6905 offset = 1;\
6906 } else {\
6907 clockTicks += 1 + dataTicksAccessSeq32(address);\
6909 address += 4;\
6911 #define STM_REG(val,num) \
6912 if(opcode & (val)) {\
6913 CPUWriteMemory(address, reg[(num)].I);\
6914 if(!offset) {\
6915 clockTicks += 1 + dataTicksAccess32(address);\
6916 offset = 1;\
6917 } else {\
6918 clockTicks += 1 + dataTicksAccessSeq32(address);\
6920 address += 4;\
6923 CASE_16(0x800)
6925 // STMDA Rn, {Rlist}
6926 if (!busPrefetchCount)
6927 busPrefetch = busPrefetchEnable;
6928 int base = (opcode & 0x000F0000) >> 16;
6929 u32 temp = reg[base].I -
6930 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6931 u32 address = (temp + 4) & 0xFFFFFFFC;
6932 int offset = 0;
6933 STM_REG(1, 0);
6934 STM_REG(2, 1);
6935 STM_REG(4, 2);
6936 STM_REG(8, 3);
6937 STM_REG(16, 4);
6938 STM_REG(32, 5);
6939 STM_REG(64, 6);
6940 STM_REG(128, 7);
6941 STM_REG(256, 8);
6942 STM_REG(512, 9);
6943 STM_REG(1024, 10);
6944 STM_REG(2048, 11);
6945 STM_REG(4096, 12);
6946 STM_REG(8192, 13);
6947 STM_REG(16384, 14);
6948 if(opcode & 32768) {
6949 CPUWriteMemory(address, reg[15].I+4);
6950 if(!offset)
6951 clockTicks += 1 + dataTicksAccess32(address);
6952 else
6953 clockTicks += 1 + dataTicksAccessSeq32(address);
6955 clockTicks += 1 + codeTicksAccess32(armNextPC);
6957 break;
6958 CASE_16(0x820)
6960 // STMDA Rn!, {Rlist}
6961 if (!busPrefetchCount)
6962 busPrefetch = busPrefetchEnable;
6963 int base = (opcode & 0x000F0000) >> 16;
6964 u32 temp = reg[base].I -
6965 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6966 u32 address = (temp+4) & 0xFFFFFFFC;
6967 int offset = 0;
6969 STMW_REG(1, 0);
6970 STMW_REG(2, 1);
6971 STMW_REG(4, 2);
6972 STMW_REG(8, 3);
6973 STMW_REG(16, 4);
6974 STMW_REG(32, 5);
6975 STMW_REG(64, 6);
6976 STMW_REG(128, 7);
6977 STMW_REG(256, 8);
6978 STMW_REG(512, 9);
6979 STMW_REG(1024, 10);
6980 STMW_REG(2048, 11);
6981 STMW_REG(4096, 12);
6982 STMW_REG(8192, 13);
6983 STMW_REG(16384, 14);
6984 if(opcode & 32768) {
6985 CPUWriteMemory(address, reg[15].I+4);
6986 if(!offset)
6987 clockTicks += 1 + dataTicksAccess32(address);
6988 else
6989 clockTicks += 1 + dataTicksAccessSeq32(address);
6990 reg[base].I = temp;
6992 clockTicks += 1 + codeTicksAccess32(armNextPC);
6994 break;
6995 CASE_16(0x840)
6997 // STMDA Rn, {Rlist}^
6998 if (!busPrefetchCount)
6999 busPrefetch = busPrefetchEnable;
7000 int base = (opcode & 0x000F0000) >> 16;
7001 u32 temp = reg[base].I -
7002 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7003 u32 address = (temp+4) & 0xFFFFFFFC;
7004 int offset = 0;
7006 STM_REG(1, 0);
7007 STM_REG(2, 1);
7008 STM_REG(4, 2);
7009 STM_REG(8, 3);
7010 STM_REG(16, 4);
7011 STM_REG(32, 5);
7012 STM_REG(64, 6);
7013 STM_REG(128, 7);
7015 if(armMode == 0x11) {
7016 STM_REG(256, R8_FIQ);
7017 STM_REG(512, R9_FIQ);
7018 STM_REG(1024, R10_FIQ);
7019 STM_REG(2048, R11_FIQ);
7020 STM_REG(4096, R12_FIQ);
7021 } else {
7022 STM_REG(256, 8);
7023 STM_REG(512, 9);
7024 STM_REG(1024, 10);
7025 STM_REG(2048, 11);
7026 STM_REG(4096, 12);
7029 if(armMode != 0x10 && armMode != 0x1f) {
7030 STM_REG(8192, R13_USR);
7031 STM_REG(16384, R14_USR);
7032 } else {
7033 STM_REG(8192, 13);
7034 STM_REG(16384, 14);
7037 if(opcode & 32768) {
7038 CPUWriteMemory(address, reg[15].I+4);
7039 if(!offset)
7040 clockTicks += 1 + dataTicksAccess32(address);
7041 else
7042 clockTicks += 1 + dataTicksAccessSeq32(address);
7044 clockTicks += 1 + codeTicksAccess32(armNextPC);
7046 break;
7047 CASE_16(0x860)
7049 // STMDA Rn!, {Rlist}^
7050 if (!busPrefetchCount)
7051 busPrefetch = busPrefetchEnable;
7052 int base = (opcode & 0x000F0000) >> 16;
7053 u32 temp = reg[base].I -
7054 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7055 u32 address = (temp+4) & 0xFFFFFFFC;
7056 int offset = 0;
7058 STMW_REG(1, 0);
7059 STMW_REG(2, 1);
7060 STMW_REG(4, 2);
7061 STMW_REG(8, 3);
7062 STMW_REG(16, 4);
7063 STMW_REG(32, 5);
7064 STMW_REG(64, 6);
7065 STMW_REG(128, 7);
7067 if(armMode == 0x11) {
7068 STMW_REG(256, R8_FIQ);
7069 STMW_REG(512, R9_FIQ);
7070 STMW_REG(1024, R10_FIQ);
7071 STMW_REG(2048, R11_FIQ);
7072 STMW_REG(4096, R12_FIQ);
7073 } else {
7074 STMW_REG(256, 8);
7075 STMW_REG(512, 9);
7076 STMW_REG(1024, 10);
7077 STMW_REG(2048, 11);
7078 STMW_REG(4096, 12);
7081 if(armMode != 0x10 && armMode != 0x1f) {
7082 STMW_REG(8192, R13_USR);
7083 STMW_REG(16384, R14_USR);
7084 } else {
7085 STMW_REG(8192, 13);
7086 STMW_REG(16384, 14);
7089 if(opcode & 32768) {
7090 CPUWriteMemory(address, reg[15].I+4);
7091 if(!offset)
7092 clockTicks += 1 + dataTicksAccess32(address);
7093 else
7094 clockTicks += 1 + dataTicksAccessSeq32(address);
7095 reg[base].I = temp;
7097 clockTicks += 1 + codeTicksAccess32(armNextPC);
7099 break;
7101 CASE_16(0x880)
7103 // STMIA Rn, {Rlist}
7104 if (!busPrefetchCount)
7105 busPrefetch = busPrefetchEnable;
7106 int base = (opcode & 0x000F0000) >> 16;
7107 u32 address = reg[base].I & 0xFFFFFFFC;
7108 int offset = 0;
7109 STM_REG(1, 0);
7110 STM_REG(2, 1);
7111 STM_REG(4, 2);
7112 STM_REG(8, 3);
7113 STM_REG(16, 4);
7114 STM_REG(32, 5);
7115 STM_REG(64, 6);
7116 STM_REG(128, 7);
7117 STM_REG(256, 8);
7118 STM_REG(512, 9);
7119 STM_REG(1024, 10);
7120 STM_REG(2048, 11);
7121 STM_REG(4096, 12);
7122 STM_REG(8192, 13);
7123 STM_REG(16384, 14);
7124 if(opcode & 32768) {
7125 CPUWriteMemory(address, reg[15].I+4);
7126 if(!offset)
7127 clockTicks += 1 + dataTicksAccess32(address);
7128 else
7129 clockTicks += 1 + dataTicksAccessSeq32(address);
7131 clockTicks += 1 + codeTicksAccess32(armNextPC);
7133 break;
7134 CASE_16(0x8a0)
7136 // STMIA Rn!, {Rlist}
7137 if (!busPrefetchCount)
7138 busPrefetch = busPrefetchEnable;
7139 int base = (opcode & 0x000F0000) >> 16;
7140 u32 address = reg[base].I & 0xFFFFFFFC;
7141 int offset = 0;
7142 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
7143 cpuBitsSet[(opcode >> 8) & 255]);
7144 STMW_REG(1, 0);
7145 STMW_REG(2, 1);
7146 STMW_REG(4, 2);
7147 STMW_REG(8, 3);
7148 STMW_REG(16, 4);
7149 STMW_REG(32, 5);
7150 STMW_REG(64, 6);
7151 STMW_REG(128, 7);
7152 STMW_REG(256, 8);
7153 STMW_REG(512, 9);
7154 STMW_REG(1024, 10);
7155 STMW_REG(2048, 11);
7156 STMW_REG(4096, 12);
7157 STMW_REG(8192, 13);
7158 STMW_REG(16384, 14);
7159 if(opcode & 32768) {
7160 CPUWriteMemory(address, reg[15].I+4);
7161 if(!offset) {
7162 reg[base].I = temp;
7163 clockTicks += 1 + dataTicksAccess32(address);
7164 } else
7165 clockTicks += 1 + dataTicksAccessSeq32(address);
7167 clockTicks += 1 + codeTicksAccess32(armNextPC);
7169 break;
7170 CASE_16(0x8c0)
7172 // STMIA Rn, {Rlist}^
7173 if (!busPrefetchCount)
7174 busPrefetch = busPrefetchEnable;
7175 int base = (opcode & 0x000F0000) >> 16;
7176 u32 address = reg[base].I & 0xFFFFFFFC;
7177 int offset = 0;
7178 STM_REG(1, 0);
7179 STM_REG(2, 1);
7180 STM_REG(4, 2);
7181 STM_REG(8, 3);
7182 STM_REG(16, 4);
7183 STM_REG(32, 5);
7184 STM_REG(64, 6);
7185 STM_REG(128, 7);
7186 if(armMode == 0x11) {
7187 STM_REG(256, R8_FIQ);
7188 STM_REG(512, R9_FIQ);
7189 STM_REG(1024, R10_FIQ);
7190 STM_REG(2048, R11_FIQ);
7191 STM_REG(4096, R12_FIQ);
7192 } else {
7193 STM_REG(256, 8);
7194 STM_REG(512, 9);
7195 STM_REG(1024, 10);
7196 STM_REG(2048, 11);
7197 STM_REG(4096, 12);
7199 if(armMode != 0x10 && armMode != 0x1f) {
7200 STM_REG(8192, R13_USR);
7201 STM_REG(16384, R14_USR);
7202 } else {
7203 STM_REG(8192, 13);
7204 STM_REG(16384, 14);
7206 if(opcode & 32768) {
7207 CPUWriteMemory(address, reg[15].I+4);
7208 if(!offset)
7209 clockTicks += 1 + dataTicksAccess32(address);
7210 else
7211 clockTicks += 1 + dataTicksAccessSeq32(address);
7213 clockTicks += 1 + codeTicksAccess32(armNextPC);
7215 break;
7216 CASE_16(0x8e0)
7218 // STMIA Rn!, {Rlist}^
7219 if (!busPrefetchCount)
7220 busPrefetch = busPrefetchEnable;
7221 int base = (opcode & 0x000F0000) >> 16;
7222 u32 address = reg[base].I & 0xFFFFFFFC;
7223 int offset = 0;
7224 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
7225 cpuBitsSet[(opcode >> 8) & 255]);
7226 STMW_REG(1, 0);
7227 STMW_REG(2, 1);
7228 STMW_REG(4, 2);
7229 STMW_REG(8, 3);
7230 STMW_REG(16, 4);
7231 STMW_REG(32, 5);
7232 STMW_REG(64, 6);
7233 STMW_REG(128, 7);
7234 if(armMode == 0x11) {
7235 STMW_REG(256, R8_FIQ);
7236 STMW_REG(512, R9_FIQ);
7237 STMW_REG(1024, R10_FIQ);
7238 STMW_REG(2048, R11_FIQ);
7239 STMW_REG(4096, R12_FIQ);
7240 } else {
7241 STMW_REG(256, 8);
7242 STMW_REG(512, 9);
7243 STMW_REG(1024, 10);
7244 STMW_REG(2048, 11);
7245 STMW_REG(4096, 12);
7247 if(armMode != 0x10 && armMode != 0x1f) {
7248 STMW_REG(8192, R13_USR);
7249 STMW_REG(16384, R14_USR);
7250 } else {
7251 STMW_REG(8192, 13);
7252 STMW_REG(16384, 14);
7254 if(opcode & 32768) {
7255 CPUWriteMemory(address, reg[15].I+4);
7256 if(!offset) {
7257 reg[base].I = temp;
7258 clockTicks += 1 + dataTicksAccess32(address);
7259 } else
7260 clockTicks += 1 + dataTicksAccessSeq32(address);
7262 clockTicks += 1 + codeTicksAccess32(armNextPC);
7264 break;
7266 CASE_16(0x900)
7268 // STMDB Rn, {Rlist}
7269 if (!busPrefetchCount)
7270 busPrefetch = busPrefetchEnable;
7271 int base = (opcode & 0x000F0000) >> 16;
7272 u32 temp = reg[base].I -
7273 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7274 u32 address = temp & 0xFFFFFFFC;
7275 int offset = 0;
7276 STM_REG(1, 0);
7277 STM_REG(2, 1);
7278 STM_REG(4, 2);
7279 STM_REG(8, 3);
7280 STM_REG(16, 4);
7281 STM_REG(32, 5);
7282 STM_REG(64, 6);
7283 STM_REG(128, 7);
7284 STM_REG(256, 8);
7285 STM_REG(512, 9);
7286 STM_REG(1024, 10);
7287 STM_REG(2048, 11);
7288 STM_REG(4096, 12);
7289 STM_REG(8192, 13);
7290 STM_REG(16384, 14);
7291 if(opcode & 32768) {
7292 CPUWriteMemory(address, reg[15].I+4);
7293 if(!offset)
7294 clockTicks += 1 + dataTicksAccess32(address);
7295 else
7296 clockTicks += 1 + dataTicksAccessSeq32(address);
7298 clockTicks += 1 + codeTicksAccess32(armNextPC);
7300 break;
7301 CASE_16(0x920)
7303 // STMDB Rn!, {Rlist}
7304 if (!busPrefetchCount)
7305 busPrefetch = busPrefetchEnable;
7306 int base = (opcode & 0x000F0000) >> 16;
7307 u32 temp = reg[base].I -
7308 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7309 u32 address = temp & 0xFFFFFFFC;
7310 int offset = 0;
7312 STMW_REG(1, 0);
7313 STMW_REG(2, 1);
7314 STMW_REG(4, 2);
7315 STMW_REG(8, 3);
7316 STMW_REG(16, 4);
7317 STMW_REG(32, 5);
7318 STMW_REG(64, 6);
7319 STMW_REG(128, 7);
7320 STMW_REG(256, 8);
7321 STMW_REG(512, 9);
7322 STMW_REG(1024, 10);
7323 STMW_REG(2048, 11);
7324 STMW_REG(4096, 12);
7325 STMW_REG(8192, 13);
7326 STMW_REG(16384, 14);
7327 if(opcode & 32768) {
7328 CPUWriteMemory(address, reg[15].I+4);
7329 if(!offset)
7330 clockTicks += 1 + dataTicksAccess32(address);
7331 else
7332 clockTicks += 1 + dataTicksAccessSeq32(address);
7333 reg[base].I = temp;
7335 clockTicks += 1 + codeTicksAccess32(armNextPC);
7337 break;
7338 CASE_16(0x940)
7340 // STMDB Rn, {Rlist}^
7341 if (!busPrefetchCount)
7342 busPrefetch = busPrefetchEnable;
7343 int base = (opcode & 0x000F0000) >> 16;
7344 u32 temp = reg[base].I -
7345 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7346 u32 address = temp & 0xFFFFFFFC;
7347 int offset = 0;
7349 STM_REG(1, 0);
7350 STM_REG(2, 1);
7351 STM_REG(4, 2);
7352 STM_REG(8, 3);
7353 STM_REG(16, 4);
7354 STM_REG(32, 5);
7355 STM_REG(64, 6);
7356 STM_REG(128, 7);
7358 if(armMode == 0x11) {
7359 STM_REG(256, R8_FIQ);
7360 STM_REG(512, R9_FIQ);
7361 STM_REG(1024, R10_FIQ);
7362 STM_REG(2048, R11_FIQ);
7363 STM_REG(4096, R12_FIQ);
7364 } else {
7365 STM_REG(256, 8);
7366 STM_REG(512, 9);
7367 STM_REG(1024, 10);
7368 STM_REG(2048, 11);
7369 STM_REG(4096, 12);
7372 if(armMode != 0x10 && armMode != 0x1f) {
7373 STM_REG(8192, R13_USR);
7374 STM_REG(16384, R14_USR);
7375 } else {
7376 STM_REG(8192, 13);
7377 STM_REG(16384, 14);
7380 if(opcode & 32768) {
7381 CPUWriteMemory(address, reg[15].I+4);
7382 if(!offset)
7383 clockTicks += 1 + dataTicksAccess32(address);
7384 else
7385 clockTicks += 1 + dataTicksAccessSeq32(address);
7387 clockTicks += 1 + codeTicksAccess32(armNextPC);
7389 break;
7390 CASE_16(0x960)
7392 // STMDB Rn!, {Rlist}^
7393 if (!busPrefetchCount)
7394 busPrefetch = busPrefetchEnable;
7395 int base = (opcode & 0x000F0000) >> 16;
7396 u32 temp = reg[base].I -
7397 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7398 u32 address = temp & 0xFFFFFFFC;
7399 int offset = 0;
7401 STMW_REG(1, 0);
7402 STMW_REG(2, 1);
7403 STMW_REG(4, 2);
7404 STMW_REG(8, 3);
7405 STMW_REG(16, 4);
7406 STMW_REG(32, 5);
7407 STMW_REG(64, 6);
7408 STMW_REG(128, 7);
7410 if(armMode == 0x11) {
7411 STMW_REG(256, R8_FIQ);
7412 STMW_REG(512, R9_FIQ);
7413 STMW_REG(1024, R10_FIQ);
7414 STMW_REG(2048, R11_FIQ);
7415 STMW_REG(4096, R12_FIQ);
7416 } else {
7417 STMW_REG(256, 8);
7418 STMW_REG(512, 9);
7419 STMW_REG(1024, 10);
7420 STMW_REG(2048, 11);
7421 STMW_REG(4096, 12);
7424 if(armMode != 0x10 && armMode != 0x1f) {
7425 STMW_REG(8192, R13_USR);
7426 STMW_REG(16384, R14_USR);
7427 } else {
7428 STMW_REG(8192, 13);
7429 STMW_REG(16384, 14);
7432 if(opcode & 32768) {
7433 CPUWriteMemory(address, reg[15].I+4);
7434 if(!offset)
7435 clockTicks += 1 + dataTicksAccess32(address);
7436 else
7437 clockTicks += 1 + dataTicksAccessSeq32(address);
7438 reg[base].I = temp;
7440 clockTicks += 1 + codeTicksAccess32(armNextPC);
7442 break;
7444 CASE_16(0x980)
7446 // STMIB Rn, {Rlist}
7447 if (!busPrefetchCount)
7448 busPrefetch = busPrefetchEnable;
7449 int base = (opcode & 0x000F0000) >> 16;
7450 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
7451 int offset = 0;
7452 STM_REG(1, 0);
7453 STM_REG(2, 1);
7454 STM_REG(4, 2);
7455 STM_REG(8, 3);
7456 STM_REG(16, 4);
7457 STM_REG(32, 5);
7458 STM_REG(64, 6);
7459 STM_REG(128, 7);
7460 STM_REG(256, 8);
7461 STM_REG(512, 9);
7462 STM_REG(1024, 10);
7463 STM_REG(2048, 11);
7464 STM_REG(4096, 12);
7465 STM_REG(8192, 13);
7466 STM_REG(16384, 14);
7467 if(opcode & 32768) {
7468 CPUWriteMemory(address, reg[15].I+4);
7469 if(!offset)
7470 clockTicks += 1 + dataTicksAccess32(address);
7471 else
7472 clockTicks += 1 + dataTicksAccessSeq32(address);
7474 clockTicks += 1 + codeTicksAccess32(armNextPC);
7476 break;
7477 CASE_16(0x9a0)
7479 // STMIB Rn!, {Rlist}
7480 if (!busPrefetchCount)
7481 busPrefetch = busPrefetchEnable;
7482 int base = (opcode & 0x000F0000) >> 16;
7483 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
7484 int offset = 0;
7485 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
7486 cpuBitsSet[(opcode >> 8) & 255]);
7487 STMW_REG(1, 0);
7488 STMW_REG(2, 1);
7489 STMW_REG(4, 2);
7490 STMW_REG(8, 3);
7491 STMW_REG(16, 4);
7492 STMW_REG(32, 5);
7493 STMW_REG(64, 6);
7494 STMW_REG(128, 7);
7495 STMW_REG(256, 8);
7496 STMW_REG(512, 9);
7497 STMW_REG(1024, 10);
7498 STMW_REG(2048, 11);
7499 STMW_REG(4096, 12);
7500 STMW_REG(8192, 13);
7501 STMW_REG(16384, 14);
7502 if(opcode & 32768) {
7503 CPUWriteMemory(address, reg[15].I+4);
7504 if(!offset) {
7505 reg[base].I = temp;
7506 clockTicks += 1 + dataTicksAccess32(address);
7507 } else
7508 clockTicks += 1 + dataTicksAccessSeq32(address);
7510 clockTicks += 1 + codeTicksAccess32(armNextPC);
7512 break;
7513 CASE_16(0x9c0)
7515 // STMIB Rn, {Rlist}^
7516 if (!busPrefetchCount)
7517 busPrefetch = busPrefetchEnable;
7518 int base = (opcode & 0x000F0000) >> 16;
7519 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
7520 int offset = 0;
7521 STM_REG(1, 0);
7522 STM_REG(2, 1);
7523 STM_REG(4, 2);
7524 STM_REG(8, 3);
7525 STM_REG(16, 4);
7526 STM_REG(32, 5);
7527 STM_REG(64, 6);
7528 STM_REG(128, 7);
7529 if(armMode == 0x11) {
7530 STM_REG(256, R8_FIQ);
7531 STM_REG(512, R9_FIQ);
7532 STM_REG(1024, R10_FIQ);
7533 STM_REG(2048, R11_FIQ);
7534 STM_REG(4096, R12_FIQ);
7535 } else {
7536 STM_REG(256, 8);
7537 STM_REG(512, 9);
7538 STM_REG(1024, 10);
7539 STM_REG(2048, 11);
7540 STM_REG(4096, 12);
7542 if(armMode != 0x10 && armMode != 0x1f) {
7543 STM_REG(8192, R13_USR);
7544 STM_REG(16384, R14_USR);
7545 } else {
7546 STM_REG(8192, 13);
7547 STM_REG(16384, 14);
7549 if(opcode & 32768) {
7550 CPUWriteMemory(address, reg[15].I+4);
7551 if(!offset)
7552 clockTicks += 1 + dataTicksAccess32(address);
7553 else
7554 clockTicks += 1 + dataTicksAccessSeq32(address);
7556 clockTicks += 1 + codeTicksAccess32(armNextPC);
7558 break;
7559 CASE_16(0x9e0)
7561 // STMIB Rn!, {Rlist}^
7562 if (!busPrefetchCount)
7563 busPrefetch = busPrefetchEnable;
7564 int base = (opcode & 0x000F0000) >> 16;
7565 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
7566 int offset = 0;
7567 u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
7568 cpuBitsSet[(opcode >> 8) & 255]);
7569 STMW_REG(1, 0);
7570 STMW_REG(2, 1);
7571 STMW_REG(4, 2);
7572 STMW_REG(8, 3);
7573 STMW_REG(16, 4);
7574 STMW_REG(32, 5);
7575 STMW_REG(64, 6);
7576 STMW_REG(128, 7);
7577 if(armMode == 0x11) {
7578 STMW_REG(256, R8_FIQ);
7579 STMW_REG(512, R9_FIQ);
7580 STMW_REG(1024, R10_FIQ);
7581 STMW_REG(2048, R11_FIQ);
7582 STMW_REG(4096, R12_FIQ);
7583 } else {
7584 STMW_REG(256, 8);
7585 STMW_REG(512, 9);
7586 STMW_REG(1024, 10);
7587 STMW_REG(2048, 11);
7588 STMW_REG(4096, 12);
7590 if(armMode != 0x10 && armMode != 0x1f) {
7591 STMW_REG(8192, R13_USR);
7592 STMW_REG(16384, R14_USR);
7593 } else {
7594 STMW_REG(8192, 13);
7595 STMW_REG(16384, 14);
7597 if(opcode & 32768) {
7598 CPUWriteMemory(address, reg[15].I+4);
7599 if(!offset) {
7600 reg[base].I = temp;
7601 clockTicks += 1 + dataTicksAccess32(address);
7602 } else
7603 clockTicks += 1 + dataTicksAccessSeq32(address);
7605 clockTicks += 1 + codeTicksAccess32(armNextPC);
7607 break;
7609 #define LDM_REG(val,num) \
7610 if(opcode & (val)) {\
7611 reg[(num)].I = CPUReadMemory(address);\
7612 if(offset)\
7613 clockTicks += 1 + dataTicksAccessSeq32(address);\
7614 else {\
7615 clockTicks += 1 + dataTicksAccess32(address);\
7616 offset = 1;\
7618 address += 4;\
7621 CASE_16(0x810)
7623 // LDMDA Rn, {Rlist}
7624 if (!busPrefetchCount)
7625 busPrefetch = busPrefetchEnable;
7626 int base = (opcode & 0x000F0000) >> 16;
7627 u32 temp = reg[base].I -
7628 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7629 u32 address = (temp + 4) & 0xFFFFFFFC;
7630 clockTicks = 0;
7631 int offset = 0;
7632 LDM_REG(1, 0);
7633 LDM_REG(2, 1);
7634 LDM_REG(4, 2);
7635 LDM_REG(8, 3);
7636 LDM_REG(16, 4);
7637 LDM_REG(32, 5);
7638 LDM_REG(64, 6);
7639 LDM_REG(128, 7);
7640 LDM_REG(256, 8);
7641 LDM_REG(512, 9);
7642 LDM_REG(1024, 10);
7643 LDM_REG(2048, 11);
7644 LDM_REG(4096, 12);
7645 LDM_REG(8192, 13);
7646 LDM_REG(16384, 14);
7647 if(opcode & 32768) {
7648 reg[15].I = CPUReadMemory(address);
7649 armNextPC = reg[15].I;
7650 reg[15].I += 4;
7651 ARM_PREFETCH;
7652 if (!offset)
7653 clockTicks += 1 + dataTicksAccess32(address);
7654 else
7655 clockTicks += 1 + dataTicksAccessSeq32(address);
7656 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7658 clockTicks += 2 + codeTicksAccess32(armNextPC);
7660 break;
7661 CASE_16(0x830)
7663 // LDMDA Rn!, {Rlist}
7664 if (!busPrefetchCount)
7665 busPrefetch = busPrefetchEnable;
7666 int base = (opcode & 0x000F0000) >> 16;
7667 u32 temp = reg[base].I -
7668 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7669 u32 address = (temp + 4) & 0xFFFFFFFC;
7670 clockTicks = 0;
7671 int offset = 0;
7672 LDM_REG(1, 0);
7673 LDM_REG(2, 1);
7674 LDM_REG(4, 2);
7675 LDM_REG(8, 3);
7676 LDM_REG(16, 4);
7677 LDM_REG(32, 5);
7678 LDM_REG(64, 6);
7679 LDM_REG(128, 7);
7680 LDM_REG(256, 8);
7681 LDM_REG(512, 9);
7682 LDM_REG(1024, 10);
7683 LDM_REG(2048, 11);
7684 LDM_REG(4096, 12);
7685 LDM_REG(8192, 13);
7686 LDM_REG(16384, 14);
7687 if(opcode & 32768) {
7688 reg[15].I = CPUReadMemory(address);
7690 armNextPC = reg[15].I;
7691 reg[15].I += 4;
7692 ARM_PREFETCH;
7693 if (!offset)
7694 clockTicks += 1 + dataTicksAccess32(address);
7695 else
7696 clockTicks += 1 + dataTicksAccessSeq32(address);
7697 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7699 clockTicks += 2 + codeTicksAccess32(armNextPC);
7700 if(!(opcode & (1 << base)))
7701 reg[base].I = temp;
7703 break;
7704 CASE_16(0x850)
7706 // LDMDA Rn, {Rlist}^
7707 if (!busPrefetchCount)
7708 busPrefetch = busPrefetchEnable;
7709 int base = (opcode & 0x000F0000) >> 16;
7710 u32 temp = reg[base].I -
7711 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7712 u32 address = (temp + 4) & 0xFFFFFFFC;
7713 clockTicks = 0;
7714 int offset = 0;
7715 if(opcode & 0x8000) {
7716 LDM_REG(1, 0);
7717 LDM_REG(2, 1);
7718 LDM_REG(4, 2);
7719 LDM_REG(8, 3);
7720 LDM_REG(16, 4);
7721 LDM_REG(32, 5);
7722 LDM_REG(64, 6);
7723 LDM_REG(128, 7);
7724 LDM_REG(256, 8);
7725 LDM_REG(512, 9);
7726 LDM_REG(1024, 10);
7727 LDM_REG(2048, 11);
7728 LDM_REG(4096, 12);
7729 LDM_REG(8192, 13);
7730 LDM_REG(16384, 14);
7732 reg[15].I = CPUReadMemory(address);
7734 CPUSwitchMode(reg[17].I & 0x1f, false);
7735 if(armState) {
7736 armNextPC = reg[15].I & 0xFFFFFFFC;
7737 reg[15].I = armNextPC + 4;
7738 ARM_PREFETCH;
7739 } else {
7740 armNextPC = reg[15].I & 0xFFFFFFFE;
7741 reg[15].I = armNextPC + 2;
7742 THUMB_PREFETCH;
7744 } else {
7745 LDM_REG(1, 0);
7746 LDM_REG(2, 1);
7747 LDM_REG(4, 2);
7748 LDM_REG(8, 3);
7749 LDM_REG(16, 4);
7750 LDM_REG(32, 5);
7751 LDM_REG(64, 6);
7752 LDM_REG(128, 7);
7754 if(armMode == 0x11) {
7755 LDM_REG(256, R8_FIQ);
7756 LDM_REG(512, R9_FIQ);
7757 LDM_REG(1024, R10_FIQ);
7758 LDM_REG(2048, R11_FIQ);
7759 LDM_REG(4096, R12_FIQ);
7760 } else {
7761 LDM_REG(256, 8);
7762 LDM_REG(512, 9);
7763 LDM_REG(1024, 10);
7764 LDM_REG(2048, 11);
7765 LDM_REG(4096, 12);
7768 if(armMode != 0x10 && armMode != 0x1f) {
7769 LDM_REG(8192, R13_USR);
7770 LDM_REG(16384, R14_USR);
7771 } else {
7772 LDM_REG(8192, 13);
7773 LDM_REG(16384, 14);
7775 if (!offset)
7776 clockTicks += 1 + dataTicksAccess32(address);
7777 else
7778 clockTicks += 1 + dataTicksAccessSeq32(address);
7779 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7781 clockTicks += 2 + codeTicksAccess32(armNextPC);
7783 break;
7784 CASE_16(0x870)
7786 // LDMDA Rn!, {Rlist}^
7787 if (!busPrefetchCount)
7788 busPrefetch = busPrefetchEnable;
7789 int base = (opcode & 0x000F0000) >> 16;
7790 u32 temp = reg[base].I -
7791 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7792 u32 address = (temp + 4) & 0xFFFFFFFC;
7793 clockTicks = 0;
7794 int offset = 0;
7795 if(opcode & 0x8000) {
7796 LDM_REG(1, 0);
7797 LDM_REG(2, 1);
7798 LDM_REG(4, 2);
7799 LDM_REG(8, 3);
7800 LDM_REG(16, 4);
7801 LDM_REG(32, 5);
7802 LDM_REG(64, 6);
7803 LDM_REG(128, 7);
7804 LDM_REG(256, 8);
7805 LDM_REG(512, 9);
7806 LDM_REG(1024, 10);
7807 LDM_REG(2048, 11);
7808 LDM_REG(4096, 12);
7809 LDM_REG(8192, 13);
7810 LDM_REG(16384, 14);
7812 reg[15].I = CPUReadMemory(address);
7814 if(!(opcode & (1 << base)))
7815 reg[base].I = temp;
7817 CPUSwitchMode(reg[17].I & 0x1f, false);
7818 if(armState) {
7819 armNextPC = reg[15].I & 0xFFFFFFFC;
7820 reg[15].I = armNextPC + 4;
7821 ARM_PREFETCH;
7822 } else {
7823 armNextPC = reg[15].I & 0xFFFFFFFE;
7824 reg[15].I = armNextPC + 2;
7825 THUMB_PREFETCH;
7827 } else {
7828 LDM_REG(1, 0);
7829 LDM_REG(2, 1);
7830 LDM_REG(4, 2);
7831 LDM_REG(8, 3);
7832 LDM_REG(16, 4);
7833 LDM_REG(32, 5);
7834 LDM_REG(64, 6);
7835 LDM_REG(128, 7);
7837 if(armMode == 0x11) {
7838 LDM_REG(256, R8_FIQ);
7839 LDM_REG(512, R9_FIQ);
7840 LDM_REG(1024, R10_FIQ);
7841 LDM_REG(2048, R11_FIQ);
7842 LDM_REG(4096, R12_FIQ);
7843 } else {
7844 LDM_REG(256, 8);
7845 LDM_REG(512, 9);
7846 LDM_REG(1024, 10);
7847 LDM_REG(2048, 11);
7848 LDM_REG(4096, 12);
7851 if(armMode != 0x10 && armMode != 0x1f) {
7852 LDM_REG(8192, R13_USR);
7853 LDM_REG(16384, R14_USR);
7854 } else {
7855 LDM_REG(8192, 13);
7856 LDM_REG(16384, 14);
7859 if(!(opcode & (1 << base)))
7860 reg[base].I = temp;
7861 if (!offset)
7862 clockTicks += 1 + dataTicksAccess32(address);
7863 else
7864 clockTicks += 1 + dataTicksAccessSeq32(address);
7865 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7867 clockTicks += 2 + codeTicksAccess32(armNextPC);
7869 break;
7871 CASE_16(0x890)
7873 // LDMIA Rn, {Rlist}
7874 if (!busPrefetchCount)
7875 busPrefetch = busPrefetchEnable;
7876 int base = (opcode & 0x000F0000) >> 16;
7877 u32 address = reg[base].I & 0xFFFFFFFC;
7878 clockTicks = 0;
7879 int offset = 0;
7880 LDM_REG(1, 0);
7881 LDM_REG(2, 1);
7882 LDM_REG(4, 2);
7883 LDM_REG(8, 3);
7884 LDM_REG(16, 4);
7885 LDM_REG(32, 5);
7886 LDM_REG(64, 6);
7887 LDM_REG(128, 7);
7888 LDM_REG(256, 8);
7889 LDM_REG(512, 9);
7890 LDM_REG(1024, 10);
7891 LDM_REG(2048, 11);
7892 LDM_REG(4096, 12);
7893 LDM_REG(8192, 13);
7894 LDM_REG(16384, 14);
7895 if(opcode & 32768) {
7896 reg[15].I = CPUReadMemory(address);
7898 armNextPC = reg[15].I;
7899 reg[15].I += 4;
7900 ARM_PREFETCH;
7901 if (!offset)
7902 clockTicks += 1 + dataTicksAccess32(address);
7903 else
7904 clockTicks += 1 + dataTicksAccessSeq32(address);
7905 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7907 clockTicks += 2 + codeTicksAccess32(armNextPC);
7909 break;
7910 CASE_16(0x8b0)
7912 // LDMIA Rn!, {Rlist}
7913 if (!busPrefetchCount)
7914 busPrefetch = busPrefetchEnable;
7915 int base = (opcode & 0x000F0000) >> 16;
7916 u32 temp = reg[base].I +
7917 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7918 u32 address = reg[base].I & 0xFFFFFFFC;
7919 clockTicks = 0;
7920 int offset = 0;
7921 LDM_REG(1, 0);
7922 LDM_REG(2, 1);
7923 LDM_REG(4, 2);
7924 LDM_REG(8, 3);
7925 LDM_REG(16, 4);
7926 LDM_REG(32, 5);
7927 LDM_REG(64, 6);
7928 LDM_REG(128, 7);
7929 LDM_REG(256, 8);
7930 LDM_REG(512, 9);
7931 LDM_REG(1024, 10);
7932 LDM_REG(2048, 11);
7933 LDM_REG(4096, 12);
7934 LDM_REG(8192, 13);
7935 LDM_REG(16384, 14);
7936 if(opcode & 32768) {
7937 reg[15].I = CPUReadMemory(address);
7939 armNextPC = reg[15].I;
7940 reg[15].I += 4;
7941 ARM_PREFETCH;
7942 if (!offset)
7943 clockTicks += 1 + dataTicksAccess32(address);
7944 else
7945 clockTicks += 1 + dataTicksAccessSeq32(address);
7946 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7948 clockTicks += 2 + codeTicksAccess32(armNextPC);
7949 if(!(opcode & (1 << base)))
7950 reg[base].I = temp;
7952 break;
7953 CASE_16(0x8d0)
7955 // LDMIA Rn, {Rlist}^
7956 if (!busPrefetchCount)
7957 busPrefetch = busPrefetchEnable;
7958 int base = (opcode & 0x000F0000) >> 16;
7959 u32 address = reg[base].I & 0xFFFFFFFC;
7960 clockTicks = 0;
7961 int offset = 0;
7962 if(opcode & 0x8000) {
7963 LDM_REG(1, 0);
7964 LDM_REG(2, 1);
7965 LDM_REG(4, 2);
7966 LDM_REG(8, 3);
7967 LDM_REG(16, 4);
7968 LDM_REG(32, 5);
7969 LDM_REG(64, 6);
7970 LDM_REG(128, 7);
7971 LDM_REG(256, 8);
7972 LDM_REG(512, 9);
7973 LDM_REG(1024, 10);
7974 LDM_REG(2048, 11);
7975 LDM_REG(4096, 12);
7976 LDM_REG(8192, 13);
7977 LDM_REG(16384, 14);
7979 reg[15].I = CPUReadMemory(address);
7981 CPUSwitchMode(reg[17].I & 0x1f, false);
7982 if(armState) {
7983 armNextPC = reg[15].I & 0xFFFFFFFC;
7984 reg[15].I = armNextPC + 4;
7985 ARM_PREFETCH;
7986 } else {
7987 armNextPC = reg[15].I & 0xFFFFFFFE;
7988 reg[15].I = armNextPC + 2;
7989 THUMB_PREFETCH;
7991 } else {
7992 LDM_REG(1, 0);
7993 LDM_REG(2, 1);
7994 LDM_REG(4, 2);
7995 LDM_REG(8, 3);
7996 LDM_REG(16, 4);
7997 LDM_REG(32, 5);
7998 LDM_REG(64, 6);
7999 LDM_REG(128, 7);
8001 if(armMode == 0x11) {
8002 LDM_REG(256, R8_FIQ);
8003 LDM_REG(512, R9_FIQ);
8004 LDM_REG(1024, R10_FIQ);
8005 LDM_REG(2048, R11_FIQ);
8006 LDM_REG(4096, R12_FIQ);
8007 } else {
8008 LDM_REG(256, 8);
8009 LDM_REG(512, 9);
8010 LDM_REG(1024, 10);
8011 LDM_REG(2048, 11);
8012 LDM_REG(4096, 12);
8015 if(armMode != 0x10 && armMode != 0x1f) {
8016 LDM_REG(8192, R13_USR);
8017 LDM_REG(16384, R14_USR);
8018 } else {
8019 LDM_REG(8192, 13);
8020 LDM_REG(16384, 14);
8022 if (!offset)
8023 clockTicks += 1 + dataTicksAccess32(address);
8024 else
8025 clockTicks += 1 + dataTicksAccessSeq32(address);
8026 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8028 clockTicks += 2 + codeTicksAccess32(armNextPC);
8030 break;
8031 CASE_16(0x8f0)
8033 // LDMIA Rn!, {Rlist}^
8034 if (!busPrefetchCount)
8035 busPrefetch = busPrefetchEnable;
8036 int base = (opcode & 0x000F0000) >> 16;
8037 u32 temp = reg[base].I +
8038 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8039 u32 address = reg[base].I & 0xFFFFFFFC;
8040 clockTicks = 0;
8041 int offset = 0;
8042 if(opcode & 0x8000) {
8043 LDM_REG(1, 0);
8044 LDM_REG(2, 1);
8045 LDM_REG(4, 2);
8046 LDM_REG(8, 3);
8047 LDM_REG(16, 4);
8048 LDM_REG(32, 5);
8049 LDM_REG(64, 6);
8050 LDM_REG(128, 7);
8051 LDM_REG(256, 8);
8052 LDM_REG(512, 9);
8053 LDM_REG(1024, 10);
8054 LDM_REG(2048, 11);
8055 LDM_REG(4096, 12);
8056 LDM_REG(8192, 13);
8057 LDM_REG(16384, 14);
8059 reg[15].I = CPUReadMemory(address);
8061 if(!(opcode & (1 << base)))
8062 reg[base].I = temp;
8064 CPUSwitchMode(reg[17].I & 0x1f, false);
8065 if(armState) {
8066 armNextPC = reg[15].I & 0xFFFFFFFC;
8067 reg[15].I = armNextPC + 4;
8068 ARM_PREFETCH;
8069 } else {
8070 armNextPC = reg[15].I & 0xFFFFFFFE;
8071 reg[15].I = armNextPC + 2;
8072 THUMB_PREFETCH;
8074 } else {
8075 LDM_REG(1, 0);
8076 LDM_REG(2, 1);
8077 LDM_REG(4, 2);
8078 LDM_REG(8, 3);
8079 LDM_REG(16, 4);
8080 LDM_REG(32, 5);
8081 LDM_REG(64, 6);
8082 LDM_REG(128, 7);
8084 if(armMode == 0x11) {
8085 LDM_REG(256, R8_FIQ);
8086 LDM_REG(512, R9_FIQ);
8087 LDM_REG(1024, R10_FIQ);
8088 LDM_REG(2048, R11_FIQ);
8089 LDM_REG(4096, R12_FIQ);
8090 } else {
8091 LDM_REG(256, 8);
8092 LDM_REG(512, 9);
8093 LDM_REG(1024, 10);
8094 LDM_REG(2048, 11);
8095 LDM_REG(4096, 12);
8098 if(armMode != 0x10 && armMode != 0x1f) {
8099 LDM_REG(8192, R13_USR);
8100 LDM_REG(16384, R14_USR);
8101 } else {
8102 LDM_REG(8192, 13);
8103 LDM_REG(16384, 14);
8106 if(!(opcode & (1 << base)))
8107 reg[base].I = temp;
8108 if (!offset)
8109 clockTicks += 1 + dataTicksAccess32(address);
8110 else
8111 clockTicks += 1 + dataTicksAccessSeq32(address);
8112 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8114 clockTicks += 2 + codeTicksAccess32(armNextPC);
8116 break;
8118 CASE_16(0x910)
8120 // LDMDB Rn, {Rlist}
8121 if (!busPrefetchCount)
8122 busPrefetch = busPrefetchEnable;
8123 int base = (opcode & 0x000F0000) >> 16;
8124 u32 temp = reg[base].I -
8125 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8126 u32 address = temp & 0xFFFFFFFC;
8127 clockTicks = 0;
8128 int offset = 0;
8129 LDM_REG(1, 0);
8130 LDM_REG(2, 1);
8131 LDM_REG(4, 2);
8132 LDM_REG(8, 3);
8133 LDM_REG(16, 4);
8134 LDM_REG(32, 5);
8135 LDM_REG(64, 6);
8136 LDM_REG(128, 7);
8137 LDM_REG(256, 8);
8138 LDM_REG(512, 9);
8139 LDM_REG(1024, 10);
8140 LDM_REG(2048, 11);
8141 LDM_REG(4096, 12);
8142 LDM_REG(8192, 13);
8143 LDM_REG(16384, 14);
8144 if(opcode & 32768) {
8145 reg[15].I = CPUReadMemory(address);
8147 armNextPC = reg[15].I;
8148 reg[15].I += 4;
8149 ARM_PREFETCH;
8150 if (!offset)
8151 clockTicks += 1 + dataTicksAccess32(address);
8152 else
8153 clockTicks += 1 + dataTicksAccessSeq32(address);
8154 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8156 clockTicks += 2 + codeTicksAccess32(armNextPC);
8158 break;
8159 CASE_16(0x930)
8161 // LDMDB Rn!, {Rlist}
8162 if (!busPrefetchCount)
8163 busPrefetch = busPrefetchEnable;
8164 int base = (opcode & 0x000F0000) >> 16;
8165 u32 temp = reg[base].I -
8166 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8167 u32 address = temp & 0xFFFFFFFC;
8168 clockTicks = 0;
8169 int offset = 0;
8170 LDM_REG(1, 0);
8171 LDM_REG(2, 1);
8172 LDM_REG(4, 2);
8173 LDM_REG(8, 3);
8174 LDM_REG(16, 4);
8175 LDM_REG(32, 5);
8176 LDM_REG(64, 6);
8177 LDM_REG(128, 7);
8178 LDM_REG(256, 8);
8179 LDM_REG(512, 9);
8180 LDM_REG(1024, 10);
8181 LDM_REG(2048, 11);
8182 LDM_REG(4096, 12);
8183 LDM_REG(8192, 13);
8184 LDM_REG(16384, 14);
8185 if(opcode & 32768) {
8186 reg[15].I = CPUReadMemory(address);
8188 armNextPC = reg[15].I;
8189 reg[15].I += 4;
8190 ARM_PREFETCH;
8191 if (!offset)
8192 clockTicks += 1 + dataTicksAccess32(address);
8193 else
8194 clockTicks += 1 + dataTicksAccessSeq32(address);
8195 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8197 clockTicks += 2 + codeTicksAccess32(armNextPC);
8198 if(!(opcode & (1 << base)))
8199 reg[base].I = temp;
8201 break;
8202 CASE_16(0x950)
8204 // LDMDB Rn, {Rlist}^
8205 if (!busPrefetchCount)
8206 busPrefetch = busPrefetchEnable;
8207 int base = (opcode & 0x000F0000) >> 16;
8208 u32 temp = reg[base].I -
8209 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8210 u32 address = temp & 0xFFFFFFFC;
8211 clockTicks = 0;
8212 int offset = 0;
8213 if(opcode & 0x8000) {
8214 LDM_REG(1, 0);
8215 LDM_REG(2, 1);
8216 LDM_REG(4, 2);
8217 LDM_REG(8, 3);
8218 LDM_REG(16, 4);
8219 LDM_REG(32, 5);
8220 LDM_REG(64, 6);
8221 LDM_REG(128, 7);
8222 LDM_REG(256, 8);
8223 LDM_REG(512, 9);
8224 LDM_REG(1024, 10);
8225 LDM_REG(2048, 11);
8226 LDM_REG(4096, 12);
8227 LDM_REG(8192, 13);
8228 LDM_REG(16384, 14);
8230 reg[15].I = CPUReadMemory(address);
8232 CPUSwitchMode(reg[17].I & 0x1f, false);
8233 if(armState) {
8234 armNextPC = reg[15].I & 0xFFFFFFFC;
8235 reg[15].I = armNextPC + 4;
8236 ARM_PREFETCH;
8237 } else {
8238 armNextPC = reg[15].I & 0xFFFFFFFE;
8239 reg[15].I = armNextPC + 2;
8240 THUMB_PREFETCH;
8242 } else {
8243 LDM_REG(1, 0);
8244 LDM_REG(2, 1);
8245 LDM_REG(4, 2);
8246 LDM_REG(8, 3);
8247 LDM_REG(16, 4);
8248 LDM_REG(32, 5);
8249 LDM_REG(64, 6);
8250 LDM_REG(128, 7);
8252 if(armMode == 0x11) {
8253 LDM_REG(256, R8_FIQ);
8254 LDM_REG(512, R9_FIQ);
8255 LDM_REG(1024, R10_FIQ);
8256 LDM_REG(2048, R11_FIQ);
8257 LDM_REG(4096, R12_FIQ);
8258 } else {
8259 LDM_REG(256, 8);
8260 LDM_REG(512, 9);
8261 LDM_REG(1024, 10);
8262 LDM_REG(2048, 11);
8263 LDM_REG(4096, 12);
8266 if(armMode != 0x10 && armMode != 0x1f) {
8267 LDM_REG(8192, R13_USR);
8268 LDM_REG(16384, R14_USR);
8269 } else {
8270 LDM_REG(8192, 13);
8271 LDM_REG(16384, 14);
8273 if (!offset)
8274 clockTicks += 1 + dataTicksAccess32(address);
8275 else
8276 clockTicks += 1 + dataTicksAccessSeq32(address);
8277 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8279 clockTicks += 2 + codeTicksAccess32(armNextPC);
8281 break;
8282 CASE_16(0x970)
8284 // LDMDB Rn!, {Rlist}^
8285 if (!busPrefetchCount)
8286 busPrefetch = busPrefetchEnable;
8287 int base = (opcode & 0x000F0000) >> 16;
8288 u32 temp = reg[base].I -
8289 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8290 u32 address = temp & 0xFFFFFFFC;
8291 clockTicks = 0;
8292 int offset = 0;
8293 if(opcode & 0x8000) {
8294 LDM_REG(1, 0);
8295 LDM_REG(2, 1);
8296 LDM_REG(4, 2);
8297 LDM_REG(8, 3);
8298 LDM_REG(16, 4);
8299 LDM_REG(32, 5);
8300 LDM_REG(64, 6);
8301 LDM_REG(128, 7);
8302 LDM_REG(256, 8);
8303 LDM_REG(512, 9);
8304 LDM_REG(1024, 10);
8305 LDM_REG(2048, 11);
8306 LDM_REG(4096, 12);
8307 LDM_REG(8192, 13);
8308 LDM_REG(16384, 14);
8310 reg[15].I = CPUReadMemory(address);
8312 if(!(opcode & (1 << base)))
8313 reg[base].I = temp;
8315 CPUSwitchMode(reg[17].I & 0x1f, false);
8316 if(armState) {
8317 armNextPC = reg[15].I & 0xFFFFFFFC;
8318 reg[15].I = armNextPC + 4;
8319 ARM_PREFETCH;
8320 } else {
8321 armNextPC = reg[15].I & 0xFFFFFFFE;
8322 reg[15].I = armNextPC + 2;
8323 THUMB_PREFETCH;
8325 } else {
8326 LDM_REG(1, 0);
8327 LDM_REG(2, 1);
8328 LDM_REG(4, 2);
8329 LDM_REG(8, 3);
8330 LDM_REG(16, 4);
8331 LDM_REG(32, 5);
8332 LDM_REG(64, 6);
8333 LDM_REG(128, 7);
8335 if(armMode == 0x11) {
8336 LDM_REG(256, R8_FIQ);
8337 LDM_REG(512, R9_FIQ);
8338 LDM_REG(1024, R10_FIQ);
8339 LDM_REG(2048, R11_FIQ);
8340 LDM_REG(4096, R12_FIQ);
8341 } else {
8342 LDM_REG(256, 8);
8343 LDM_REG(512, 9);
8344 LDM_REG(1024, 10);
8345 LDM_REG(2048, 11);
8346 LDM_REG(4096, 12);
8349 if(armMode != 0x10 && armMode != 0x1f) {
8350 LDM_REG(8192, R13_USR);
8351 LDM_REG(16384, R14_USR);
8352 } else {
8353 LDM_REG(8192, 13);
8354 LDM_REG(16384, 14);
8357 if(!(opcode & (1 << base)))
8358 reg[base].I = temp;
8359 if (!offset)
8360 clockTicks += 1 + dataTicksAccess32(address);
8361 else
8362 clockTicks += 1 + dataTicksAccessSeq32(address);
8363 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8365 clockTicks += 2 + codeTicksAccess32(armNextPC);
8367 break;
8369 CASE_16(0x990)
8371 // LDMIB Rn, {Rlist}
8372 if (!busPrefetchCount)
8373 busPrefetch = busPrefetchEnable;
8374 int base = (opcode & 0x000F0000) >> 16;
8375 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
8376 clockTicks = 0;
8377 int offset = 0;
8378 LDM_REG(1, 0);
8379 LDM_REG(2, 1);
8380 LDM_REG(4, 2);
8381 LDM_REG(8, 3);
8382 LDM_REG(16, 4);
8383 LDM_REG(32, 5);
8384 LDM_REG(64, 6);
8385 LDM_REG(128, 7);
8386 LDM_REG(256, 8);
8387 LDM_REG(512, 9);
8388 LDM_REG(1024, 10);
8389 LDM_REG(2048, 11);
8390 LDM_REG(4096, 12);
8391 LDM_REG(8192, 13);
8392 LDM_REG(16384, 14);
8393 if(opcode & 32768) {
8394 reg[15].I = CPUReadMemory(address);
8396 armNextPC = reg[15].I;
8397 reg[15].I += 4;
8398 ARM_PREFETCH;
8399 if (!offset)
8400 clockTicks += 1 + dataTicksAccess32(address);
8401 else
8402 clockTicks += 1 + dataTicksAccessSeq32(address);
8403 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8405 clockTicks += 2 + codeTicksAccess32(armNextPC);
8407 break;
8408 CASE_16(0x9b0)
8410 // LDMIB Rn!, {Rlist}
8411 if (!busPrefetchCount)
8412 busPrefetch = busPrefetchEnable;
8413 int base = (opcode & 0x000F0000) >> 16;
8414 u32 temp = reg[base].I +
8415 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8416 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
8417 clockTicks = 0;
8418 int offset = 0;
8419 LDM_REG(1, 0);
8420 LDM_REG(2, 1);
8421 LDM_REG(4, 2);
8422 LDM_REG(8, 3);
8423 LDM_REG(16, 4);
8424 LDM_REG(32, 5);
8425 LDM_REG(64, 6);
8426 LDM_REG(128, 7);
8427 LDM_REG(256, 8);
8428 LDM_REG(512, 9);
8429 LDM_REG(1024, 10);
8430 LDM_REG(2048, 11);
8431 LDM_REG(4096, 12);
8432 LDM_REG(8192, 13);
8433 LDM_REG(16384, 14);
8434 if(opcode & 32768) {
8435 reg[15].I = CPUReadMemory(address);
8436 if (!offset)
8437 clockTicks += 1 + dataTicksAccess32(address);
8438 else
8439 clockTicks += 1 + dataTicksAccessSeq32(address);
8440 clockTicks += 1 + dataTicksAccessSeq32(address);
8442 armNextPC = reg[15].I;
8443 reg[15].I += 4;
8444 ARM_PREFETCH;
8445 if (!offset)
8446 clockTicks += 1 + dataTicksAccess32(address);
8447 else
8448 clockTicks += 1 + dataTicksAccessSeq32(address);
8449 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8451 clockTicks += 2 + codeTicksAccess32(armNextPC);
8452 if(!(opcode & (1 << base)))
8453 reg[base].I = temp;
8455 break;
8456 CASE_16(0x9d0)
8458 // LDMIB Rn, {Rlist}^
8459 if (!busPrefetchCount)
8460 busPrefetch = busPrefetchEnable;
8461 int base = (opcode & 0x000F0000) >> 16;
8462 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
8463 clockTicks = 0;
8464 int offset = 0;
8465 if(opcode & 0x8000) {
8466 LDM_REG(1, 0);
8467 LDM_REG(2, 1);
8468 LDM_REG(4, 2);
8469 LDM_REG(8, 3);
8470 LDM_REG(16, 4);
8471 LDM_REG(32, 5);
8472 LDM_REG(64, 6);
8473 LDM_REG(128, 7);
8474 LDM_REG(256, 8);
8475 LDM_REG(512, 9);
8476 LDM_REG(1024, 10);
8477 LDM_REG(2048, 11);
8478 LDM_REG(4096, 12);
8479 LDM_REG(8192, 13);
8480 LDM_REG(16384, 14);
8482 reg[15].I = CPUReadMemory(address);
8484 CPUSwitchMode(reg[17].I & 0x1f, false);
8485 if(armState) {
8486 armNextPC = reg[15].I & 0xFFFFFFFC;
8487 reg[15].I = armNextPC + 4;
8488 ARM_PREFETCH;
8489 } else {
8490 armNextPC = reg[15].I & 0xFFFFFFFE;
8491 reg[15].I = armNextPC + 2;
8492 THUMB_PREFETCH;
8494 } else {
8495 LDM_REG(1, 0);
8496 LDM_REG(2, 1);
8497 LDM_REG(4, 2);
8498 LDM_REG(8, 3);
8499 LDM_REG(16, 4);
8500 LDM_REG(32, 5);
8501 LDM_REG(64, 6);
8502 LDM_REG(128, 7);
8504 if(armMode == 0x11) {
8505 LDM_REG(256, R8_FIQ);
8506 LDM_REG(512, R9_FIQ);
8507 LDM_REG(1024, R10_FIQ);
8508 LDM_REG(2048, R11_FIQ);
8509 LDM_REG(4096, R12_FIQ);
8510 } else {
8511 LDM_REG(256, 8);
8512 LDM_REG(512, 9);
8513 LDM_REG(1024, 10);
8514 LDM_REG(2048, 11);
8515 LDM_REG(4096, 12);
8518 if(armMode != 0x10 && armMode != 0x1f) {
8519 LDM_REG(8192, R13_USR);
8520 LDM_REG(16384, R14_USR);
8521 } else {
8522 LDM_REG(8192, 13);
8523 LDM_REG(16384, 14);
8525 if (!offset)
8526 clockTicks += 1 + dataTicksAccess32(address);
8527 else
8528 clockTicks += 1 + dataTicksAccessSeq32(address);
8529 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8531 clockTicks += 2 + codeTicksAccess32(armNextPC);
8533 break;
8534 CASE_16(0x9f0)
8536 // LDMIB Rn!, {Rlist}^
8537 if (!busPrefetchCount)
8538 busPrefetch = busPrefetchEnable;
8539 int base = (opcode & 0x000F0000) >> 16;
8540 u32 temp = reg[base].I +
8541 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
8542 u32 address = (reg[base].I+4) & 0xFFFFFFFC;
8543 clockTicks = 0;
8544 int offset = 0;
8545 if(opcode & 0x8000) {
8546 LDM_REG(1, 0);
8547 LDM_REG(2, 1);
8548 LDM_REG(4, 2);
8549 LDM_REG(8, 3);
8550 LDM_REG(16, 4);
8551 LDM_REG(32, 5);
8552 LDM_REG(64, 6);
8553 LDM_REG(128, 7);
8554 LDM_REG(256, 8);
8555 LDM_REG(512, 9);
8556 LDM_REG(1024, 10);
8557 LDM_REG(2048, 11);
8558 LDM_REG(4096, 12);
8559 LDM_REG(8192, 13);
8560 LDM_REG(16384, 14);
8562 reg[15].I = CPUReadMemory(address);
8564 if(!(opcode & (1 << base)))
8565 reg[base].I = temp;
8567 CPUSwitchMode(reg[17].I & 0x1f, false);
8568 if(armState) {
8569 armNextPC = reg[15].I & 0xFFFFFFFC;
8570 reg[15].I = armNextPC + 4;
8571 ARM_PREFETCH;
8572 } else {
8573 armNextPC = reg[15].I & 0xFFFFFFFE;
8574 reg[15].I = armNextPC + 2;
8575 THUMB_PREFETCH;
8577 } else {
8578 LDM_REG(1, 0);
8579 LDM_REG(2, 1);
8580 LDM_REG(4, 2);
8581 LDM_REG(8, 3);
8582 LDM_REG(16, 4);
8583 LDM_REG(32, 5);
8584 LDM_REG(64, 6);
8585 LDM_REG(128, 7);
8587 if(armMode == 0x11) {
8588 LDM_REG(256, R8_FIQ);
8589 LDM_REG(512, R9_FIQ);
8590 LDM_REG(1024, R10_FIQ);
8591 LDM_REG(2048, R11_FIQ);
8592 LDM_REG(4096, R12_FIQ);
8593 } else {
8594 LDM_REG(256, 8);
8595 LDM_REG(512, 9);
8596 LDM_REG(1024, 10);
8597 LDM_REG(2048, 11);
8598 LDM_REG(4096, 12);
8601 if(armMode != 0x10 && armMode != 0x1f) {
8602 LDM_REG(8192, R13_USR);
8603 LDM_REG(16384, R14_USR);
8604 } else {
8605 LDM_REG(8192, 13);
8606 LDM_REG(16384, 14);
8609 if(!(opcode & (1 << base)))
8610 reg[base].I = temp;
8611 if (!offset)
8612 clockTicks += 1 + dataTicksAccess32(address);
8613 else
8614 clockTicks += 1 + dataTicksAccessSeq32(address);
8615 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
8617 clockTicks += 2 + codeTicksAccess32(armNextPC);
8619 break;
8620 CASE_256(0xa00)
8622 // B <offset>
8623 int offset = opcode & 0x00FFFFFF;
8624 if(offset & 0x00800000) {
8625 offset |= 0xFF000000;
8627 offset <<= 2;
8628 reg[15].I += offset;
8629 armNextPC = reg[15].I;
8630 reg[15].I += 4;
8631 ARM_PREFETCH;
8632 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
8633 clockTicks += 2 + codeTicksAccess32(armNextPC) +
8634 codeTicksAccessSeq32(armNextPC);
8635 busPrefetchCount=0;
8637 break;
8638 CASE_256(0xb00)
8640 // BL <offset>
8641 int offset = opcode & 0x00FFFFFF;
8642 if(offset & 0x00800000) {
8643 offset |= 0xFF000000;
8645 offset <<= 2;
8646 reg[14].I = reg[15].I - 4;
8647 reg[15].I += offset;
8648 armNextPC = reg[15].I;
8649 reg[15].I += 4;
8650 ARM_PREFETCH;
8651 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
8652 clockTicks += 2 + codeTicksAccess32(armNextPC) +
8653 codeTicksAccessSeq32(armNextPC);
8654 busPrefetchCount=0;
8656 break;
8657 CASE_256(0xf00)
8658 // SWI <comment>
8659 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
8660 clockTicks += 2 + codeTicksAccess32(armNextPC) +
8661 codeTicksAccessSeq32(armNextPC);
8662 busPrefetchCount=0;
8663 CPUSoftwareInterrupt(opcode & 0x00FFFFFF);
8665 break;
8666 #ifdef GP_SUPPORT
8667 case 0xe11:
8668 case 0xe13:
8669 case 0xe15:
8670 case 0xe17:
8671 case 0xe19:
8672 case 0xe1b:
8673 case 0xe1d:
8674 case 0xe1f:
8675 // MRC
8676 break;
8677 case 0xe01:
8678 case 0xe03:
8679 case 0xe05:
8680 case 0xe07:
8681 case 0xe09:
8682 case 0xe0b:
8683 case 0xe0d:
8684 case 0xe0f:
8685 // MRC
8686 break;
8687 #endif
8688 default:
8689 #ifdef DEV_VERSION
8690 if(systemVerbose & VERBOSE_UNDEFINED)
8691 log("Undefined ARM instruction %08x at %08x\n", opcode,
8692 armNextPC-4);
8693 #endif
8694 CPUUndefinedException();
8695 break;
8696 // END
8700 if (clockTicks == 0)
8701 clockTicks = codeTicksAccessSeq32(oldArmNextPC) + 1;