4 * ARM7TDMI CPU emulation core.
6 * Copyright (c) 2005 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #define MODULE aica_module
21 #include "dreamcast.h"
23 #include "aica/armcore.h"
24 #include "aica/aica.h"
26 #define STM_R15_OFFSET 12
28 struct arm_registers armr;
30 void arm_set_mode( int mode );
32 uint32_t arm_exceptions[][2] = {{ MODE_SVC, 0x00000000 },
33 { MODE_UND, 0x00000004 },
34 { MODE_SVC, 0x00000008 },
35 { MODE_ABT, 0x0000000C },
36 { MODE_ABT, 0x00000010 },
37 { MODE_IRQ, 0x00000018 },
38 { MODE_FIQ, 0x0000001C } };
41 #define EXC_UNDEFINED 1
42 #define EXC_SOFTWARE 2
43 #define EXC_PREFETCH_ABORT 3
44 #define EXC_DATA_ABORT 4
46 #define EXC_FAST_IRQ 6
48 uint32_t arm_cpu_freq = ARM_BASE_RATE;
49 uint32_t arm_cpu_period = 1000 / ARM_BASE_RATE;
51 #define CYCLES_PER_SAMPLE ((ARM_BASE_RATE * 1000000) / AICA_SAMPLE_RATE)
53 static struct breakpoint_struct arm_breakpoints[MAX_BREAKPOINTS];
54 static int arm_breakpoint_count = 0;
56 void arm_set_breakpoint( uint32_t pc, breakpoint_type_t type )
58 arm_breakpoints[arm_breakpoint_count].address = pc;
59 arm_breakpoints[arm_breakpoint_count].type = type;
60 arm_breakpoint_count++;
63 gboolean arm_clear_breakpoint( uint32_t pc, breakpoint_type_t type )
67 for( i=0; i<arm_breakpoint_count; i++ ) {
68 if( arm_breakpoints[i].address == pc &&
69 arm_breakpoints[i].type == type ) {
70 while( ++i < arm_breakpoint_count ) {
71 arm_breakpoints[i-1].address = arm_breakpoints[i].address;
72 arm_breakpoints[i-1].type = arm_breakpoints[i].type;
74 arm_breakpoint_count--;
81 int arm_get_breakpoint( uint32_t pc )
84 for( i=0; i<arm_breakpoint_count; i++ ) {
85 if( arm_breakpoints[i].address == pc )
86 return arm_breakpoints[i].type;
91 uint32_t arm_run_slice( uint32_t num_samples )
98 for( i=0; i<num_samples; i++ ) {
99 for( j=0; j < CYCLES_PER_SAMPLE; j++ ) {
101 if( !arm_execute_instruction() )
103 #ifdef ENABLE_DEBUG_MODE
104 for( k=0; k<arm_breakpoint_count; k++ ) {
105 if( arm_breakpoints[k].address == armr.r[15] ) {
107 if( arm_breakpoints[k].type == BREAK_ONESHOT )
108 arm_clear_breakpoint( armr.r[15], BREAK_ONESHOT );
115 k = MMIO_READ( AICA2, AICA_TCR );
117 uint8_t val = MMIO_READ( AICA2, AICA_TIMER );
120 aica_event( AICA_EVENT_TIMER );
121 MMIO_WRITE( AICA2, AICA_TCR, k & ~0x40 );
123 MMIO_WRITE( AICA2, AICA_TIMER, val );
125 if( !dreamcast_is_running() )
132 void arm_save_state( FILE *f )
134 fwrite( &armr, sizeof(armr), 1, f );
137 int arm_load_state( FILE *f )
139 fread( &armr, sizeof(armr), 1, f );
144 void arm_reset( void )
146 /* Wipe all processor state */
147 memset( &armr, 0, sizeof(armr) );
149 armr.cpsr = MODE_SVC | CPSR_I | CPSR_F;
150 armr.r[15] = 0x00000000;
154 #define SET_CPSR_CONTROL 0x00010000
155 #define SET_CPSR_EXTENSION 0x00020000
156 #define SET_CPSR_STATUS 0x00040000
157 #define SET_CPSR_FLAGS 0x00080000
159 uint32_t arm_get_cpsr( void )
161 /* write back all flags to the cpsr */
162 armr.cpsr = armr.cpsr & CPSR_COMPACT_MASK;
163 if( armr.n ) armr.cpsr |= CPSR_N;
164 if( armr.z ) armr.cpsr |= CPSR_Z;
165 if( armr.c ) armr.cpsr |= CPSR_C;
166 if( armr.v ) armr.cpsr |= CPSR_V;
167 if( armr.t ) armr.cpsr |= CPSR_T;
172 * Return a pointer to the specified register in the user bank,
173 * regardless of the active bank
175 static uint32_t *arm_user_reg( int reg )
177 if( IS_EXCEPTION_MODE() ) {
178 if( reg == 13 || reg == 14 )
179 return &armr.user_r[reg-8];
180 if( IS_FIQ_MODE() ) {
181 if( reg >= 8 || reg <= 12 )
182 return &armr.user_r[reg-8];
188 #define USER_R(n) *arm_user_reg(n)
191 * Set the CPSR to the specified value.
193 * @param value values to set in CPSR
194 * @param fields set of mask values to define which sections of the
195 * CPSR to set (one of the SET_CPSR_* values above)
197 void arm_set_cpsr( uint32_t value, uint32_t fields )
199 if( IS_PRIVILEGED_MODE() ) {
200 if( fields & SET_CPSR_CONTROL ) {
201 int mode = value & CPSR_MODE;
202 arm_set_mode( mode );
203 armr.t = ( value & CPSR_T ); /* Technically illegal to change */
204 armr.cpsr = (armr.cpsr & 0xFFFFFF00) | (value & 0x000000FF);
207 /* Middle 16 bits not currently defined */
209 if( fields & SET_CPSR_FLAGS ) {
210 /* Break flags directly out of given value - don't bother writing
213 armr.n = ( value & CPSR_N );
214 armr.z = ( value & CPSR_Z );
215 armr.c = ( value & CPSR_C );
216 armr.v = ( value & CPSR_V );
220 void arm_set_spsr( uint32_t value, uint32_t fields )
222 /* Only defined if we actually have an SPSR register */
223 if( IS_EXCEPTION_MODE() ) {
224 if( fields & SET_CPSR_CONTROL ) {
225 armr.spsr = (armr.spsr & 0xFFFFFF00) | (value & 0x000000FF);
228 /* Middle 16 bits not currently defined */
230 if( fields & SET_CPSR_FLAGS ) {
231 armr.spsr = (armr.spsr & 0x00FFFFFF) | (value & 0xFF000000);
237 * Raise an ARM exception (other than reset, which uses arm_reset().
238 * @param exception one of the EXC_* exception codes defined above.
240 void arm_raise_exception( int exception )
242 int mode = arm_exceptions[exception][0];
243 uint32_t spsr = arm_get_cpsr();
244 arm_set_mode( mode );
246 armr.r[14] = armr.r[15] + 4;
247 armr.cpsr = (spsr & 0xFFFFFF00) | mode | CPSR_I;
248 if( mode == MODE_FIQ )
250 armr.r[15] = arm_exceptions[exception][1];
253 void arm_restore_cpsr( void )
255 int spsr = armr.spsr;
256 int mode = spsr & CPSR_MODE;
257 arm_set_mode( mode );
259 armr.n = ( spsr & CPSR_N );
260 armr.z = ( spsr & CPSR_Z );
261 armr.c = ( spsr & CPSR_C );
262 armr.v = ( spsr & CPSR_V );
263 armr.t = ( spsr & CPSR_T );
269 * Change the current executing ARM mode to the requested mode.
270 * Saves any required registers to banks and restores those for the
271 * correct mode. (Note does not actually update CPSR at the moment).
273 void arm_set_mode( int targetMode )
275 int currentMode = armr.cpsr & CPSR_MODE;
276 if( currentMode == targetMode )
279 switch( currentMode ) {
282 armr.user_r[5] = armr.r[13];
283 armr.user_r[6] = armr.r[14];
286 armr.svc_r[0] = armr.r[13];
287 armr.svc_r[1] = armr.r[14];
288 armr.svc_r[2] = armr.spsr;
291 armr.abt_r[0] = armr.r[13];
292 armr.abt_r[1] = armr.r[14];
293 armr.abt_r[2] = armr.spsr;
296 armr.und_r[0] = armr.r[13];
297 armr.und_r[1] = armr.r[14];
298 armr.und_r[2] = armr.spsr;
301 armr.irq_r[0] = armr.r[13];
302 armr.irq_r[1] = armr.r[14];
303 armr.irq_r[2] = armr.spsr;
306 armr.fiq_r[0] = armr.r[8];
307 armr.fiq_r[1] = armr.r[9];
308 armr.fiq_r[2] = armr.r[10];
309 armr.fiq_r[3] = armr.r[11];
310 armr.fiq_r[4] = armr.r[12];
311 armr.fiq_r[5] = armr.r[13];
312 armr.fiq_r[6] = armr.r[14];
313 armr.fiq_r[7] = armr.spsr;
314 armr.r[8] = armr.user_r[0];
315 armr.r[9] = armr.user_r[1];
316 armr.r[10] = armr.user_r[2];
317 armr.r[11] = armr.user_r[3];
318 armr.r[12] = armr.user_r[4];
322 switch( targetMode ) {
325 armr.r[13] = armr.user_r[5];
326 armr.r[14] = armr.user_r[6];
329 armr.r[13] = armr.svc_r[0];
330 armr.r[14] = armr.svc_r[1];
331 armr.spsr = armr.svc_r[2];
334 armr.r[13] = armr.abt_r[0];
335 armr.r[14] = armr.abt_r[1];
336 armr.spsr = armr.abt_r[2];
339 armr.r[13] = armr.und_r[0];
340 armr.r[14] = armr.und_r[1];
341 armr.spsr = armr.und_r[2];
344 armr.r[13] = armr.irq_r[0];
345 armr.r[14] = armr.irq_r[1];
346 armr.spsr = armr.irq_r[2];
349 armr.user_r[0] = armr.r[8];
350 armr.user_r[1] = armr.r[9];
351 armr.user_r[2] = armr.r[10];
352 armr.user_r[3] = armr.r[11];
353 armr.user_r[4] = armr.r[12];
354 armr.r[8] = armr.fiq_r[0];
355 armr.r[9] = armr.fiq_r[1];
356 armr.r[10] = armr.fiq_r[2];
357 armr.r[11] = armr.fiq_r[3];
358 armr.r[12] = armr.fiq_r[4];
359 armr.r[13] = armr.fiq_r[5];
360 armr.r[14] = armr.fiq_r[6];
361 armr.spsr = armr.fiq_r[7];
366 /* Page references are as per ARM DDI 0100E (June 2000) */
368 #define MEM_READ_BYTE( addr ) arm_read_byte(addr)
369 #define MEM_READ_WORD( addr ) arm_read_word(addr)
370 #define MEM_READ_LONG( addr ) arm_read_long(addr)
371 #define MEM_WRITE_BYTE( addr, val ) arm_write_byte(addr, val)
372 #define MEM_WRITE_WORD( addr, val ) arm_write_word(addr, val)
373 #define MEM_WRITE_LONG( addr, val ) arm_write_long(addr, val)
376 #define IS_NOTBORROW( result, op1, op2 ) (op2 > op1 ? 0 : 1)
377 #define IS_CARRY( result, op1, op2 ) (result < op1 ? 1 : 0)
378 #define IS_SUBOVERFLOW( result, op1, op2 ) (((op1^op2) & (result^op1)) >> 31)
379 #define IS_ADDOVERFLOW( result, op1, op2 ) (((op1&op2) & (result^op1)) >> 31)
381 #define PC armr.r[15]
383 /* Instruction fields */
384 #define COND(ir) (ir>>28)
385 #define GRP(ir) ((ir>>26)&0x03)
386 #define OPCODE(ir) ((ir>>20)&0x1F)
387 #define IFLAG(ir) (ir&0x02000000)
388 #define SFLAG(ir) (ir&0x00100000)
389 #define PFLAG(ir) (ir&0x01000000)
390 #define UFLAG(ir) (ir&0x00800000)
391 #define BFLAG(ir) (ir&0x00400000)
392 #define WFLAG(ir) (ir&0x00200000)
393 #define LFLAG(ir) SFLAG(ir)
394 #define RN(ir) (armr.r[((ir>>16)&0x0F)] + (((ir>>16)&0x0F) == 0x0F ? 4 : 0))
395 #define RD(ir) (armr.r[((ir>>12)&0x0F)] + (((ir>>12)&0x0F) == 0x0F ? 4 : 0))
396 #define RDn(ir) ((ir>>12)&0x0F)
397 #define RS(ir) (armr.r[((ir>>8)&0x0F)] + (((ir>>8)&0x0F) == 0x0F ? 4 : 0))
398 #define RM(ir) (armr.r[(ir&0x0F)] + (((ir&0x0F) == 0x0F ? 4 : 0)) )
399 #define LRN(ir) armr.r[((ir>>16)&0x0F)]
400 #define LRD(ir) armr.r[((ir>>12)&0x0F)]
401 #define LRS(ir) armr.r[((ir>>8)&0x0F)]
402 #define LRM(ir) armr.r[(ir&0x0F)]
404 #define IMM8(ir) (ir&0xFF)
405 #define IMM12(ir) (ir&0xFFF)
406 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
407 #define IMMROT(ir) ((ir>>7)&0x1E)
408 #define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
409 #define SIGNEXT24(n) (((n)&0x00800000) ? ((n)|0xFF000000) : ((n)&0x00FFFFFF))
410 #define SHIFT(ir) ((ir>>4)&0x07)
411 #define DISP24(ir) ((ir&0x00FFFFFF))
412 #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)
413 #define UNIMP(ir) do{ PC-=4; ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", PC, ir ); dreamcast_stop(); return FALSE; }while(0)
416 * Determine the value of the shift-operand for a data processing instruction,
417 * without determing a value for shift_C (optimized form for instructions that
418 * don't require shift_C ).
419 * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
421 static uint32_t arm_get_shift_operand( uint32_t ir )
423 uint32_t operand, tmp;
424 if( IFLAG(ir) == 0 ) {
427 case 0: /* (Rm << imm) */
428 operand = operand << SHIFTIMM(ir);
430 case 1: /* (Rm << Rs) */
432 if( tmp > 31 ) operand = 0;
433 else operand = operand << tmp;
435 case 2: /* (Rm >> imm) */
436 operand = operand >> SHIFTIMM(ir);
438 case 3: /* (Rm >> Rs) */
440 if( tmp > 31 ) operand = 0;
441 else operand = operand >> ir;
443 case 4: /* (Rm >>> imm) */
445 if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
446 else operand = ((int32_t)operand) >> tmp;
448 case 5: /* (Rm >>> Rs) */
450 if( tmp > 31 ) operand = ((int32_t)operand) >> 31;
451 else operand = ((int32_t)operand) >> tmp;
455 if( tmp == 0 ) /* RRX aka rotate with carry */
456 operand = (operand >> 1) | (armr.c<<31);
458 operand = ROTATE_RIGHT_LONG(operand,tmp);
462 operand = ROTATE_RIGHT_LONG(operand,tmp);
468 operand = ROTATE_RIGHT_LONG(operand, tmp);
474 * Determine the value of the shift-operand for a data processing instruction,
475 * and set armr.shift_c accordingly.
476 * @see s5.1 Addressing Mode 1 - Data-processing operands (p A5-2, 218)
478 static uint32_t arm_get_shift_operand_s( uint32_t ir )
480 uint32_t operand, tmp;
481 if( IFLAG(ir) == 0 ) {
484 case 0: /* (Rm << imm) */
486 if( tmp == 0 ) { /* Rm */
487 armr.shift_c = armr.c;
488 } else { /* Rm << imm */
489 armr.shift_c = (operand >> (32-tmp)) & 0x01;
490 operand = operand << tmp;
493 case 1: /* (Rm << Rs) */
496 armr.shift_c = armr.c;
499 armr.shift_c = (operand >> (32-tmp)) & 0x01;
500 else armr.shift_c = 0;
502 operand = operand << tmp;
506 case 2: /* (Rm >> imm) */
509 armr.shift_c = operand >> 31;
512 armr.shift_c = (operand >> (tmp-1)) & 0x01;
513 operand = RM(ir) >> tmp;
516 case 3: /* (Rm >> Rs) */
519 armr.shift_c = armr.c;
522 armr.shift_c = (operand >> (tmp-1))&0x01;
523 else armr.shift_c = 0;
525 operand = operand >> tmp;
529 case 4: /* (Rm >>> imm) */
532 armr.shift_c = operand >> 31;
533 operand = -armr.shift_c;
535 armr.shift_c = (operand >> (tmp-1)) & 0x01;
536 operand = ((int32_t)operand) >> tmp;
539 case 5: /* (Rm >>> Rs) */
542 armr.shift_c = armr.c;
545 armr.shift_c = (operand >> (tmp-1))&0x01;
546 operand = ((int32_t)operand) >> tmp;
548 armr.shift_c = operand >> 31;
549 operand = ((int32_t)operand) >> 31;
555 if( tmp == 0 ) { /* RRX aka rotate with carry */
556 armr.shift_c = operand&0x01;
557 operand = (operand >> 1) | (armr.c<<31);
559 armr.shift_c = operand>>(tmp-1);
560 operand = ROTATE_RIGHT_LONG(operand,tmp);
566 armr.shift_c = armr.c;
570 armr.shift_c = operand>>31;
572 armr.shift_c = (operand>>(tmp-1))&0x1;
573 operand = ROTATE_RIGHT_LONG(operand,tmp);
582 armr.shift_c = armr.c;
584 operand = ROTATE_RIGHT_LONG(operand, tmp);
585 armr.shift_c = operand>>31;
592 * Another variant of the shifter code for index-based memory addressing.
593 * Distinguished by the fact that it doesn't support register shifts, and
594 * ignores the I flag (WTF do the load/store instructions use the I flag to
595 * mean the _exact opposite_ of what it means for the data processing
598 static uint32_t arm_get_address_index( uint32_t ir )
600 uint32_t operand = RM(ir);
604 case 0: /* (Rm << imm) */
605 operand = operand << SHIFTIMM(ir);
607 case 2: /* (Rm >> imm) */
608 operand = operand >> SHIFTIMM(ir);
610 case 4: /* (Rm >>> imm) */
612 if( tmp == 0 ) operand = ((int32_t)operand) >> 31;
613 else operand = ((int32_t)operand) >> tmp;
617 if( tmp == 0 ) /* RRX aka rotate with carry */
618 operand = (operand >> 1) | (armr.c<<31);
620 operand = ROTATE_RIGHT_LONG(operand,tmp);
628 * Determine the address operand of a load/store instruction, including
629 * applying any pre/post adjustments to the address registers.
630 * @see s5.2 Addressing Mode 2 - Load and Store Word or Unsigned Byte
631 * @param The instruction word.
632 * @return The calculated address
634 static uint32_t arm_get_address_operand( uint32_t ir )
639 switch( (ir>>21)&0x1D ) {
640 case 0: /* Rn -= imm offset (post-indexed) [5.2.8 A5-28] */
643 LRN(ir) = addr - IMM12(ir);
645 case 4: /* Rn += imm offsett (post-indexed) [5.2.8 A5-28] */
648 LRN(ir) = addr + IMM12(ir);
650 case 8: /* Rn - imm offset [5.2.2 A5-20] */
651 addr = RN(ir) - IMM12(ir);
653 case 9: /* Rn -= imm offset (pre-indexed) [5.2.5 A5-24] */
654 addr = RN(ir) - IMM12(ir);
657 case 12: /* Rn + imm offset [5.2.2 A5-20] */
658 addr = RN(ir) + IMM12(ir);
660 case 13: /* Rn += imm offset [5.2.5 A5-24 ] */
661 addr = RN(ir) + IMM12(ir);
664 case 16: /* Rn -= Rm (post-indexed) [5.2.10 A5-32 ] */
667 LRN(ir) = addr - arm_get_address_index(ir);
669 case 20: /* Rn += Rm (post-indexed) [5.2.10 A5-32 ] */
672 LRN(ir) = addr - arm_get_address_index(ir);
674 case 24: /* Rn - Rm [5.2.4 A5-23] */
675 addr = RN(ir) - arm_get_address_index(ir);
677 case 25: /* RN -= Rm (pre-indexed) [5.2.7 A5-26] */
678 addr = RN(ir) - arm_get_address_index(ir);
681 case 28: /* Rn + Rm [5.2.4 A5-23] */
682 addr = RN(ir) + arm_get_address_index(ir);
684 case 29: /* RN += Rm (pre-indexed) [5.2.7 A5-26] */
685 addr = RN(ir) + arm_get_address_index(ir);
692 gboolean arm_execute_instruction( void )
696 uint32_t operand, operand2, tmp, tmp2, cond;
699 tmp = armr.int_pending & (~armr.cpsr);
702 arm_raise_exception( EXC_FAST_IRQ );
704 arm_raise_exception( EXC_IRQ );
708 ir = MEM_READ_LONG(PC);
713 * Check the condition bits first - if the condition fails return
714 * immediately without actually looking at the rest of the instruction.
742 cond = armr.c && !armr.z;
745 cond = (!armr.c) || armr.z;
748 cond = (armr.n == armr.v);
751 cond = (armr.n != armr.v);
754 cond = (!armr.z) && (armr.n == armr.v);
757 cond = armr.z || (armr.n != armr.v);
770 * Condition passed, now for the actual instructions...
774 if( (ir & 0x0D900000) == 0x01000000 ) {
775 /* Instructions that aren't actual data processing even though
776 * they sit in the DP instruction block.
778 switch( ir & 0x0FF000F0 ) {
779 case 0x01200010: /* BX Rd */
781 armr.r[15] = RM(ir) & 0xFFFFFFFE;
783 case 0x01000000: /* MRS Rd, CPSR */
784 LRD(ir) = arm_get_cpsr();
786 case 0x01400000: /* MRS Rd, SPSR */
789 case 0x01200000: /* MSR CPSR, Rd */
790 arm_set_cpsr( RM(ir), ir );
792 case 0x01600000: /* MSR SPSR, Rd */
793 arm_set_spsr( RM(ir), ir );
795 case 0x03200000: /* MSR CPSR, imm */
796 arm_set_cpsr( ROTIMM12(ir), ir );
798 case 0x03600000: /* MSR SPSR, imm */
799 arm_set_spsr( ROTIMM12(ir), ir );
804 } else if( (ir & 0x0E000090) == 0x00000090 ) {
805 /* Neither are these */
806 switch( (ir>>5)&0x03 ) {
808 /* Arithmetic extension area */
811 LRN(ir) = RM(ir) * RS(ir);
814 tmp = RM(ir) * RS(ir);
820 LRN(ir) = RM(ir) * RS(ir) + RD(ir);
823 tmp = RM(ir) * RS(ir) + RD(ir);
831 case 11: /* UMLALS */
833 case 13: /* SMULLS */
835 case 15: /* SMLALS */
839 tmp = arm_read_long( RN(ir) );
840 switch( RN(ir) & 0x03 ) {
842 tmp = ROTATE_RIGHT_LONG(tmp, 8);
845 tmp = ROTATE_RIGHT_LONG(tmp, 16);
848 tmp = ROTATE_RIGHT_LONG(tmp, 24);
851 arm_write_long( RN(ir), RM(ir) );
855 tmp = arm_read_byte( RN(ir) );
856 arm_write_byte( RN(ir), RM(ir) );
887 /* Data processing */
890 case 0: /* AND Rd, Rn, operand */
891 LRD(ir) = RN(ir) & arm_get_shift_operand(ir);
893 case 1: /* ANDS Rd, Rn, operand */
894 operand = arm_get_shift_operand_s(ir) & RN(ir);
896 if( RDn(ir) == 15 ) {
899 armr.n = operand>>31;
900 armr.z = (operand == 0);
901 armr.c = armr.shift_c;
904 case 2: /* EOR Rd, Rn, operand */
905 LRD(ir) = RN(ir) ^ arm_get_shift_operand(ir);
907 case 3: /* EORS Rd, Rn, operand */
908 operand = arm_get_shift_operand_s(ir) ^ RN(ir);
910 if( RDn(ir) == 15 ) {
913 armr.n = operand>>31;
914 armr.z = (operand == 0);
915 armr.c = armr.shift_c;
918 case 4: /* SUB Rd, Rn, operand */
919 LRD(ir) = RN(ir) - arm_get_shift_operand(ir);
921 case 5: /* SUBS Rd, Rn, operand */
923 operand2 = arm_get_shift_operand(ir);
924 tmp = operand - operand2;
926 if( RDn(ir) == 15 ) {
931 armr.c = IS_NOTBORROW(tmp,operand,operand2);
932 armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
935 case 6: /* RSB Rd, operand, Rn */
936 LRD(ir) = arm_get_shift_operand(ir) - RN(ir);
938 case 7: /* RSBS Rd, operand, Rn */
939 operand = arm_get_shift_operand(ir);
941 tmp = operand - operand2;
943 if( RDn(ir) == 15 ) {
948 armr.c = IS_NOTBORROW(tmp,operand,operand2);
949 armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
952 case 8: /* ADD Rd, Rn, operand */
953 LRD(ir) = RN(ir) + arm_get_shift_operand(ir);
955 case 9: /* ADDS Rd, Rn, operand */
956 operand = arm_get_shift_operand(ir);
958 tmp = operand + operand2;
960 if( RDn(ir) == 15 ) {
965 armr.c = IS_CARRY(tmp,operand,operand2);
966 armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
970 LRD(ir) = RN(ir) + arm_get_shift_operand(ir) +
974 operand = arm_get_shift_operand(ir);
976 tmp = operand + operand2;
977 tmp2 = tmp + armr.c ? 1 : 0;
979 if( RDn(ir) == 15 ) {
983 armr.z = (tmp == 0 );
984 armr.c = IS_CARRY(tmp,operand,operand2) ||
986 armr.v = IS_ADDOVERFLOW(tmp,operand, operand2) ||
987 ((tmp&0x80000000) != (tmp2&0x80000000));
991 LRD(ir) = RN(ir) - arm_get_shift_operand(ir) -
996 operand2 = arm_get_shift_operand(ir);
997 tmp = operand - operand2;
998 tmp2 = tmp - (armr.c ? 0 : 1);
999 if( RDn(ir) == 15 ) {
1003 armr.z = (tmp == 0 );
1004 armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1006 armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1007 ((tmp&0x80000000) != (tmp2&0x80000000));
1011 LRD(ir) = arm_get_shift_operand(ir) - RN(ir) -
1015 operand = arm_get_shift_operand(ir);
1017 tmp = operand - operand2;
1018 tmp2 = tmp - (armr.c ? 0 : 1);
1019 if( RDn(ir) == 15 ) {
1023 armr.z = (tmp == 0 );
1024 armr.c = IS_NOTBORROW(tmp,operand,operand2) &&
1026 armr.v = IS_SUBOVERFLOW(tmp,operand,operand2) ||
1027 ((tmp&0x80000000) != (tmp2&0x80000000));
1030 case 17: /* TST Rn, operand */
1031 operand = arm_get_shift_operand_s(ir) & RN(ir);
1032 armr.n = operand>>31;
1033 armr.z = (operand == 0);
1034 armr.c = armr.shift_c;
1036 case 19: /* TEQ Rn, operand */
1037 operand = arm_get_shift_operand_s(ir) ^ RN(ir);
1038 armr.n = operand>>31;
1039 armr.z = (operand == 0);
1040 armr.c = armr.shift_c;
1042 case 21: /* CMP Rn, operand */
1044 operand2 = arm_get_shift_operand(ir);
1045 tmp = operand - operand2;
1047 armr.z = (tmp == 0);
1048 armr.c = IS_NOTBORROW(tmp,operand,operand2);
1049 armr.v = IS_SUBOVERFLOW(tmp,operand,operand2);
1051 case 23: /* CMN Rn, operand */
1053 operand2 = arm_get_shift_operand(ir);
1054 tmp = operand + operand2;
1056 armr.z = (tmp == 0);
1057 armr.c = IS_CARRY(tmp,operand,operand2);
1058 armr.v = IS_ADDOVERFLOW(tmp,operand,operand2);
1060 case 24: /* ORR Rd, Rn, operand */
1061 LRD(ir) = RN(ir) | arm_get_shift_operand(ir);
1063 case 25: /* ORRS Rd, Rn, operand */
1064 operand = arm_get_shift_operand_s(ir) | RN(ir);
1066 if( RDn(ir) == 15 ) {
1069 armr.n = operand>>31;
1070 armr.z = (operand == 0);
1071 armr.c = armr.shift_c;
1074 case 26: /* MOV Rd, operand */
1075 LRD(ir) = arm_get_shift_operand(ir);
1077 case 27: /* MOVS Rd, operand */
1078 operand = arm_get_shift_operand_s(ir);
1080 if( RDn(ir) == 15 ) {
1083 armr.n = operand>>31;
1084 armr.z = (operand == 0);
1085 armr.c = armr.shift_c;
1088 case 28: /* BIC Rd, Rn, operand */
1089 LRD(ir) = RN(ir) & (~arm_get_shift_operand(ir));
1091 case 29: /* BICS Rd, Rn, operand */
1092 operand = RN(ir) & (~arm_get_shift_operand_s(ir));
1094 if( RDn(ir) == 15 ) {
1097 armr.n = operand>>31;
1098 armr.z = (operand == 0);
1099 armr.c = armr.shift_c;
1102 case 30: /* MVN Rd, operand */
1103 LRD(ir) = ~arm_get_shift_operand(ir);
1105 case 31: /* MVNS Rd, operand */
1106 operand = ~arm_get_shift_operand_s(ir);
1108 if( RDn(ir) == 15 ) {
1111 armr.n = operand>>31;
1112 armr.z = (operand == 0);
1113 armr.c = armr.shift_c;
1121 case 1: /* Load/store */
1122 operand = arm_get_address_operand(ir);
1123 switch( (ir>>20)&0x17 ) {
1124 case 0: case 16: case 18: /* STR Rd, address */
1125 arm_write_long( operand, RD(ir) );
1127 case 1: case 17: case 19: /* LDR Rd, address */
1128 LRD(ir) = arm_read_long(operand);
1130 case 2: /* STRT Rd, address */
1131 arm_write_long_user( operand, RD(ir) );
1133 case 3: /* LDRT Rd, address */
1134 LRD(ir) = arm_read_long_user( operand );
1136 case 4: case 20: case 22: /* STRB Rd, address */
1137 arm_write_byte( operand, RD(ir) );
1139 case 5: case 21: case 23: /* LDRB Rd, address */
1140 LRD(ir) = arm_read_byte( operand );
1142 case 6: /* STRBT Rd, address */
1143 arm_write_byte_user( operand, RD(ir) );
1145 case 7: /* LDRBT Rd, address */
1146 LRD(ir) = arm_read_byte_user( operand );
1150 case 2: /* Load/store multiple, branch*/
1151 if( (ir & 0x02000000) == 0x02000000 ) { /* B[L] imm24 */
1152 operand = (SIGNEXT24(ir&0x00FFFFFF) << 2);
1153 if( (ir & 0x01000000) == 0x01000000 ) {
1154 armr.r[14] = pc; /* BL */
1156 armr.r[15] = pc + 4 + operand;
1157 } else { /* Load/store multiple */
1158 gboolean needRestore = FALSE;
1161 switch( (ir & 0x01D00000) >> 20 ) {
1164 arm_write_long( operand, armr.r[15]+4 );
1167 for( i=14; i>= 0; i-- ) {
1168 if( (ir & (1<<i)) ) {
1169 arm_write_long( operand, armr.r[i] );
1175 for( i=15; i>= 0; i-- ) {
1176 if( (ir & (1<<i)) ) {
1177 armr.r[i] = arm_read_long( operand );
1182 case 4: /* STMDA (S) */
1184 arm_write_long( operand, armr.r[15]+4 );
1187 for( i=14; i>= 0; i-- ) {
1188 if( (ir & (1<<i)) ) {
1189 arm_write_long( operand, USER_R(i) );
1194 case 5: /* LDMDA (S) */
1195 if( (ir&0x00008000) ) { /* Load PC */
1196 for( i=15; i>= 0; i-- ) {
1197 if( (ir & (1<<i)) ) {
1198 armr.r[i] = arm_read_long( operand );
1204 for( i=15; i>= 0; i-- ) {
1205 if( (ir & (1<<i)) ) {
1206 USER_R(i) = arm_read_long( operand );
1213 for( i=0; i< 15; i++ ) {
1214 if( (ir & (1<<i)) ) {
1215 arm_write_long( operand, armr.r[i] );
1220 arm_write_long( operand, armr.r[15]+4 );
1225 for( i=0; i< 16; i++ ) {
1226 if( (ir & (1<<i)) ) {
1227 armr.r[i] = arm_read_long( operand );
1232 case 12: /* STMIA (S) */
1233 for( i=0; i< 15; i++ ) {
1234 if( (ir & (1<<i)) ) {
1235 arm_write_long( operand, USER_R(i) );
1240 arm_write_long( operand, armr.r[15]+4 );
1244 case 13: /* LDMIA (S) */
1245 if( (ir&0x00008000) ) { /* Load PC */
1246 for( i=0; i < 16; i++ ) {
1247 if( (ir & (1<<i)) ) {
1248 armr.r[i] = arm_read_long( operand );
1254 for( i=0; i < 16; i++ ) {
1255 if( (ir & (1<<i)) ) {
1256 USER_R(i) = arm_read_long( operand );
1262 case 16: /* STMDB */
1265 arm_write_long( operand, armr.r[15]+4 );
1267 for( i=14; i>= 0; i-- ) {
1268 if( (ir & (1<<i)) ) {
1270 arm_write_long( operand, armr.r[i] );
1274 case 17: /* LDMDB */
1275 for( i=15; i>= 0; i-- ) {
1276 if( (ir & (1<<i)) ) {
1278 armr.r[i] = arm_read_long( operand );
1282 case 20: /* STMDB (S) */
1285 arm_write_long( operand, armr.r[15]+4 );
1287 for( i=14; i>= 0; i-- ) {
1288 if( (ir & (1<<i)) ) {
1290 arm_write_long( operand, USER_R(i) );
1294 case 21: /* LDMDB (S) */
1295 if( (ir&0x00008000) ) { /* Load PC */
1296 for( i=15; i>= 0; i-- ) {
1297 if( (ir & (1<<i)) ) {
1299 armr.r[i] = arm_read_long( operand );
1304 for( i=15; i>= 0; i-- ) {
1305 if( (ir & (1<<i)) ) {
1307 USER_R(i) = arm_read_long( operand );
1312 case 24: /* STMIB */
1313 for( i=0; i< 15; i++ ) {
1314 if( (ir & (1<<i)) ) {
1316 arm_write_long( operand, armr.r[i] );
1321 arm_write_long( operand, armr.r[15]+4 );
1324 case 25: /* LDMIB */
1325 for( i=0; i< 16; i++ ) {
1326 if( (ir & (1<<i)) ) {
1328 armr.r[i] = arm_read_long( operand );
1332 case 28: /* STMIB (S) */
1333 for( i=0; i< 15; i++ ) {
1334 if( (ir & (1<<i)) ) {
1336 arm_write_long( operand, USER_R(i) );
1341 arm_write_long( operand, armr.r[15]+4 );
1344 case 29: /* LDMIB (S) */
1345 if( (ir&0x00008000) ) { /* Load PC */
1346 for( i=0; i < 16; i++ ) {
1347 if( (ir & (1<<i)) ) {
1349 armr.r[i] = arm_read_long( operand );
1354 for( i=0; i < 16; i++ ) {
1355 if( (ir & (1<<i)) ) {
1357 USER_R(i) = arm_read_long( operand );
1371 if( (ir & 0x0F000000) == 0x0F000000 ) { /* SWI */
1372 arm_raise_exception( EXC_SOFTWARE );
1381 if( armr.r[15] >= 0x00200000 ) {
1382 armr.running = FALSE;
1383 WARN( "ARM Halted: BRANCH to invalid address %08X at %08X", armr.r[15], pc );
.