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