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