filename | src/sh4/sh4core.c |
changeset | 740:dd11269ee48b |
prev | 736:a02d1475ccfd |
author | nkeynes |
date | Sat Jul 19 02:34:11 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Fix make clean target And therefore (finally) fix the distcheck target overall |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * SH4 emulation core, and parent module for all the SH4 peripheral
5 * modules.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #define MODULE sh4_module
21 #include <assert.h>
22 #include <math.h>
23 #include "dream.h"
24 #include "dreamcast.h"
25 #include "eventq.h"
26 #include "mem.h"
27 #include "clock.h"
28 #include "syscall.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4mmio.h"
31 #include "sh4/sh4stat.h"
32 #include "sh4/intc.h"
34 #define SH4_CALLTRACE 1
36 #define MAX_INT 0x7FFFFFFF
37 #define MIN_INT 0x80000000
38 #define MAX_INTF 2147483647.0
39 #define MIN_INTF -2147483648.0
41 /********************** SH4 Module Definition ****************************/
43 uint32_t sh4_emulate_run_slice( uint32_t nanosecs )
44 {
45 int i;
47 if( sh4_breakpoint_count == 0 ) {
48 for( ; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
49 if( SH4_EVENT_PENDING() ) {
50 if( sh4r.event_types & PENDING_EVENT ) {
51 event_execute();
52 }
53 /* Eventq execute may (quite likely) deliver an immediate IRQ */
54 if( sh4r.event_types & PENDING_IRQ ) {
55 sh4_accept_interrupt();
56 }
57 }
58 if( !sh4_execute_instruction() ) {
59 break;
60 }
61 }
62 } else {
63 for( ;sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {
64 if( SH4_EVENT_PENDING() ) {
65 if( sh4r.event_types & PENDING_EVENT ) {
66 event_execute();
67 }
68 /* Eventq execute may (quite likely) deliver an immediate IRQ */
69 if( sh4r.event_types & PENDING_IRQ ) {
70 sh4_accept_interrupt();
71 }
72 }
74 if( !sh4_execute_instruction() )
75 break;
76 #ifdef ENABLE_DEBUG_MODE
77 for( i=0; i<sh4_breakpoint_count; i++ ) {
78 if( sh4_breakpoints[i].address == sh4r.pc ) {
79 break;
80 }
81 }
82 if( i != sh4_breakpoint_count ) {
83 sh4_core_exit( CORE_EXIT_BREAKPOINT );
84 }
85 #endif
86 }
87 }
89 /* If we aborted early, but the cpu is still technically running,
90 * we're doing a hard abort - cut the timeslice back to what we
91 * actually executed
92 */
93 if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {
94 nanosecs = sh4r.slice_cycle;
95 }
96 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
97 TMU_run_slice( nanosecs );
98 SCIF_run_slice( nanosecs );
99 }
100 return nanosecs;
101 }
103 /********************** SH4 emulation core ****************************/
105 #define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)
106 #define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }while(0)
108 #if(SH4_CALLTRACE == 1)
109 #define MAX_CALLSTACK 32
110 static struct call_stack {
111 sh4addr_t call_addr;
112 sh4addr_t target_addr;
113 sh4addr_t stack_pointer;
114 } call_stack[MAX_CALLSTACK];
116 static int call_stack_depth = 0;
117 int sh4_call_trace_on = 0;
119 static inline void trace_call( sh4addr_t source, sh4addr_t dest )
120 {
121 if( call_stack_depth < MAX_CALLSTACK ) {
122 call_stack[call_stack_depth].call_addr = source;
123 call_stack[call_stack_depth].target_addr = dest;
124 call_stack[call_stack_depth].stack_pointer = sh4r.r[15];
125 }
126 call_stack_depth++;
127 }
129 static inline void trace_return( sh4addr_t source, sh4addr_t dest )
130 {
131 if( call_stack_depth > 0 ) {
132 call_stack_depth--;
133 }
134 }
136 void fprint_stack_trace( FILE *f )
137 {
138 int i = call_stack_depth -1;
139 if( i >= MAX_CALLSTACK )
140 i = MAX_CALLSTACK - 1;
141 for( ; i >= 0; i-- ) {
142 fprintf( f, "%d. Call from %08X => %08X, SP=%08X\n",
143 (call_stack_depth - i), call_stack[i].call_addr,
144 call_stack[i].target_addr, call_stack[i].stack_pointer );
145 }
146 }
148 #define TRACE_CALL( source, dest ) trace_call(source, dest)
149 #define TRACE_RETURN( source, dest ) trace_return(source, dest)
150 #else
151 #define TRACE_CALL( dest, rts )
152 #define TRACE_RETURN( source, dest )
153 #endif
155 #define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )
156 #define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )
157 #define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )
158 #define CHECKRALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )
159 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
160 #define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
161 #define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )
163 #define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }
164 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }
165 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
167 #define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }
168 #define MEM_READ_WORD( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_word(memtmp); }
169 #define MEM_READ_LONG( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_long(memtmp); }
170 #define MEM_WRITE_BYTE( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_byte(memtmp, val); }
171 #define MEM_WRITE_WORD( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_word(memtmp, val); }
172 #define MEM_WRITE_LONG( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_long(memtmp, val); }
174 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
176 #define MEM_FP_READ( addr, reg ) \
177 if( IS_FPU_DOUBLESIZE() ) { \
178 CHECKRALIGN64(addr); \
179 memtmp = mmu_vma_to_phys_read(addr); \
180 if( memtmp == MMU_VMA_ERROR ) { \
181 return TRUE; \
182 } else { \
183 if( reg & 1 ) { \
184 *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(memtmp); \
185 *((uint32_t *)&XF(reg)) = sh4_read_long(memtmp+4); \
186 } else { \
187 *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
188 *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(memtmp+4); \
189 } \
190 } \
191 } else { \
192 CHECKRALIGN32(addr); \
193 memtmp = mmu_vma_to_phys_read(addr); \
194 if( memtmp == MMU_VMA_ERROR ) { \
195 return TRUE; \
196 } else { \
197 *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
198 } \
199 }
200 #define MEM_FP_WRITE( addr, reg ) \
201 if( IS_FPU_DOUBLESIZE() ) { \
202 CHECKWALIGN64(addr); \
203 memtmp = mmu_vma_to_phys_write(addr); \
204 if( memtmp == MMU_VMA_ERROR ) { \
205 return TRUE; \
206 } else { \
207 if( reg & 1 ) { \
208 sh4_write_long( memtmp, *((uint32_t *)&XF((reg)&0x0E)) ); \
209 sh4_write_long( memtmp+4, *((uint32_t *)&XF(reg)) ); \
210 } else { \
211 sh4_write_long( memtmp, *((uint32_t *)&FR(reg)) ); \
212 sh4_write_long( memtmp+4, *((uint32_t *)&FR((reg)|0x01)) ); \
213 } \
214 } \
215 } else { \
216 CHECKWALIGN32(addr); \
217 memtmp = mmu_vma_to_phys_write(addr); \
218 if( memtmp == MMU_VMA_ERROR ) { \
219 return TRUE; \
220 } else { \
221 sh4_write_long( memtmp, *((uint32_t *)&FR((reg))) ); \
222 } \
223 }
225 gboolean sh4_execute_instruction( void )
226 {
227 uint32_t pc;
228 unsigned short ir;
229 uint32_t tmp;
230 float ftmp;
231 double dtmp;
232 int64_t memtmp; // temporary holder for memory reads
234 #define R0 sh4r.r[0]
235 pc = sh4r.pc;
236 if( pc > 0xFFFFFF00 ) {
237 /* SYSCALL Magic */
238 syscall_invoke( pc );
239 sh4r.in_delay_slot = 0;
240 pc = sh4r.pc = sh4r.pr;
241 sh4r.new_pc = sh4r.pc + 2;
242 return TRUE;
243 }
244 CHECKRALIGN16(pc);
246 #ifdef ENABLE_SH4STATS
247 sh4_stats_add_by_pc(sh4r.pc);
248 #endif
250 /* Read instruction */
251 if( !IS_IN_ICACHE(pc) ) {
252 if( !mmu_update_icache(pc) ) {
253 // Fault - look for the fault handler
254 if( !mmu_update_icache(sh4r.pc) ) {
255 // double fault - halt
256 ERROR( "Double fault - halting" );
257 sh4_core_exit(CORE_EXIT_HALT);
258 return FALSE;
259 }
260 }
261 pc = sh4r.pc;
262 }
263 assert( IS_IN_ICACHE(pc) );
264 ir = *(uint16_t *)GET_ICACHE_PTR(sh4r.pc);
265 switch( (ir&0xF000) >> 12 ) {
266 case 0x0:
267 switch( ir&0xF ) {
268 case 0x2:
269 switch( (ir&0x80) >> 7 ) {
270 case 0x0:
271 switch( (ir&0x70) >> 4 ) {
272 case 0x0:
273 { /* STC SR, Rn */
274 uint32_t Rn = ((ir>>8)&0xF);
275 CHECKPRIV();
276 sh4r.r[Rn] = sh4_read_sr();
277 }
278 break;
279 case 0x1:
280 { /* STC GBR, Rn */
281 uint32_t Rn = ((ir>>8)&0xF);
282 sh4r.r[Rn] = sh4r.gbr;
283 }
284 break;
285 case 0x2:
286 { /* STC VBR, Rn */
287 uint32_t Rn = ((ir>>8)&0xF);
288 CHECKPRIV();
289 sh4r.r[Rn] = sh4r.vbr;
290 }
291 break;
292 case 0x3:
293 { /* STC SSR, Rn */
294 uint32_t Rn = ((ir>>8)&0xF);
295 CHECKPRIV();
296 sh4r.r[Rn] = sh4r.ssr;
297 }
298 break;
299 case 0x4:
300 { /* STC SPC, Rn */
301 uint32_t Rn = ((ir>>8)&0xF);
302 CHECKPRIV();
303 sh4r.r[Rn] = sh4r.spc;
304 }
305 break;
306 default:
307 UNDEF();
308 break;
309 }
310 break;
311 case 0x1:
312 { /* STC Rm_BANK, Rn */
313 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
314 CHECKPRIV();
315 sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];
316 }
317 break;
318 }
319 break;
320 case 0x3:
321 switch( (ir&0xF0) >> 4 ) {
322 case 0x0:
323 { /* BSRF Rn */
324 uint32_t Rn = ((ir>>8)&0xF);
325 CHECKSLOTILLEGAL();
326 CHECKDEST( pc + 4 + sh4r.r[Rn] );
327 sh4r.in_delay_slot = 1;
328 sh4r.pr = sh4r.pc + 4;
329 sh4r.pc = sh4r.new_pc;
330 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
331 TRACE_CALL( pc, sh4r.new_pc );
332 return TRUE;
333 }
334 break;
335 case 0x2:
336 { /* BRAF Rn */
337 uint32_t Rn = ((ir>>8)&0xF);
338 CHECKSLOTILLEGAL();
339 CHECKDEST( pc + 4 + sh4r.r[Rn] );
340 sh4r.in_delay_slot = 1;
341 sh4r.pc = sh4r.new_pc;
342 sh4r.new_pc = pc + 4 + sh4r.r[Rn];
343 return TRUE;
344 }
345 break;
346 case 0x8:
347 { /* PREF @Rn */
348 uint32_t Rn = ((ir>>8)&0xF);
349 tmp = sh4r.r[Rn];
350 if( (tmp & 0xFC000000) == 0xE0000000 ) {
351 sh4_flush_store_queue(tmp);
352 }
353 }
354 break;
355 case 0x9:
356 { /* OCBI @Rn */
357 uint32_t Rn = ((ir>>8)&0xF);
358 }
359 break;
360 case 0xA:
361 { /* OCBP @Rn */
362 uint32_t Rn = ((ir>>8)&0xF);
363 }
364 break;
365 case 0xB:
366 { /* OCBWB @Rn */
367 uint32_t Rn = ((ir>>8)&0xF);
368 }
369 break;
370 case 0xC:
371 { /* MOVCA.L R0, @Rn */
372 uint32_t Rn = ((ir>>8)&0xF);
373 tmp = sh4r.r[Rn];
374 CHECKWALIGN32(tmp);
375 MEM_WRITE_LONG( tmp, R0 );
376 }
377 break;
378 default:
379 UNDEF();
380 break;
381 }
382 break;
383 case 0x4:
384 { /* MOV.B Rm, @(R0, Rn) */
385 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
386 MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] );
387 }
388 break;
389 case 0x5:
390 { /* MOV.W Rm, @(R0, Rn) */
391 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
392 CHECKWALIGN16( R0 + sh4r.r[Rn] );
393 MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );
394 }
395 break;
396 case 0x6:
397 { /* MOV.L Rm, @(R0, Rn) */
398 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
399 CHECKWALIGN32( R0 + sh4r.r[Rn] );
400 MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );
401 }
402 break;
403 case 0x7:
404 { /* MUL.L Rm, Rn */
405 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
406 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
407 (sh4r.r[Rm] * sh4r.r[Rn]);
408 }
409 break;
410 case 0x8:
411 switch( (ir&0xFF0) >> 4 ) {
412 case 0x0:
413 { /* CLRT */
414 sh4r.t = 0;
415 }
416 break;
417 case 0x1:
418 { /* SETT */
419 sh4r.t = 1;
420 }
421 break;
422 case 0x2:
423 { /* CLRMAC */
424 sh4r.mac = 0;
425 }
426 break;
427 case 0x3:
428 { /* LDTLB */
429 MMU_ldtlb();
430 }
431 break;
432 case 0x4:
433 { /* CLRS */
434 sh4r.s = 0;
435 }
436 break;
437 case 0x5:
438 { /* SETS */
439 sh4r.s = 1;
440 }
441 break;
442 default:
443 UNDEF();
444 break;
445 }
446 break;
447 case 0x9:
448 switch( (ir&0xF0) >> 4 ) {
449 case 0x0:
450 { /* NOP */
451 /* NOP */
452 }
453 break;
454 case 0x1:
455 { /* DIV0U */
456 sh4r.m = sh4r.q = sh4r.t = 0;
457 }
458 break;
459 case 0x2:
460 { /* MOVT Rn */
461 uint32_t Rn = ((ir>>8)&0xF);
462 sh4r.r[Rn] = sh4r.t;
463 }
464 break;
465 default:
466 UNDEF();
467 break;
468 }
469 break;
470 case 0xA:
471 switch( (ir&0xF0) >> 4 ) {
472 case 0x0:
473 { /* STS MACH, Rn */
474 uint32_t Rn = ((ir>>8)&0xF);
475 sh4r.r[Rn] = (sh4r.mac>>32);
476 }
477 break;
478 case 0x1:
479 { /* STS MACL, Rn */
480 uint32_t Rn = ((ir>>8)&0xF);
481 sh4r.r[Rn] = (uint32_t)sh4r.mac;
482 }
483 break;
484 case 0x2:
485 { /* STS PR, Rn */
486 uint32_t Rn = ((ir>>8)&0xF);
487 sh4r.r[Rn] = sh4r.pr;
488 }
489 break;
490 case 0x3:
491 { /* STC SGR, Rn */
492 uint32_t Rn = ((ir>>8)&0xF);
493 CHECKPRIV();
494 sh4r.r[Rn] = sh4r.sgr;
495 }
496 break;
497 case 0x5:
498 { /* STS FPUL, Rn */
499 uint32_t Rn = ((ir>>8)&0xF);
500 CHECKFPUEN();
501 sh4r.r[Rn] = FPULi;
502 }
503 break;
504 case 0x6:
505 { /* STS FPSCR, Rn */
506 uint32_t Rn = ((ir>>8)&0xF);
507 CHECKFPUEN();
508 sh4r.r[Rn] = sh4r.fpscr;
509 }
510 break;
511 case 0xF:
512 { /* STC DBR, Rn */
513 uint32_t Rn = ((ir>>8)&0xF);
514 CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;
515 }
516 break;
517 default:
518 UNDEF();
519 break;
520 }
521 break;
522 case 0xB:
523 switch( (ir&0xFF0) >> 4 ) {
524 case 0x0:
525 { /* RTS */
526 CHECKSLOTILLEGAL();
527 CHECKDEST( sh4r.pr );
528 sh4r.in_delay_slot = 1;
529 sh4r.pc = sh4r.new_pc;
530 sh4r.new_pc = sh4r.pr;
531 TRACE_RETURN( pc, sh4r.new_pc );
532 return TRUE;
533 }
534 break;
535 case 0x1:
536 { /* SLEEP */
537 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
538 sh4r.sh4_state = SH4_STATE_STANDBY;
539 } else {
540 sh4r.sh4_state = SH4_STATE_SLEEP;
541 }
542 return FALSE; /* Halt CPU */
543 }
544 break;
545 case 0x2:
546 { /* RTE */
547 CHECKPRIV();
548 CHECKDEST( sh4r.spc );
549 CHECKSLOTILLEGAL();
550 sh4r.in_delay_slot = 1;
551 sh4r.pc = sh4r.new_pc;
552 sh4r.new_pc = sh4r.spc;
553 sh4_write_sr( sh4r.ssr );
554 return TRUE;
555 }
556 break;
557 default:
558 UNDEF();
559 break;
560 }
561 break;
562 case 0xC:
563 { /* MOV.B @(R0, Rm), Rn */
564 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
565 MEM_READ_BYTE( R0 + sh4r.r[Rm], sh4r.r[Rn] );
566 }
567 break;
568 case 0xD:
569 { /* MOV.W @(R0, Rm), Rn */
570 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
571 CHECKRALIGN16( R0 + sh4r.r[Rm] );
572 MEM_READ_WORD( R0 + sh4r.r[Rm], sh4r.r[Rn] );
573 }
574 break;
575 case 0xE:
576 { /* MOV.L @(R0, Rm), Rn */
577 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
578 CHECKRALIGN32( R0 + sh4r.r[Rm] );
579 MEM_READ_LONG( R0 + sh4r.r[Rm], sh4r.r[Rn] );
580 }
581 break;
582 case 0xF:
583 { /* MAC.L @Rm+, @Rn+ */
584 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
585 int64_t tmpl;
586 if( Rm == Rn ) {
587 CHECKRALIGN32( sh4r.r[Rn] );
588 MEM_READ_LONG(sh4r.r[Rn], tmp);
589 tmpl = SIGNEXT32(tmp);
590 MEM_READ_LONG(sh4r.r[Rn]+4, tmp);
591 tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
592 sh4r.r[Rn] += 8;
593 } else {
594 CHECKRALIGN32( sh4r.r[Rm] );
595 CHECKRALIGN32( sh4r.r[Rn] );
596 MEM_READ_LONG(sh4r.r[Rn], tmp);
597 tmpl = SIGNEXT32(tmp);
598 MEM_READ_LONG(sh4r.r[Rm], tmp);
599 tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
600 sh4r.r[Rn] += 4;
601 sh4r.r[Rm] += 4;
602 }
603 if( sh4r.s ) {
604 /* 48-bit Saturation. Yuch */
605 if( tmpl < (int64_t)0xFFFF800000000000LL )
606 tmpl = 0xFFFF800000000000LL;
607 else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )
608 tmpl = 0x00007FFFFFFFFFFFLL;
609 }
610 sh4r.mac = tmpl;
611 }
612 break;
613 default:
614 UNDEF();
615 break;
616 }
617 break;
618 case 0x1:
619 { /* MOV.L Rm, @(disp, Rn) */
620 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
621 tmp = sh4r.r[Rn] + disp;
622 CHECKWALIGN32( tmp );
623 MEM_WRITE_LONG( tmp, sh4r.r[Rm] );
624 }
625 break;
626 case 0x2:
627 switch( ir&0xF ) {
628 case 0x0:
629 { /* MOV.B Rm, @Rn */
630 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
631 MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
632 }
633 break;
634 case 0x1:
635 { /* MOV.W Rm, @Rn */
636 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
637 CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
638 }
639 break;
640 case 0x2:
641 { /* MOV.L Rm, @Rn */
642 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
643 CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
644 }
645 break;
646 case 0x4:
647 { /* MOV.B Rm, @-Rn */
648 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
649 MEM_WRITE_BYTE( sh4r.r[Rn]-1, sh4r.r[Rm] ); sh4r.r[Rn]--;
650 }
651 break;
652 case 0x5:
653 { /* MOV.W Rm, @-Rn */
654 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
655 CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn]-2, sh4r.r[Rm] ); sh4r.r[Rn] -= 2;
656 }
657 break;
658 case 0x6:
659 { /* MOV.L Rm, @-Rn */
660 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
661 CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r[Rm] ); sh4r.r[Rn] -= 4;
662 }
663 break;
664 case 0x7:
665 { /* DIV0S Rm, Rn */
666 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
667 sh4r.q = sh4r.r[Rn]>>31;
668 sh4r.m = sh4r.r[Rm]>>31;
669 sh4r.t = sh4r.q ^ sh4r.m;
670 }
671 break;
672 case 0x8:
673 { /* TST Rm, Rn */
674 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
675 sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);
676 }
677 break;
678 case 0x9:
679 { /* AND Rm, Rn */
680 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
681 sh4r.r[Rn] &= sh4r.r[Rm];
682 }
683 break;
684 case 0xA:
685 { /* XOR Rm, Rn */
686 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
687 sh4r.r[Rn] ^= sh4r.r[Rm];
688 }
689 break;
690 case 0xB:
691 { /* OR Rm, Rn */
692 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
693 sh4r.r[Rn] |= sh4r.r[Rm];
694 }
695 break;
696 case 0xC:
697 { /* CMP/STR Rm, Rn */
698 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
699 /* set T = 1 if any byte in RM & RN is the same */
700 tmp = sh4r.r[Rm] ^ sh4r.r[Rn];
701 sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||
702 (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;
703 }
704 break;
705 case 0xD:
706 { /* XTRCT Rm, Rn */
707 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
708 sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16);
709 }
710 break;
711 case 0xE:
712 { /* MULU.W Rm, Rn */
713 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
714 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
715 (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));
716 }
717 break;
718 case 0xF:
719 { /* MULS.W Rm, Rn */
720 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
721 sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |
722 (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));
723 }
724 break;
725 default:
726 UNDEF();
727 break;
728 }
729 break;
730 case 0x3:
731 switch( ir&0xF ) {
732 case 0x0:
733 { /* CMP/EQ Rm, Rn */
734 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
735 sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 );
736 }
737 break;
738 case 0x2:
739 { /* CMP/HS Rm, Rn */
740 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
741 sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 );
742 }
743 break;
744 case 0x3:
745 { /* CMP/GE Rm, Rn */
746 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
747 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
748 }
749 break;
750 case 0x4:
751 { /* DIV1 Rm, Rn */
752 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
753 /* This is derived from the sh4 manual with some simplifications */
754 uint32_t tmp0, tmp1, tmp2, dir;
756 dir = sh4r.q ^ sh4r.m;
757 sh4r.q = (sh4r.r[Rn] >> 31);
758 tmp2 = sh4r.r[Rm];
759 sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;
760 tmp0 = sh4r.r[Rn];
761 if( dir ) {
762 sh4r.r[Rn] += tmp2;
763 tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );
764 } else {
765 sh4r.r[Rn] -= tmp2;
766 tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );
767 }
768 sh4r.q ^= sh4r.m ^ tmp1;
769 sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );
770 }
771 break;
772 case 0x5:
773 { /* DMULU.L Rm, Rn */
774 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
775 sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]);
776 }
777 break;
778 case 0x6:
779 { /* CMP/HI Rm, Rn */
780 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
781 sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 );
782 }
783 break;
784 case 0x7:
785 { /* CMP/GT Rm, Rn */
786 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
787 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 );
788 }
789 break;
790 case 0x8:
791 { /* SUB Rm, Rn */
792 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
793 sh4r.r[Rn] -= sh4r.r[Rm];
794 }
795 break;
796 case 0xA:
797 { /* SUBC Rm, Rn */
798 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
799 tmp = sh4r.r[Rn];
800 sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;
801 sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));
802 }
803 break;
804 case 0xB:
805 UNIMP(ir); /* SUBV Rm, Rn */
806 break;
807 case 0xC:
808 { /* ADD Rm, Rn */
809 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
810 sh4r.r[Rn] += sh4r.r[Rm];
811 }
812 break;
813 case 0xD:
814 { /* DMULS.L Rm, Rn */
815 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
816 sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]);
817 }
818 break;
819 case 0xE:
820 { /* ADDC Rm, Rn */
821 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
822 tmp = sh4r.r[Rn];
823 sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;
824 sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );
825 }
826 break;
827 case 0xF:
828 { /* ADDV Rm, Rn */
829 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
830 tmp = sh4r.r[Rn] + sh4r.r[Rm];
831 sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );
832 sh4r.r[Rn] = tmp;
833 }
834 break;
835 default:
836 UNDEF();
837 break;
838 }
839 break;
840 case 0x4:
841 switch( ir&0xF ) {
842 case 0x0:
843 switch( (ir&0xF0) >> 4 ) {
844 case 0x0:
845 { /* SHLL Rn */
846 uint32_t Rn = ((ir>>8)&0xF);
847 sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;
848 }
849 break;
850 case 0x1:
851 { /* DT Rn */
852 uint32_t Rn = ((ir>>8)&0xF);
853 sh4r.r[Rn] --;
854 sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );
855 }
856 break;
857 case 0x2:
858 { /* SHAL Rn */
859 uint32_t Rn = ((ir>>8)&0xF);
860 sh4r.t = sh4r.r[Rn] >> 31;
861 sh4r.r[Rn] <<= 1;
862 }
863 break;
864 default:
865 UNDEF();
866 break;
867 }
868 break;
869 case 0x1:
870 switch( (ir&0xF0) >> 4 ) {
871 case 0x0:
872 { /* SHLR Rn */
873 uint32_t Rn = ((ir>>8)&0xF);
874 sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;
875 }
876 break;
877 case 0x1:
878 { /* CMP/PZ Rn */
879 uint32_t Rn = ((ir>>8)&0xF);
880 sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );
881 }
882 break;
883 case 0x2:
884 { /* SHAR Rn */
885 uint32_t Rn = ((ir>>8)&0xF);
886 sh4r.t = sh4r.r[Rn] & 0x00000001;
887 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;
888 }
889 break;
890 default:
891 UNDEF();
892 break;
893 }
894 break;
895 case 0x2:
896 switch( (ir&0xF0) >> 4 ) {
897 case 0x0:
898 { /* STS.L MACH, @-Rn */
899 uint32_t Rn = ((ir>>8)&0xF);
900 CHECKWALIGN32( sh4r.r[Rn] );
901 MEM_WRITE_LONG( sh4r.r[Rn]-4, (sh4r.mac>>32) );
902 sh4r.r[Rn] -= 4;
903 }
904 break;
905 case 0x1:
906 { /* STS.L MACL, @-Rn */
907 uint32_t Rn = ((ir>>8)&0xF);
908 CHECKWALIGN32( sh4r.r[Rn] );
909 MEM_WRITE_LONG( sh4r.r[Rn]-4, (uint32_t)sh4r.mac );
910 sh4r.r[Rn] -= 4;
911 }
912 break;
913 case 0x2:
914 { /* STS.L PR, @-Rn */
915 uint32_t Rn = ((ir>>8)&0xF);
916 CHECKWALIGN32( sh4r.r[Rn] );
917 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.pr );
918 sh4r.r[Rn] -= 4;
919 }
920 break;
921 case 0x3:
922 { /* STC.L SGR, @-Rn */
923 uint32_t Rn = ((ir>>8)&0xF);
924 CHECKPRIV();
925 CHECKWALIGN32( sh4r.r[Rn] );
926 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.sgr );
927 sh4r.r[Rn] -= 4;
928 }
929 break;
930 case 0x5:
931 { /* STS.L FPUL, @-Rn */
932 uint32_t Rn = ((ir>>8)&0xF);
933 CHECKFPUEN();
934 CHECKWALIGN32( sh4r.r[Rn] );
935 MEM_WRITE_LONG( sh4r.r[Rn]-4, FPULi );
936 sh4r.r[Rn] -= 4;
937 }
938 break;
939 case 0x6:
940 { /* STS.L FPSCR, @-Rn */
941 uint32_t Rn = ((ir>>8)&0xF);
942 CHECKFPUEN();
943 CHECKWALIGN32( sh4r.r[Rn] );
944 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.fpscr );
945 sh4r.r[Rn] -= 4;
946 }
947 break;
948 case 0xF:
949 { /* STC.L DBR, @-Rn */
950 uint32_t Rn = ((ir>>8)&0xF);
951 CHECKPRIV();
952 CHECKWALIGN32( sh4r.r[Rn] );
953 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.dbr );
954 sh4r.r[Rn] -= 4;
955 }
956 break;
957 default:
958 UNDEF();
959 break;
960 }
961 break;
962 case 0x3:
963 switch( (ir&0x80) >> 7 ) {
964 case 0x0:
965 switch( (ir&0x70) >> 4 ) {
966 case 0x0:
967 { /* STC.L SR, @-Rn */
968 uint32_t Rn = ((ir>>8)&0xF);
969 CHECKPRIV();
970 CHECKWALIGN32( sh4r.r[Rn] );
971 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4_read_sr() );
972 sh4r.r[Rn] -= 4;
973 }
974 break;
975 case 0x1:
976 { /* STC.L GBR, @-Rn */
977 uint32_t Rn = ((ir>>8)&0xF);
978 CHECKWALIGN32( sh4r.r[Rn] );
979 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.gbr );
980 sh4r.r[Rn] -= 4;
981 }
982 break;
983 case 0x2:
984 { /* STC.L VBR, @-Rn */
985 uint32_t Rn = ((ir>>8)&0xF);
986 CHECKPRIV();
987 CHECKWALIGN32( sh4r.r[Rn] );
988 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.vbr );
989 sh4r.r[Rn] -= 4;
990 }
991 break;
992 case 0x3:
993 { /* STC.L SSR, @-Rn */
994 uint32_t Rn = ((ir>>8)&0xF);
995 CHECKPRIV();
996 CHECKWALIGN32( sh4r.r[Rn] );
997 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.ssr );
998 sh4r.r[Rn] -= 4;
999 }
1000 break;
1001 case 0x4:
1002 { /* STC.L SPC, @-Rn */
1003 uint32_t Rn = ((ir>>8)&0xF);
1004 CHECKPRIV();
1005 CHECKWALIGN32( sh4r.r[Rn] );
1006 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.spc );
1007 sh4r.r[Rn] -= 4;
1008 }
1009 break;
1010 default:
1011 UNDEF();
1012 break;
1013 }
1014 break;
1015 case 0x1:
1016 { /* STC.L Rm_BANK, @-Rn */
1017 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1018 CHECKPRIV();
1019 CHECKWALIGN32( sh4r.r[Rn] );
1020 MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r_bank[Rm_BANK] );
1021 sh4r.r[Rn] -= 4;
1022 }
1023 break;
1024 }
1025 break;
1026 case 0x4:
1027 switch( (ir&0xF0) >> 4 ) {
1028 case 0x0:
1029 { /* ROTL Rn */
1030 uint32_t Rn = ((ir>>8)&0xF);
1031 sh4r.t = sh4r.r[Rn] >> 31;
1032 sh4r.r[Rn] <<= 1;
1033 sh4r.r[Rn] |= sh4r.t;
1034 }
1035 break;
1036 case 0x2:
1037 { /* ROTCL Rn */
1038 uint32_t Rn = ((ir>>8)&0xF);
1039 tmp = sh4r.r[Rn] >> 31;
1040 sh4r.r[Rn] <<= 1;
1041 sh4r.r[Rn] |= sh4r.t;
1042 sh4r.t = tmp;
1043 }
1044 break;
1045 default:
1046 UNDEF();
1047 break;
1048 }
1049 break;
1050 case 0x5:
1051 switch( (ir&0xF0) >> 4 ) {
1052 case 0x0:
1053 { /* ROTR Rn */
1054 uint32_t Rn = ((ir>>8)&0xF);
1055 sh4r.t = sh4r.r[Rn] & 0x00000001;
1056 sh4r.r[Rn] >>= 1;
1057 sh4r.r[Rn] |= (sh4r.t << 31);
1058 }
1059 break;
1060 case 0x1:
1061 { /* CMP/PL Rn */
1062 uint32_t Rn = ((ir>>8)&0xF);
1063 sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );
1064 }
1065 break;
1066 case 0x2:
1067 { /* ROTCR Rn */
1068 uint32_t Rn = ((ir>>8)&0xF);
1069 tmp = sh4r.r[Rn] & 0x00000001;
1070 sh4r.r[Rn] >>= 1;
1071 sh4r.r[Rn] |= (sh4r.t << 31 );
1072 sh4r.t = tmp;
1073 }
1074 break;
1075 default:
1076 UNDEF();
1077 break;
1078 }
1079 break;
1080 case 0x6:
1081 switch( (ir&0xF0) >> 4 ) {
1082 case 0x0:
1083 { /* LDS.L @Rm+, MACH */
1084 uint32_t Rm = ((ir>>8)&0xF);
1085 CHECKRALIGN32( sh4r.r[Rm] );
1086 MEM_READ_LONG(sh4r.r[Rm], tmp);
1087 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1088 (((uint64_t)tmp)<<32);
1089 sh4r.r[Rm] += 4;
1090 }
1091 break;
1092 case 0x1:
1093 { /* LDS.L @Rm+, MACL */
1094 uint32_t Rm = ((ir>>8)&0xF);
1095 CHECKRALIGN32( sh4r.r[Rm] );
1096 MEM_READ_LONG(sh4r.r[Rm], tmp);
1097 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1098 (uint64_t)((uint32_t)tmp);
1099 sh4r.r[Rm] += 4;
1100 }
1101 break;
1102 case 0x2:
1103 { /* LDS.L @Rm+, PR */
1104 uint32_t Rm = ((ir>>8)&0xF);
1105 CHECKRALIGN32( sh4r.r[Rm] );
1106 MEM_READ_LONG( sh4r.r[Rm], sh4r.pr );
1107 sh4r.r[Rm] += 4;
1108 }
1109 break;
1110 case 0x3:
1111 { /* LDC.L @Rm+, SGR */
1112 uint32_t Rm = ((ir>>8)&0xF);
1113 CHECKPRIV();
1114 CHECKRALIGN32( sh4r.r[Rm] );
1115 MEM_READ_LONG(sh4r.r[Rm], sh4r.sgr);
1116 sh4r.r[Rm] +=4;
1117 }
1118 break;
1119 case 0x5:
1120 { /* LDS.L @Rm+, FPUL */
1121 uint32_t Rm = ((ir>>8)&0xF);
1122 CHECKFPUEN();
1123 CHECKRALIGN32( sh4r.r[Rm] );
1124 MEM_READ_LONG(sh4r.r[Rm], FPULi);
1125 sh4r.r[Rm] +=4;
1126 }
1127 break;
1128 case 0x6:
1129 { /* LDS.L @Rm+, FPSCR */
1130 uint32_t Rm = ((ir>>8)&0xF);
1131 CHECKFPUEN();
1132 CHECKRALIGN32( sh4r.r[Rm] );
1133 MEM_READ_LONG(sh4r.r[Rm], tmp);
1134 sh4r.r[Rm] +=4;
1135 sh4_write_fpscr( tmp );
1136 }
1137 break;
1138 case 0xF:
1139 { /* LDC.L @Rm+, DBR */
1140 uint32_t Rm = ((ir>>8)&0xF);
1141 CHECKPRIV();
1142 CHECKRALIGN32( sh4r.r[Rm] );
1143 MEM_READ_LONG(sh4r.r[Rm], sh4r.dbr);
1144 sh4r.r[Rm] +=4;
1145 }
1146 break;
1147 default:
1148 UNDEF();
1149 break;
1150 }
1151 break;
1152 case 0x7:
1153 switch( (ir&0x80) >> 7 ) {
1154 case 0x0:
1155 switch( (ir&0x70) >> 4 ) {
1156 case 0x0:
1157 { /* LDC.L @Rm+, SR */
1158 uint32_t Rm = ((ir>>8)&0xF);
1159 CHECKSLOTILLEGAL();
1160 CHECKPRIV();
1161 CHECKWALIGN32( sh4r.r[Rm] );
1162 MEM_READ_LONG(sh4r.r[Rm], tmp);
1163 sh4_write_sr( tmp );
1164 sh4r.r[Rm] +=4;
1165 }
1166 break;
1167 case 0x1:
1168 { /* LDC.L @Rm+, GBR */
1169 uint32_t Rm = ((ir>>8)&0xF);
1170 CHECKRALIGN32( sh4r.r[Rm] );
1171 MEM_READ_LONG(sh4r.r[Rm], sh4r.gbr);
1172 sh4r.r[Rm] +=4;
1173 }
1174 break;
1175 case 0x2:
1176 { /* LDC.L @Rm+, VBR */
1177 uint32_t Rm = ((ir>>8)&0xF);
1178 CHECKPRIV();
1179 CHECKRALIGN32( sh4r.r[Rm] );
1180 MEM_READ_LONG(sh4r.r[Rm], sh4r.vbr);
1181 sh4r.r[Rm] +=4;
1182 }
1183 break;
1184 case 0x3:
1185 { /* LDC.L @Rm+, SSR */
1186 uint32_t Rm = ((ir>>8)&0xF);
1187 CHECKPRIV();
1188 CHECKRALIGN32( sh4r.r[Rm] );
1189 MEM_READ_LONG(sh4r.r[Rm], sh4r.ssr);
1190 sh4r.r[Rm] +=4;
1191 }
1192 break;
1193 case 0x4:
1194 { /* LDC.L @Rm+, SPC */
1195 uint32_t Rm = ((ir>>8)&0xF);
1196 CHECKPRIV();
1197 CHECKRALIGN32( sh4r.r[Rm] );
1198 MEM_READ_LONG(sh4r.r[Rm], sh4r.spc);
1199 sh4r.r[Rm] +=4;
1200 }
1201 break;
1202 default:
1203 UNDEF();
1204 break;
1205 }
1206 break;
1207 case 0x1:
1208 { /* LDC.L @Rm+, Rn_BANK */
1209 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1210 CHECKPRIV();
1211 CHECKRALIGN32( sh4r.r[Rm] );
1212 MEM_READ_LONG( sh4r.r[Rm], sh4r.r_bank[Rn_BANK] );
1213 sh4r.r[Rm] += 4;
1214 }
1215 break;
1216 }
1217 break;
1218 case 0x8:
1219 switch( (ir&0xF0) >> 4 ) {
1220 case 0x0:
1221 { /* SHLL2 Rn */
1222 uint32_t Rn = ((ir>>8)&0xF);
1223 sh4r.r[Rn] <<= 2;
1224 }
1225 break;
1226 case 0x1:
1227 { /* SHLL8 Rn */
1228 uint32_t Rn = ((ir>>8)&0xF);
1229 sh4r.r[Rn] <<= 8;
1230 }
1231 break;
1232 case 0x2:
1233 { /* SHLL16 Rn */
1234 uint32_t Rn = ((ir>>8)&0xF);
1235 sh4r.r[Rn] <<= 16;
1236 }
1237 break;
1238 default:
1239 UNDEF();
1240 break;
1241 }
1242 break;
1243 case 0x9:
1244 switch( (ir&0xF0) >> 4 ) {
1245 case 0x0:
1246 { /* SHLR2 Rn */
1247 uint32_t Rn = ((ir>>8)&0xF);
1248 sh4r.r[Rn] >>= 2;
1249 }
1250 break;
1251 case 0x1:
1252 { /* SHLR8 Rn */
1253 uint32_t Rn = ((ir>>8)&0xF);
1254 sh4r.r[Rn] >>= 8;
1255 }
1256 break;
1257 case 0x2:
1258 { /* SHLR16 Rn */
1259 uint32_t Rn = ((ir>>8)&0xF);
1260 sh4r.r[Rn] >>= 16;
1261 }
1262 break;
1263 default:
1264 UNDEF();
1265 break;
1266 }
1267 break;
1268 case 0xA:
1269 switch( (ir&0xF0) >> 4 ) {
1270 case 0x0:
1271 { /* LDS Rm, MACH */
1272 uint32_t Rm = ((ir>>8)&0xF);
1273 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |
1274 (((uint64_t)sh4r.r[Rm])<<32);
1275 }
1276 break;
1277 case 0x1:
1278 { /* LDS Rm, MACL */
1279 uint32_t Rm = ((ir>>8)&0xF);
1280 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1281 (uint64_t)((uint32_t)(sh4r.r[Rm]));
1282 }
1283 break;
1284 case 0x2:
1285 { /* LDS Rm, PR */
1286 uint32_t Rm = ((ir>>8)&0xF);
1287 sh4r.pr = sh4r.r[Rm];
1288 }
1289 break;
1290 case 0x3:
1291 { /* LDC Rm, SGR */
1292 uint32_t Rm = ((ir>>8)&0xF);
1293 CHECKPRIV();
1294 sh4r.sgr = sh4r.r[Rm];
1295 }
1296 break;
1297 case 0x5:
1298 { /* LDS Rm, FPUL */
1299 uint32_t Rm = ((ir>>8)&0xF);
1300 CHECKFPUEN();
1301 FPULi = sh4r.r[Rm];
1302 }
1303 break;
1304 case 0x6:
1305 { /* LDS Rm, FPSCR */
1306 uint32_t Rm = ((ir>>8)&0xF);
1307 CHECKFPUEN();
1308 sh4_write_fpscr( sh4r.r[Rm] );
1309 }
1310 break;
1311 case 0xF:
1312 { /* LDC Rm, DBR */
1313 uint32_t Rm = ((ir>>8)&0xF);
1314 CHECKPRIV();
1315 sh4r.dbr = sh4r.r[Rm];
1316 }
1317 break;
1318 default:
1319 UNDEF();
1320 break;
1321 }
1322 break;
1323 case 0xB:
1324 switch( (ir&0xF0) >> 4 ) {
1325 case 0x0:
1326 { /* JSR @Rn */
1327 uint32_t Rn = ((ir>>8)&0xF);
1328 CHECKDEST( sh4r.r[Rn] );
1329 CHECKSLOTILLEGAL();
1330 sh4r.in_delay_slot = 1;
1331 sh4r.pc = sh4r.new_pc;
1332 sh4r.new_pc = sh4r.r[Rn];
1333 sh4r.pr = pc + 4;
1334 TRACE_CALL( pc, sh4r.new_pc );
1335 return TRUE;
1336 }
1337 break;
1338 case 0x1:
1339 { /* TAS.B @Rn */
1340 uint32_t Rn = ((ir>>8)&0xF);
1341 MEM_READ_BYTE( sh4r.r[Rn], tmp );
1342 sh4r.t = ( tmp == 0 ? 1 : 0 );
1343 MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );
1344 }
1345 break;
1346 case 0x2:
1347 { /* JMP @Rn */
1348 uint32_t Rn = ((ir>>8)&0xF);
1349 CHECKDEST( sh4r.r[Rn] );
1350 CHECKSLOTILLEGAL();
1351 sh4r.in_delay_slot = 1;
1352 sh4r.pc = sh4r.new_pc;
1353 sh4r.new_pc = sh4r.r[Rn];
1354 return TRUE;
1355 }
1356 break;
1357 default:
1358 UNDEF();
1359 break;
1360 }
1361 break;
1362 case 0xC:
1363 { /* SHAD Rm, Rn */
1364 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1365 tmp = sh4r.r[Rm];
1366 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1367 else if( (tmp & 0x1F) == 0 )
1368 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;
1369 else
1370 sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);
1371 }
1372 break;
1373 case 0xD:
1374 { /* SHLD Rm, Rn */
1375 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1376 tmp = sh4r.r[Rm];
1377 if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);
1378 else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;
1379 else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);
1380 }
1381 break;
1382 case 0xE:
1383 switch( (ir&0x80) >> 7 ) {
1384 case 0x0:
1385 switch( (ir&0x70) >> 4 ) {
1386 case 0x0:
1387 { /* LDC Rm, SR */
1388 uint32_t Rm = ((ir>>8)&0xF);
1389 CHECKSLOTILLEGAL();
1390 CHECKPRIV();
1391 sh4_write_sr( sh4r.r[Rm] );
1392 }
1393 break;
1394 case 0x1:
1395 { /* LDC Rm, GBR */
1396 uint32_t Rm = ((ir>>8)&0xF);
1397 sh4r.gbr = sh4r.r[Rm];
1398 }
1399 break;
1400 case 0x2:
1401 { /* LDC Rm, VBR */
1402 uint32_t Rm = ((ir>>8)&0xF);
1403 CHECKPRIV();
1404 sh4r.vbr = sh4r.r[Rm];
1405 }
1406 break;
1407 case 0x3:
1408 { /* LDC Rm, SSR */
1409 uint32_t Rm = ((ir>>8)&0xF);
1410 CHECKPRIV();
1411 sh4r.ssr = sh4r.r[Rm];
1412 }
1413 break;
1414 case 0x4:
1415 { /* LDC Rm, SPC */
1416 uint32_t Rm = ((ir>>8)&0xF);
1417 CHECKPRIV();
1418 sh4r.spc = sh4r.r[Rm];
1419 }
1420 break;
1421 default:
1422 UNDEF();
1423 break;
1424 }
1425 break;
1426 case 0x1:
1427 { /* LDC Rm, Rn_BANK */
1428 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1429 CHECKPRIV();
1430 sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];
1431 }
1432 break;
1433 }
1434 break;
1435 case 0xF:
1436 { /* MAC.W @Rm+, @Rn+ */
1437 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1438 int32_t stmp;
1439 if( Rm == Rn ) {
1440 CHECKRALIGN16(sh4r.r[Rn]);
1441 MEM_READ_WORD( sh4r.r[Rn], tmp );
1442 stmp = SIGNEXT16(tmp);
1443 MEM_READ_WORD( sh4r.r[Rn]+2, tmp );
1444 stmp *= SIGNEXT16(tmp);
1445 sh4r.r[Rn] += 4;
1446 } else {
1447 CHECKRALIGN16( sh4r.r[Rn] );
1448 CHECKRALIGN16( sh4r.r[Rm] );
1449 MEM_READ_WORD(sh4r.r[Rn], tmp);
1450 stmp = SIGNEXT16(tmp);
1451 MEM_READ_WORD(sh4r.r[Rm], tmp);
1452 stmp = stmp * SIGNEXT16(tmp);
1453 sh4r.r[Rn] += 2;
1454 sh4r.r[Rm] += 2;
1455 }
1456 if( sh4r.s ) {
1457 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;
1458 if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {
1459 sh4r.mac = 0x000000017FFFFFFFLL;
1460 } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {
1461 sh4r.mac = 0x0000000180000000LL;
1462 } else {
1463 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |
1464 ((uint32_t)(sh4r.mac + stmp));
1465 }
1466 } else {
1467 sh4r.mac += SIGNEXT32(stmp);
1468 }
1469 }
1470 break;
1471 }
1472 break;
1473 case 0x5:
1474 { /* MOV.L @(disp, Rm), Rn */
1475 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1476 tmp = sh4r.r[Rm] + disp;
1477 CHECKRALIGN32( tmp );
1478 MEM_READ_LONG( tmp, sh4r.r[Rn] );
1479 }
1480 break;
1481 case 0x6:
1482 switch( ir&0xF ) {
1483 case 0x0:
1484 { /* MOV.B @Rm, Rn */
1485 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1486 MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] );
1487 }
1488 break;
1489 case 0x1:
1490 { /* MOV.W @Rm, Rn */
1491 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1492 CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] );
1493 }
1494 break;
1495 case 0x2:
1496 { /* MOV.L @Rm, Rn */
1497 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1498 CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] );
1499 }
1500 break;
1501 case 0x3:
1502 { /* MOV Rm, Rn */
1503 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1504 sh4r.r[Rn] = sh4r.r[Rm];
1505 }
1506 break;
1507 case 0x4:
1508 { /* MOV.B @Rm+, Rn */
1509 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1510 MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] ++;
1511 }
1512 break;
1513 case 0x5:
1514 { /* MOV.W @Rm+, Rn */
1515 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1516 CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 2;
1517 }
1518 break;
1519 case 0x6:
1520 { /* MOV.L @Rm+, Rn */
1521 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1522 CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 4;
1523 }
1524 break;
1525 case 0x7:
1526 { /* NOT Rm, Rn */
1527 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1528 sh4r.r[Rn] = ~sh4r.r[Rm];
1529 }
1530 break;
1531 case 0x8:
1532 { /* SWAP.B Rm, Rn */
1533 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1534 sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8);
1535 }
1536 break;
1537 case 0x9:
1538 { /* SWAP.W Rm, Rn */
1539 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1540 sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16);
1541 }
1542 break;
1543 case 0xA:
1544 { /* NEGC Rm, Rn */
1545 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1546 tmp = 0 - sh4r.r[Rm];
1547 sh4r.r[Rn] = tmp - sh4r.t;
1548 sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );
1549 }
1550 break;
1551 case 0xB:
1552 { /* NEG Rm, Rn */
1553 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1554 sh4r.r[Rn] = 0 - sh4r.r[Rm];
1555 }
1556 break;
1557 case 0xC:
1558 { /* EXTU.B Rm, Rn */
1559 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1560 sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF;
1561 }
1562 break;
1563 case 0xD:
1564 { /* EXTU.W Rm, Rn */
1565 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1566 sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF;
1567 }
1568 break;
1569 case 0xE:
1570 { /* EXTS.B Rm, Rn */
1571 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1572 sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF );
1573 }
1574 break;
1575 case 0xF:
1576 { /* EXTS.W Rm, Rn */
1577 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1578 sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF );
1579 }
1580 break;
1581 }
1582 break;
1583 case 0x7:
1584 { /* ADD #imm, Rn */
1585 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1586 sh4r.r[Rn] += imm;
1587 }
1588 break;
1589 case 0x8:
1590 switch( (ir&0xF00) >> 8 ) {
1591 case 0x0:
1592 { /* MOV.B R0, @(disp, Rn) */
1593 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1594 MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 );
1595 }
1596 break;
1597 case 0x1:
1598 { /* MOV.W R0, @(disp, Rn) */
1599 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1600 tmp = sh4r.r[Rn] + disp;
1601 CHECKWALIGN16( tmp );
1602 MEM_WRITE_WORD( tmp, R0 );
1603 }
1604 break;
1605 case 0x4:
1606 { /* MOV.B @(disp, Rm), R0 */
1607 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1608 MEM_READ_BYTE( sh4r.r[Rm] + disp, R0 );
1609 }
1610 break;
1611 case 0x5:
1612 { /* MOV.W @(disp, Rm), R0 */
1613 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1614 tmp = sh4r.r[Rm] + disp;
1615 CHECKRALIGN16( tmp );
1616 MEM_READ_WORD( tmp, R0 );
1617 }
1618 break;
1619 case 0x8:
1620 { /* CMP/EQ #imm, R0 */
1621 int32_t imm = SIGNEXT8(ir&0xFF);
1622 sh4r.t = ( R0 == imm ? 1 : 0 );
1623 }
1624 break;
1625 case 0x9:
1626 { /* BT disp */
1627 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1628 CHECKSLOTILLEGAL();
1629 if( sh4r.t ) {
1630 CHECKDEST( sh4r.pc + disp + 4 )
1631 sh4r.pc += disp + 4;
1632 sh4r.new_pc = sh4r.pc + 2;
1633 return TRUE;
1634 }
1635 }
1636 break;
1637 case 0xB:
1638 { /* BF disp */
1639 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1640 CHECKSLOTILLEGAL();
1641 if( !sh4r.t ) {
1642 CHECKDEST( sh4r.pc + disp + 4 )
1643 sh4r.pc += disp + 4;
1644 sh4r.new_pc = sh4r.pc + 2;
1645 return TRUE;
1646 }
1647 }
1648 break;
1649 case 0xD:
1650 { /* BT/S disp */
1651 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1652 CHECKSLOTILLEGAL();
1653 if( sh4r.t ) {
1654 CHECKDEST( sh4r.pc + disp + 4 )
1655 sh4r.in_delay_slot = 1;
1656 sh4r.pc = sh4r.new_pc;
1657 sh4r.new_pc = pc + disp + 4;
1658 sh4r.in_delay_slot = 1;
1659 return TRUE;
1660 }
1661 }
1662 break;
1663 case 0xF:
1664 { /* BF/S disp */
1665 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1666 CHECKSLOTILLEGAL();
1667 if( !sh4r.t ) {
1668 CHECKDEST( sh4r.pc + disp + 4 )
1669 sh4r.in_delay_slot = 1;
1670 sh4r.pc = sh4r.new_pc;
1671 sh4r.new_pc = pc + disp + 4;
1672 return TRUE;
1673 }
1674 }
1675 break;
1676 default:
1677 UNDEF();
1678 break;
1679 }
1680 break;
1681 case 0x9:
1682 { /* MOV.W @(disp, PC), Rn */
1683 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1684 CHECKSLOTILLEGAL();
1685 tmp = pc + 4 + disp;
1686 MEM_READ_WORD( tmp, sh4r.r[Rn] );
1687 }
1688 break;
1689 case 0xA:
1690 { /* BRA disp */
1691 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1692 CHECKSLOTILLEGAL();
1693 CHECKDEST( sh4r.pc + disp + 4 );
1694 sh4r.in_delay_slot = 1;
1695 sh4r.pc = sh4r.new_pc;
1696 sh4r.new_pc = pc + 4 + disp;
1697 return TRUE;
1698 }
1699 break;
1700 case 0xB:
1701 { /* BSR disp */
1702 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1703 CHECKDEST( sh4r.pc + disp + 4 );
1704 CHECKSLOTILLEGAL();
1705 sh4r.in_delay_slot = 1;
1706 sh4r.pr = pc + 4;
1707 sh4r.pc = sh4r.new_pc;
1708 sh4r.new_pc = pc + 4 + disp;
1709 TRACE_CALL( pc, sh4r.new_pc );
1710 return TRUE;
1711 }
1712 break;
1713 case 0xC:
1714 switch( (ir&0xF00) >> 8 ) {
1715 case 0x0:
1716 { /* MOV.B R0, @(disp, GBR) */
1717 uint32_t disp = (ir&0xFF);
1718 MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );
1719 }
1720 break;
1721 case 0x1:
1722 { /* MOV.W R0, @(disp, GBR) */
1723 uint32_t disp = (ir&0xFF)<<1;
1724 tmp = sh4r.gbr + disp;
1725 CHECKWALIGN16( tmp );
1726 MEM_WRITE_WORD( tmp, R0 );
1727 }
1728 break;
1729 case 0x2:
1730 { /* MOV.L R0, @(disp, GBR) */
1731 uint32_t disp = (ir&0xFF)<<2;
1732 tmp = sh4r.gbr + disp;
1733 CHECKWALIGN32( tmp );
1734 MEM_WRITE_LONG( tmp, R0 );
1735 }
1736 break;
1737 case 0x3:
1738 { /* TRAPA #imm */
1739 uint32_t imm = (ir&0xFF);
1740 CHECKSLOTILLEGAL();
1741 sh4r.pc += 2;
1742 sh4_raise_trap( imm );
1743 return TRUE;
1744 }
1745 break;
1746 case 0x4:
1747 { /* MOV.B @(disp, GBR), R0 */
1748 uint32_t disp = (ir&0xFF);
1749 MEM_READ_BYTE( sh4r.gbr + disp, R0 );
1750 }
1751 break;
1752 case 0x5:
1753 { /* MOV.W @(disp, GBR), R0 */
1754 uint32_t disp = (ir&0xFF)<<1;
1755 tmp = sh4r.gbr + disp;
1756 CHECKRALIGN16( tmp );
1757 MEM_READ_WORD( tmp, R0 );
1758 }
1759 break;
1760 case 0x6:
1761 { /* MOV.L @(disp, GBR), R0 */
1762 uint32_t disp = (ir&0xFF)<<2;
1763 tmp = sh4r.gbr + disp;
1764 CHECKRALIGN32( tmp );
1765 MEM_READ_LONG( tmp, R0 );
1766 }
1767 break;
1768 case 0x7:
1769 { /* MOVA @(disp, PC), R0 */
1770 uint32_t disp = (ir&0xFF)<<2;
1771 CHECKSLOTILLEGAL();
1772 R0 = (pc&0xFFFFFFFC) + disp + 4;
1773 }
1774 break;
1775 case 0x8:
1776 { /* TST #imm, R0 */
1777 uint32_t imm = (ir&0xFF);
1778 sh4r.t = (R0 & imm ? 0 : 1);
1779 }
1780 break;
1781 case 0x9:
1782 { /* AND #imm, R0 */
1783 uint32_t imm = (ir&0xFF);
1784 R0 &= imm;
1785 }
1786 break;
1787 case 0xA:
1788 { /* XOR #imm, R0 */
1789 uint32_t imm = (ir&0xFF);
1790 R0 ^= imm;
1791 }
1792 break;
1793 case 0xB:
1794 { /* OR #imm, R0 */
1795 uint32_t imm = (ir&0xFF);
1796 R0 |= imm;
1797 }
1798 break;
1799 case 0xC:
1800 { /* TST.B #imm, @(R0, GBR) */
1801 uint32_t imm = (ir&0xFF);
1802 MEM_READ_BYTE(R0+sh4r.gbr, tmp); sh4r.t = ( tmp & imm ? 0 : 1 );
1803 }
1804 break;
1805 case 0xD:
1806 { /* AND.B #imm, @(R0, GBR) */
1807 uint32_t imm = (ir&0xFF);
1808 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & tmp );
1809 }
1810 break;
1811 case 0xE:
1812 { /* XOR.B #imm, @(R0, GBR) */
1813 uint32_t imm = (ir&0xFF);
1814 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ tmp );
1815 }
1816 break;
1817 case 0xF:
1818 { /* OR.B #imm, @(R0, GBR) */
1819 uint32_t imm = (ir&0xFF);
1820 MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | tmp );
1821 }
1822 break;
1823 }
1824 break;
1825 case 0xD:
1826 { /* MOV.L @(disp, PC), Rn */
1827 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1828 CHECKSLOTILLEGAL();
1829 tmp = (pc&0xFFFFFFFC) + disp + 4;
1830 MEM_READ_LONG( tmp, sh4r.r[Rn] );
1831 }
1832 break;
1833 case 0xE:
1834 { /* MOV #imm, Rn */
1835 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1836 sh4r.r[Rn] = imm;
1837 }
1838 break;
1839 case 0xF:
1840 switch( ir&0xF ) {
1841 case 0x0:
1842 { /* FADD FRm, FRn */
1843 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1844 CHECKFPUEN();
1845 if( IS_FPU_DOUBLEPREC() ) {
1846 DR(FRn) += DR(FRm);
1847 } else {
1848 FR(FRn) += FR(FRm);
1849 }
1850 }
1851 break;
1852 case 0x1:
1853 { /* FSUB FRm, FRn */
1854 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1855 CHECKFPUEN();
1856 if( IS_FPU_DOUBLEPREC() ) {
1857 DR(FRn) -= DR(FRm);
1858 } else {
1859 FR(FRn) -= FR(FRm);
1860 }
1861 }
1862 break;
1863 case 0x2:
1864 { /* FMUL FRm, FRn */
1865 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1866 CHECKFPUEN();
1867 if( IS_FPU_DOUBLEPREC() ) {
1868 DR(FRn) *= DR(FRm);
1869 } else {
1870 FR(FRn) *= FR(FRm);
1871 }
1872 }
1873 break;
1874 case 0x3:
1875 { /* FDIV FRm, FRn */
1876 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1877 CHECKFPUEN();
1878 if( IS_FPU_DOUBLEPREC() ) {
1879 DR(FRn) /= DR(FRm);
1880 } else {
1881 FR(FRn) /= FR(FRm);
1882 }
1883 }
1884 break;
1885 case 0x4:
1886 { /* FCMP/EQ FRm, FRn */
1887 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1888 CHECKFPUEN();
1889 if( IS_FPU_DOUBLEPREC() ) {
1890 sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );
1891 } else {
1892 sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );
1893 }
1894 }
1895 break;
1896 case 0x5:
1897 { /* FCMP/GT FRm, FRn */
1898 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1899 CHECKFPUEN();
1900 if( IS_FPU_DOUBLEPREC() ) {
1901 sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );
1902 } else {
1903 sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );
1904 }
1905 }
1906 break;
1907 case 0x6:
1908 { /* FMOV @(R0, Rm), FRn */
1909 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1910 MEM_FP_READ( sh4r.r[Rm] + R0, FRn );
1911 }
1912 break;
1913 case 0x7:
1914 { /* FMOV FRm, @(R0, Rn) */
1915 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1916 MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm );
1917 }
1918 break;
1919 case 0x8:
1920 { /* FMOV @Rm, FRn */
1921 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1922 MEM_FP_READ( sh4r.r[Rm], FRn );
1923 }
1924 break;
1925 case 0x9:
1926 { /* FMOV @Rm+, FRn */
1927 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1928 MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH;
1929 }
1930 break;
1931 case 0xA:
1932 { /* FMOV FRm, @Rn */
1933 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1934 MEM_FP_WRITE( sh4r.r[Rn], FRm );
1935 }
1936 break;
1937 case 0xB:
1938 { /* FMOV FRm, @-Rn */
1939 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1940 MEM_FP_WRITE( sh4r.r[Rn] - FP_WIDTH, FRm ); sh4r.r[Rn] -= FP_WIDTH;
1941 }
1942 break;
1943 case 0xC:
1944 { /* FMOV FRm, FRn */
1945 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1946 if( IS_FPU_DOUBLESIZE() )
1947 DR(FRn) = DR(FRm);
1948 else
1949 FR(FRn) = FR(FRm);
1950 }
1951 break;
1952 case 0xD:
1953 switch( (ir&0xF0) >> 4 ) {
1954 case 0x0:
1955 { /* FSTS FPUL, FRn */
1956 uint32_t FRn = ((ir>>8)&0xF);
1957 CHECKFPUEN(); FR(FRn) = FPULf;
1958 }
1959 break;
1960 case 0x1:
1961 { /* FLDS FRm, FPUL */
1962 uint32_t FRm = ((ir>>8)&0xF);
1963 CHECKFPUEN(); FPULf = FR(FRm);
1964 }
1965 break;
1966 case 0x2:
1967 { /* FLOAT FPUL, FRn */
1968 uint32_t FRn = ((ir>>8)&0xF);
1969 CHECKFPUEN();
1970 if( IS_FPU_DOUBLEPREC() ) {
1971 if( FRn&1 ) { // No, really...
1972 dtmp = (double)FPULi;
1973 FR(FRn) = *(((float *)&dtmp)+1);
1974 } else {
1975 DRF(FRn>>1) = (double)FPULi;
1976 }
1977 } else {
1978 FR(FRn) = (float)FPULi;
1979 }
1980 }
1981 break;
1982 case 0x3:
1983 { /* FTRC FRm, FPUL */
1984 uint32_t FRm = ((ir>>8)&0xF);
1985 CHECKFPUEN();
1986 if( IS_FPU_DOUBLEPREC() ) {
1987 if( FRm&1 ) {
1988 dtmp = 0;
1989 *(((float *)&dtmp)+1) = FR(FRm);
1990 } else {
1991 dtmp = DRF(FRm>>1);
1992 }
1993 if( dtmp >= MAX_INTF )
1994 FPULi = MAX_INT;
1995 else if( dtmp <= MIN_INTF )
1996 FPULi = MIN_INT;
1997 else
1998 FPULi = (int32_t)dtmp;
1999 } else {
2000 ftmp = FR(FRm);
2001 if( ftmp >= MAX_INTF )
2002 FPULi = MAX_INT;
2003 else if( ftmp <= MIN_INTF )
2004 FPULi = MIN_INT;
2005 else
2006 FPULi = (int32_t)ftmp;
2007 }
2008 }
2009 break;
2010 case 0x4:
2011 { /* FNEG FRn */
2012 uint32_t FRn = ((ir>>8)&0xF);
2013 CHECKFPUEN();
2014 if( IS_FPU_DOUBLEPREC() ) {
2015 DR(FRn) = -DR(FRn);
2016 } else {
2017 FR(FRn) = -FR(FRn);
2018 }
2019 }
2020 break;
2021 case 0x5:
2022 { /* FABS FRn */
2023 uint32_t FRn = ((ir>>8)&0xF);
2024 CHECKFPUEN();
2025 if( IS_FPU_DOUBLEPREC() ) {
2026 DR(FRn) = fabs(DR(FRn));
2027 } else {
2028 FR(FRn) = fabsf(FR(FRn));
2029 }
2030 }
2031 break;
2032 case 0x6:
2033 { /* FSQRT FRn */
2034 uint32_t FRn = ((ir>>8)&0xF);
2035 CHECKFPUEN();
2036 if( IS_FPU_DOUBLEPREC() ) {
2037 DR(FRn) = sqrt(DR(FRn));
2038 } else {
2039 FR(FRn) = sqrtf(FR(FRn));
2040 }
2041 }
2042 break;
2043 case 0x7:
2044 { /* FSRRA FRn */
2045 uint32_t FRn = ((ir>>8)&0xF);
2046 CHECKFPUEN();
2047 if( !IS_FPU_DOUBLEPREC() ) {
2048 FR(FRn) = 1.0/sqrtf(FR(FRn));
2049 }
2050 }
2051 break;
2052 case 0x8:
2053 { /* FLDI0 FRn */
2054 uint32_t FRn = ((ir>>8)&0xF);
2055 CHECKFPUEN();
2056 if( IS_FPU_DOUBLEPREC() ) {
2057 DR(FRn) = 0.0;
2058 } else {
2059 FR(FRn) = 0.0;
2060 }
2061 }
2062 break;
2063 case 0x9:
2064 { /* FLDI1 FRn */
2065 uint32_t FRn = ((ir>>8)&0xF);
2066 CHECKFPUEN();
2067 if( IS_FPU_DOUBLEPREC() ) {
2068 DR(FRn) = 1.0;
2069 } else {
2070 FR(FRn) = 1.0;
2071 }
2072 }
2073 break;
2074 case 0xA:
2075 { /* FCNVSD FPUL, FRn */
2076 uint32_t FRn = ((ir>>8)&0xF);
2077 CHECKFPUEN();
2078 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2079 DR(FRn) = (double)FPULf;
2080 }
2081 }
2082 break;
2083 case 0xB:
2084 { /* FCNVDS FRm, FPUL */
2085 uint32_t FRm = ((ir>>8)&0xF);
2086 CHECKFPUEN();
2087 if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {
2088 FPULf = (float)DR(FRm);
2089 }
2090 }
2091 break;
2092 case 0xE:
2093 { /* FIPR FVm, FVn */
2094 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2095 CHECKFPUEN();
2096 if( !IS_FPU_DOUBLEPREC() ) {
2097 int tmp2 = FVn<<2;
2098 tmp = FVm<<2;
2099 FR(tmp2+3) = FR(tmp)*FR(tmp2) +
2100 FR(tmp+1)*FR(tmp2+1) +
2101 FR(tmp+2)*FR(tmp2+2) +
2102 FR(tmp+3)*FR(tmp2+3);
2103 }
2104 }
2105 break;
2106 case 0xF:
2107 switch( (ir&0x100) >> 8 ) {
2108 case 0x0:
2109 { /* FSCA FPUL, FRn */
2110 uint32_t FRn = ((ir>>9)&0x7)<<1;
2111 CHECKFPUEN();
2112 if( !IS_FPU_DOUBLEPREC() ) {
2113 sh4_fsca( FPULi, &(DRF(FRn>>1)) );
2114 /*
2115 float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;
2116 FR(FRn) = sinf(angle);
2117 FR((FRn)+1) = cosf(angle);
2118 */
2119 }
2120 }
2121 break;
2122 case 0x1:
2123 switch( (ir&0x200) >> 9 ) {
2124 case 0x0:
2125 { /* FTRV XMTRX, FVn */
2126 uint32_t FVn = ((ir>>10)&0x3);
2127 CHECKFPUEN();
2128 if( !IS_FPU_DOUBLEPREC() ) {
2129 sh4_ftrv(&(DRF(FVn<<1)) );
2130 }
2131 }
2132 break;
2133 case 0x1:
2134 switch( (ir&0xC00) >> 10 ) {
2135 case 0x0:
2136 { /* FSCHG */
2137 CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;
2138 }
2139 break;
2140 case 0x2:
2141 { /* FRCHG */
2142 CHECKFPUEN();
2143 sh4r.fpscr ^= FPSCR_FR;
2144 sh4_switch_fr_banks();
2145 }
2146 break;
2147 case 0x3:
2148 { /* UNDEF */
2149 UNDEF(ir);
2150 }
2151 break;
2152 default:
2153 UNDEF();
2154 break;
2155 }
2156 break;
2157 }
2158 break;
2159 }
2160 break;
2161 default:
2162 UNDEF();
2163 break;
2164 }
2165 break;
2166 case 0xE:
2167 { /* FMAC FR0, FRm, FRn */
2168 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2169 CHECKFPUEN();
2170 if( IS_FPU_DOUBLEPREC() ) {
2171 DR(FRn) += DR(FRm)*DR(0);
2172 } else {
2173 FR(FRn) += FR(FRm)*FR(0);
2174 }
2175 }
2176 break;
2177 default:
2178 UNDEF();
2179 break;
2180 }
2181 break;
2182 }
2184 sh4r.pc = sh4r.new_pc;
2185 sh4r.new_pc += 2;
2186 sh4r.in_delay_slot = 0;
2187 return TRUE;
2188 }
.