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