filename | src/sh4/sh4x86.c |
changeset | 417:bd927df302a9 |
prev | 416:714df603c869 |
next | 502:c4ecae2b1b5e |
author | nkeynes |
date | Sun Oct 28 07:23:46 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Fix CDI with multiple tracks/session Fix file being closed too early |
view | annotate | diff | log | raw |
1 /**
2 * $Id: sh4x86.c,v 1.18 2007-10-04 08:47:27 nkeynes Exp $
3 *
4 * SH4 => x86 translation. This version does no real optimization, it just
5 * outputs straight-line x86 code - it mainly exists to provide a baseline
6 * to test the optimizing versions against.
7 *
8 * Copyright (c) 2007 Nathan Keynes.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
21 #include <assert.h>
22 #include <math.h>
24 #ifndef NDEBUG
25 #define DEBUG_JUMPS 1
26 #endif
28 #include "sh4/xltcache.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4trans.h"
31 #include "sh4/sh4mmio.h"
32 #include "sh4/x86op.h"
33 #include "clock.h"
35 #define DEFAULT_BACKPATCH_SIZE 4096
37 /**
38 * Struct to manage internal translation state. This state is not saved -
39 * it is only valid between calls to sh4_translate_begin_block() and
40 * sh4_translate_end_block()
41 */
42 struct sh4_x86_state {
43 gboolean in_delay_slot;
44 gboolean priv_checked; /* true if we've already checked the cpu mode. */
45 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
46 gboolean branch_taken; /* true if we branched unconditionally */
47 uint32_t block_start_pc;
48 int tstate;
50 /* Allocated memory for the (block-wide) back-patch list */
51 uint32_t **backpatch_list;
52 uint32_t backpatch_posn;
53 uint32_t backpatch_size;
54 };
56 #define TSTATE_NONE -1
57 #define TSTATE_O 0
58 #define TSTATE_C 2
59 #define TSTATE_E 4
60 #define TSTATE_NE 5
61 #define TSTATE_G 0xF
62 #define TSTATE_GE 0xD
63 #define TSTATE_A 7
64 #define TSTATE_AE 3
66 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
67 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
68 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
69 OP(0x70+sh4_x86.tstate); OP(rel8); \
70 MARK_JMP(rel8,label)
71 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
72 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
73 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
74 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
75 MARK_JMP(rel8, label)
78 #define EXIT_DATA_ADDR_READ 0
79 #define EXIT_DATA_ADDR_WRITE 7
80 #define EXIT_ILLEGAL 14
81 #define EXIT_SLOT_ILLEGAL 21
82 #define EXIT_FPU_DISABLED 28
83 #define EXIT_SLOT_FPU_DISABLED 35
85 static struct sh4_x86_state sh4_x86;
87 static uint32_t max_int = 0x7FFFFFFF;
88 static uint32_t min_int = 0x80000000;
89 static uint32_t save_fcw; /* save value for fpu control word */
90 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
92 void sh4_x86_init()
93 {
94 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
95 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
96 }
99 static void sh4_x86_add_backpatch( uint8_t *ptr )
100 {
101 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
102 sh4_x86.backpatch_size <<= 1;
103 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
104 assert( sh4_x86.backpatch_list != NULL );
105 }
106 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
107 }
109 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
110 {
111 unsigned int i;
112 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
113 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
114 }
115 }
117 /**
118 * Emit an instruction to load an SH4 reg into a real register
119 */
120 static inline void load_reg( int x86reg, int sh4reg )
121 {
122 /* mov [bp+n], reg */
123 OP(0x8B);
124 OP(0x45 + (x86reg<<3));
125 OP(REG_OFFSET(r[sh4reg]));
126 }
128 static inline void load_reg16s( int x86reg, int sh4reg )
129 {
130 OP(0x0F);
131 OP(0xBF);
132 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
133 }
135 static inline void load_reg16u( int x86reg, int sh4reg )
136 {
137 OP(0x0F);
138 OP(0xB7);
139 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
141 }
143 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
144 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
145 /**
146 * Emit an instruction to load an immediate value into a register
147 */
148 static inline void load_imm32( int x86reg, uint32_t value ) {
149 /* mov #value, reg */
150 OP(0xB8 + x86reg);
151 OP32(value);
152 }
154 /**
155 * Emit an instruction to store an SH4 reg (RN)
156 */
157 void static inline store_reg( int x86reg, int sh4reg ) {
158 /* mov reg, [bp+n] */
159 OP(0x89);
160 OP(0x45 + (x86reg<<3));
161 OP(REG_OFFSET(r[sh4reg]));
162 }
164 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
166 /**
167 * Load an FR register (single-precision floating point) into an integer x86
168 * register (eg for register-to-register moves)
169 */
170 void static inline load_fr( int bankreg, int x86reg, int frm )
171 {
172 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
173 }
175 /**
176 * Store an FR register (single-precision floating point) into an integer x86
177 * register (eg for register-to-register moves)
178 */
179 void static inline store_fr( int bankreg, int x86reg, int frn )
180 {
181 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
182 }
185 /**
186 * Load a pointer to the back fp back into the specified x86 register. The
187 * bankreg must have been previously loaded with FPSCR.
188 * NB: 12 bytes
189 */
190 static inline void load_xf_bank( int bankreg )
191 {
192 NOT_r32( bankreg );
193 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
194 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
195 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
196 }
198 /**
199 * Update the fr_bank pointer based on the current fpscr value.
200 */
201 static inline void update_fr_bank( int fpscrreg )
202 {
203 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
204 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
205 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
206 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
207 }
208 /**
209 * Push FPUL (as a 32-bit float) onto the FPU stack
210 */
211 static inline void push_fpul( )
212 {
213 OP(0xD9); OP(0x45); OP(R_FPUL);
214 }
216 /**
217 * Pop FPUL (as a 32-bit float) from the FPU stack
218 */
219 static inline void pop_fpul( )
220 {
221 OP(0xD9); OP(0x5D); OP(R_FPUL);
222 }
224 /**
225 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
226 * with the location of the current fp bank.
227 */
228 static inline void push_fr( int bankreg, int frm )
229 {
230 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
231 }
233 /**
234 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
235 * with bankreg previously loaded with the location of the current fp bank.
236 */
237 static inline void pop_fr( int bankreg, int frm )
238 {
239 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
240 }
242 /**
243 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
244 * with the location of the current fp bank.
245 */
246 static inline void push_dr( int bankreg, int frm )
247 {
248 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
249 }
251 static inline void pop_dr( int bankreg, int frm )
252 {
253 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
254 }
256 /**
257 * Note: clobbers EAX to make the indirect call - this isn't usually
258 * a problem since the callee will usually clobber it anyway.
259 */
260 static inline void call_func0( void *ptr )
261 {
262 load_imm32(R_EAX, (uint32_t)ptr);
263 CALL_r32(R_EAX);
264 }
266 static inline void call_func1( void *ptr, int arg1 )
267 {
268 PUSH_r32(arg1);
269 call_func0(ptr);
270 ADD_imm8s_r32( 4, R_ESP );
271 }
273 static inline void call_func2( void *ptr, int arg1, int arg2 )
274 {
275 PUSH_r32(arg2);
276 PUSH_r32(arg1);
277 call_func0(ptr);
278 ADD_imm8s_r32( 8, R_ESP );
279 }
281 /**
282 * Write a double (64-bit) value into memory, with the first word in arg2a, and
283 * the second in arg2b
284 * NB: 30 bytes
285 */
286 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
287 {
288 ADD_imm8s_r32( 4, addr );
289 PUSH_r32(arg2b);
290 PUSH_r32(addr);
291 ADD_imm8s_r32( -4, addr );
292 PUSH_r32(arg2a);
293 PUSH_r32(addr);
294 call_func0(sh4_write_long);
295 ADD_imm8s_r32( 8, R_ESP );
296 call_func0(sh4_write_long);
297 ADD_imm8s_r32( 8, R_ESP );
298 }
300 /**
301 * Read a double (64-bit) value from memory, writing the first word into arg2a
302 * and the second into arg2b. The addr must not be in EAX
303 * NB: 27 bytes
304 */
305 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
306 {
307 PUSH_r32(addr);
308 call_func0(sh4_read_long);
309 POP_r32(addr);
310 PUSH_r32(R_EAX);
311 ADD_imm8s_r32( 4, addr );
312 PUSH_r32(addr);
313 call_func0(sh4_read_long);
314 ADD_imm8s_r32( 4, R_ESP );
315 MOV_r32_r32( R_EAX, arg2b );
316 POP_r32(arg2a);
317 }
319 /* Exception checks - Note that all exception checks will clobber EAX */
320 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
322 #define check_priv( ) \
323 if( !sh4_x86.priv_checked ) { \
324 sh4_x86.priv_checked = TRUE;\
325 precheck();\
326 load_spreg( R_EAX, R_SR );\
327 AND_imm32_r32( SR_MD, R_EAX );\
328 if( sh4_x86.in_delay_slot ) {\
329 JE_exit( EXIT_SLOT_ILLEGAL );\
330 } else {\
331 JE_exit( EXIT_ILLEGAL );\
332 }\
333 }\
336 static void check_priv_no_precheck()
337 {
338 if( !sh4_x86.priv_checked ) {
339 sh4_x86.priv_checked = TRUE;
340 load_spreg( R_EAX, R_SR );
341 AND_imm32_r32( SR_MD, R_EAX );
342 if( sh4_x86.in_delay_slot ) {
343 JE_exit( EXIT_SLOT_ILLEGAL );
344 } else {
345 JE_exit( EXIT_ILLEGAL );
346 }
347 }
348 }
350 #define check_fpuen( ) \
351 if( !sh4_x86.fpuen_checked ) {\
352 sh4_x86.fpuen_checked = TRUE;\
353 precheck();\
354 load_spreg( R_EAX, R_SR );\
355 AND_imm32_r32( SR_FD, R_EAX );\
356 if( sh4_x86.in_delay_slot ) {\
357 JNE_exit(EXIT_SLOT_FPU_DISABLED);\
358 } else {\
359 JNE_exit(EXIT_FPU_DISABLED);\
360 }\
361 }
363 static void check_fpuen_no_precheck()
364 {
365 if( !sh4_x86.fpuen_checked ) {
366 sh4_x86.fpuen_checked = TRUE;
367 load_spreg( R_EAX, R_SR );
368 AND_imm32_r32( SR_FD, R_EAX );
369 if( sh4_x86.in_delay_slot ) {
370 JNE_exit(EXIT_SLOT_FPU_DISABLED);
371 } else {
372 JNE_exit(EXIT_FPU_DISABLED);
373 }
374 }
376 }
378 static void check_ralign16( int x86reg )
379 {
380 TEST_imm32_r32( 0x00000001, x86reg );
381 JNE_exit(EXIT_DATA_ADDR_READ);
382 }
384 static void check_walign16( int x86reg )
385 {
386 TEST_imm32_r32( 0x00000001, x86reg );
387 JNE_exit(EXIT_DATA_ADDR_WRITE);
388 }
390 static void check_ralign32( int x86reg )
391 {
392 TEST_imm32_r32( 0x00000003, x86reg );
393 JNE_exit(EXIT_DATA_ADDR_READ);
394 }
395 static void check_walign32( int x86reg )
396 {
397 TEST_imm32_r32( 0x00000003, x86reg );
398 JNE_exit(EXIT_DATA_ADDR_WRITE);
399 }
401 #define UNDEF()
402 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
403 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
404 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
405 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
406 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
407 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
408 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
410 #define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
414 /**
415 * Emit the 'start of block' assembly. Sets up the stack frame and save
416 * SI/DI as required
417 */
418 void sh4_translate_begin_block( sh4addr_t pc )
419 {
420 PUSH_r32(R_EBP);
421 /* mov &sh4r, ebp */
422 load_imm32( R_EBP, (uint32_t)&sh4r );
424 sh4_x86.in_delay_slot = FALSE;
425 sh4_x86.priv_checked = FALSE;
426 sh4_x86.fpuen_checked = FALSE;
427 sh4_x86.branch_taken = FALSE;
428 sh4_x86.backpatch_posn = 0;
429 sh4_x86.block_start_pc = pc;
430 sh4_x86.tstate = TSTATE_NONE;
431 }
433 /**
434 * Exit the block to an absolute PC
435 * Bytes: 29
436 */
437 void exit_block( sh4addr_t pc, sh4addr_t endpc )
438 {
439 load_imm32( R_ECX, pc ); // 5
440 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
441 MOV_moff32_EAX( (uint32_t)xlat_get_lut_entry(pc) ); // 5
442 AND_imm8s_r32( 0xFC, R_EAX ); // 3
443 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
444 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
445 POP_r32(R_EBP);
446 RET();
447 }
449 /**
450 * Exit the block with sh4r.pc already written
451 * Bytes: 15
452 */
453 void exit_block_pcset( pc )
454 {
455 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
456 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
457 load_spreg( R_EAX, REG_OFFSET(pc) );
458 call_func1(xlat_get_code,R_EAX);
459 POP_r32(R_EBP);
460 RET();
461 }
463 /**
464 * Write the block trailer (exception handling block)
465 */
466 void sh4_translate_end_block( sh4addr_t pc ) {
467 if( sh4_x86.branch_taken == FALSE ) {
468 // Didn't exit unconditionally already, so write the termination here
469 exit_block( pc, pc );
470 }
471 if( sh4_x86.backpatch_posn != 0 ) {
472 uint8_t *end_ptr = xlat_output;
473 // Exception termination. Jump block for various exception codes:
474 PUSH_imm32( EXC_DATA_ADDR_READ );
475 JMP_rel8( 33, target1 );
476 PUSH_imm32( EXC_DATA_ADDR_WRITE );
477 JMP_rel8( 26, target2 );
478 PUSH_imm32( EXC_ILLEGAL );
479 JMP_rel8( 19, target3 );
480 PUSH_imm32( EXC_SLOT_ILLEGAL );
481 JMP_rel8( 12, target4 );
482 PUSH_imm32( EXC_FPU_DISABLED );
483 JMP_rel8( 5, target5 );
484 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
485 // target
486 JMP_TARGET(target1);
487 JMP_TARGET(target2);
488 JMP_TARGET(target3);
489 JMP_TARGET(target4);
490 JMP_TARGET(target5);
491 // Raise exception
492 load_spreg( R_ECX, REG_OFFSET(pc) );
493 ADD_r32_r32( R_EDX, R_ECX );
494 ADD_r32_r32( R_EDX, R_ECX );
495 store_spreg( R_ECX, REG_OFFSET(pc) );
496 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
497 MUL_r32( R_EDX );
498 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
500 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
501 CALL_r32( R_EAX ); // 2
502 ADD_imm8s_r32( 4, R_ESP );
503 load_spreg( R_EAX, REG_OFFSET(pc) );
504 call_func1(xlat_get_code,R_EAX);
505 POP_r32(R_EBP);
506 RET();
508 sh4_x86_do_backpatch( end_ptr );
509 }
511 }
514 extern uint16_t *sh4_icache;
515 extern uint32_t sh4_icache_addr;
517 /**
518 * Translate a single instruction. Delayed branches are handled specially
519 * by translating both branch and delayed instruction as a single unit (as
520 *
521 *
522 * @return true if the instruction marks the end of a basic block
523 * (eg a branch or
524 */
525 uint32_t sh4_x86_translate_instruction( sh4addr_t pc )
526 {
527 uint32_t ir;
528 /* Read instruction */
529 uint32_t pageaddr = pc >> 12;
530 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
531 ir = sh4_icache[(pc&0xFFF)>>1];
532 } else {
533 sh4_icache = (uint16_t *)mem_get_page(pc);
534 if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
535 /* If someone's actually been so daft as to try to execute out of an IO
536 * region, fallback on the full-blown memory read
537 */
538 sh4_icache = NULL;
539 ir = sh4_read_word(pc);
540 } else {
541 sh4_icache_addr = pageaddr;
542 ir = sh4_icache[(pc&0xFFF)>>1];
543 }
544 }
546 switch( (ir&0xF000) >> 12 ) {
547 case 0x0:
548 switch( ir&0xF ) {
549 case 0x2:
550 switch( (ir&0x80) >> 7 ) {
551 case 0x0:
552 switch( (ir&0x70) >> 4 ) {
553 case 0x0:
554 { /* STC SR, Rn */
555 uint32_t Rn = ((ir>>8)&0xF);
556 check_priv();
557 call_func0(sh4_read_sr);
558 store_reg( R_EAX, Rn );
559 sh4_x86.tstate = TSTATE_NONE;
560 }
561 break;
562 case 0x1:
563 { /* STC GBR, Rn */
564 uint32_t Rn = ((ir>>8)&0xF);
565 load_spreg( R_EAX, R_GBR );
566 store_reg( R_EAX, Rn );
567 }
568 break;
569 case 0x2:
570 { /* STC VBR, Rn */
571 uint32_t Rn = ((ir>>8)&0xF);
572 check_priv();
573 load_spreg( R_EAX, R_VBR );
574 store_reg( R_EAX, Rn );
575 sh4_x86.tstate = TSTATE_NONE;
576 }
577 break;
578 case 0x3:
579 { /* STC SSR, Rn */
580 uint32_t Rn = ((ir>>8)&0xF);
581 check_priv();
582 load_spreg( R_EAX, R_SSR );
583 store_reg( R_EAX, Rn );
584 sh4_x86.tstate = TSTATE_NONE;
585 }
586 break;
587 case 0x4:
588 { /* STC SPC, Rn */
589 uint32_t Rn = ((ir>>8)&0xF);
590 check_priv();
591 load_spreg( R_EAX, R_SPC );
592 store_reg( R_EAX, Rn );
593 sh4_x86.tstate = TSTATE_NONE;
594 }
595 break;
596 default:
597 UNDEF();
598 break;
599 }
600 break;
601 case 0x1:
602 { /* STC Rm_BANK, Rn */
603 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
604 check_priv();
605 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
606 store_reg( R_EAX, Rn );
607 sh4_x86.tstate = TSTATE_NONE;
608 }
609 break;
610 }
611 break;
612 case 0x3:
613 switch( (ir&0xF0) >> 4 ) {
614 case 0x0:
615 { /* BSRF Rn */
616 uint32_t Rn = ((ir>>8)&0xF);
617 if( sh4_x86.in_delay_slot ) {
618 SLOTILLEGAL();
619 } else {
620 load_imm32( R_ECX, pc + 4 );
621 store_spreg( R_ECX, R_PR );
622 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
623 store_spreg( R_ECX, REG_OFFSET(pc) );
624 sh4_x86.in_delay_slot = TRUE;
625 sh4_x86.tstate = TSTATE_NONE;
626 sh4_x86_translate_instruction( pc + 2 );
627 exit_block_pcset(pc+2);
628 sh4_x86.branch_taken = TRUE;
629 return 4;
630 }
631 }
632 break;
633 case 0x2:
634 { /* BRAF Rn */
635 uint32_t Rn = ((ir>>8)&0xF);
636 if( sh4_x86.in_delay_slot ) {
637 SLOTILLEGAL();
638 } else {
639 load_reg( R_EAX, Rn );
640 ADD_imm32_r32( pc + 4, R_EAX );
641 store_spreg( R_EAX, REG_OFFSET(pc) );
642 sh4_x86.in_delay_slot = TRUE;
643 sh4_x86.tstate = TSTATE_NONE;
644 sh4_x86_translate_instruction( pc + 2 );
645 exit_block_pcset(pc+2);
646 sh4_x86.branch_taken = TRUE;
647 return 4;
648 }
649 }
650 break;
651 case 0x8:
652 { /* PREF @Rn */
653 uint32_t Rn = ((ir>>8)&0xF);
654 load_reg( R_EAX, Rn );
655 PUSH_r32( R_EAX );
656 AND_imm32_r32( 0xFC000000, R_EAX );
657 CMP_imm32_r32( 0xE0000000, R_EAX );
658 JNE_rel8(7, end);
659 call_func0( sh4_flush_store_queue );
660 JMP_TARGET(end);
661 ADD_imm8s_r32( 4, R_ESP );
662 sh4_x86.tstate = TSTATE_NONE;
663 }
664 break;
665 case 0x9:
666 { /* OCBI @Rn */
667 uint32_t Rn = ((ir>>8)&0xF);
668 }
669 break;
670 case 0xA:
671 { /* OCBP @Rn */
672 uint32_t Rn = ((ir>>8)&0xF);
673 }
674 break;
675 case 0xB:
676 { /* OCBWB @Rn */
677 uint32_t Rn = ((ir>>8)&0xF);
678 }
679 break;
680 case 0xC:
681 { /* MOVCA.L R0, @Rn */
682 uint32_t Rn = ((ir>>8)&0xF);
683 load_reg( R_EAX, 0 );
684 load_reg( R_ECX, Rn );
685 precheck();
686 check_walign32( R_ECX );
687 MEM_WRITE_LONG( R_ECX, R_EAX );
688 sh4_x86.tstate = TSTATE_NONE;
689 }
690 break;
691 default:
692 UNDEF();
693 break;
694 }
695 break;
696 case 0x4:
697 { /* MOV.B Rm, @(R0, Rn) */
698 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
699 load_reg( R_EAX, 0 );
700 load_reg( R_ECX, Rn );
701 ADD_r32_r32( R_EAX, R_ECX );
702 load_reg( R_EAX, Rm );
703 MEM_WRITE_BYTE( R_ECX, R_EAX );
704 sh4_x86.tstate = TSTATE_NONE;
705 }
706 break;
707 case 0x5:
708 { /* MOV.W Rm, @(R0, Rn) */
709 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
710 load_reg( R_EAX, 0 );
711 load_reg( R_ECX, Rn );
712 ADD_r32_r32( R_EAX, R_ECX );
713 precheck();
714 check_walign16( R_ECX );
715 load_reg( R_EAX, Rm );
716 MEM_WRITE_WORD( R_ECX, R_EAX );
717 sh4_x86.tstate = TSTATE_NONE;
718 }
719 break;
720 case 0x6:
721 { /* MOV.L Rm, @(R0, Rn) */
722 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
723 load_reg( R_EAX, 0 );
724 load_reg( R_ECX, Rn );
725 ADD_r32_r32( R_EAX, R_ECX );
726 precheck();
727 check_walign32( R_ECX );
728 load_reg( R_EAX, Rm );
729 MEM_WRITE_LONG( R_ECX, R_EAX );
730 sh4_x86.tstate = TSTATE_NONE;
731 }
732 break;
733 case 0x7:
734 { /* MUL.L Rm, Rn */
735 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
736 load_reg( R_EAX, Rm );
737 load_reg( R_ECX, Rn );
738 MUL_r32( R_ECX );
739 store_spreg( R_EAX, R_MACL );
740 sh4_x86.tstate = TSTATE_NONE;
741 }
742 break;
743 case 0x8:
744 switch( (ir&0xFF0) >> 4 ) {
745 case 0x0:
746 { /* CLRT */
747 CLC();
748 SETC_t();
749 sh4_x86.tstate = TSTATE_C;
750 }
751 break;
752 case 0x1:
753 { /* SETT */
754 STC();
755 SETC_t();
756 sh4_x86.tstate = TSTATE_C;
757 }
758 break;
759 case 0x2:
760 { /* CLRMAC */
761 XOR_r32_r32(R_EAX, R_EAX);
762 store_spreg( R_EAX, R_MACL );
763 store_spreg( R_EAX, R_MACH );
764 sh4_x86.tstate = TSTATE_NONE;
765 }
766 break;
767 case 0x3:
768 { /* LDTLB */
769 }
770 break;
771 case 0x4:
772 { /* CLRS */
773 CLC();
774 SETC_sh4r(R_S);
775 sh4_x86.tstate = TSTATE_C;
776 }
777 break;
778 case 0x5:
779 { /* SETS */
780 STC();
781 SETC_sh4r(R_S);
782 sh4_x86.tstate = TSTATE_C;
783 }
784 break;
785 default:
786 UNDEF();
787 break;
788 }
789 break;
790 case 0x9:
791 switch( (ir&0xF0) >> 4 ) {
792 case 0x0:
793 { /* NOP */
794 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
795 }
796 break;
797 case 0x1:
798 { /* DIV0U */
799 XOR_r32_r32( R_EAX, R_EAX );
800 store_spreg( R_EAX, R_Q );
801 store_spreg( R_EAX, R_M );
802 store_spreg( R_EAX, R_T );
803 sh4_x86.tstate = TSTATE_C; // works for DIV1
804 }
805 break;
806 case 0x2:
807 { /* MOVT Rn */
808 uint32_t Rn = ((ir>>8)&0xF);
809 load_spreg( R_EAX, R_T );
810 store_reg( R_EAX, Rn );
811 }
812 break;
813 default:
814 UNDEF();
815 break;
816 }
817 break;
818 case 0xA:
819 switch( (ir&0xF0) >> 4 ) {
820 case 0x0:
821 { /* STS MACH, Rn */
822 uint32_t Rn = ((ir>>8)&0xF);
823 load_spreg( R_EAX, R_MACH );
824 store_reg( R_EAX, Rn );
825 }
826 break;
827 case 0x1:
828 { /* STS MACL, Rn */
829 uint32_t Rn = ((ir>>8)&0xF);
830 load_spreg( R_EAX, R_MACL );
831 store_reg( R_EAX, Rn );
832 }
833 break;
834 case 0x2:
835 { /* STS PR, Rn */
836 uint32_t Rn = ((ir>>8)&0xF);
837 load_spreg( R_EAX, R_PR );
838 store_reg( R_EAX, Rn );
839 }
840 break;
841 case 0x3:
842 { /* STC SGR, Rn */
843 uint32_t Rn = ((ir>>8)&0xF);
844 check_priv();
845 load_spreg( R_EAX, R_SGR );
846 store_reg( R_EAX, Rn );
847 sh4_x86.tstate = TSTATE_NONE;
848 }
849 break;
850 case 0x5:
851 { /* STS FPUL, Rn */
852 uint32_t Rn = ((ir>>8)&0xF);
853 load_spreg( R_EAX, R_FPUL );
854 store_reg( R_EAX, Rn );
855 }
856 break;
857 case 0x6:
858 { /* STS FPSCR, Rn */
859 uint32_t Rn = ((ir>>8)&0xF);
860 load_spreg( R_EAX, R_FPSCR );
861 store_reg( R_EAX, Rn );
862 }
863 break;
864 case 0xF:
865 { /* STC DBR, Rn */
866 uint32_t Rn = ((ir>>8)&0xF);
867 check_priv();
868 load_spreg( R_EAX, R_DBR );
869 store_reg( R_EAX, Rn );
870 sh4_x86.tstate = TSTATE_NONE;
871 }
872 break;
873 default:
874 UNDEF();
875 break;
876 }
877 break;
878 case 0xB:
879 switch( (ir&0xFF0) >> 4 ) {
880 case 0x0:
881 { /* RTS */
882 if( sh4_x86.in_delay_slot ) {
883 SLOTILLEGAL();
884 } else {
885 load_spreg( R_ECX, R_PR );
886 store_spreg( R_ECX, REG_OFFSET(pc) );
887 sh4_x86.in_delay_slot = TRUE;
888 sh4_x86_translate_instruction(pc+2);
889 exit_block_pcset(pc+2);
890 sh4_x86.branch_taken = TRUE;
891 return 4;
892 }
893 }
894 break;
895 case 0x1:
896 { /* SLEEP */
897 check_priv();
898 call_func0( sh4_sleep );
899 sh4_x86.tstate = TSTATE_NONE;
900 sh4_x86.in_delay_slot = FALSE;
901 return 2;
902 }
903 break;
904 case 0x2:
905 { /* RTE */
906 if( sh4_x86.in_delay_slot ) {
907 SLOTILLEGAL();
908 } else {
909 check_priv();
910 load_spreg( R_ECX, R_SPC );
911 store_spreg( R_ECX, REG_OFFSET(pc) );
912 load_spreg( R_EAX, R_SSR );
913 call_func1( sh4_write_sr, R_EAX );
914 sh4_x86.in_delay_slot = TRUE;
915 sh4_x86.priv_checked = FALSE;
916 sh4_x86.fpuen_checked = FALSE;
917 sh4_x86.tstate = TSTATE_NONE;
918 sh4_x86_translate_instruction(pc+2);
919 exit_block_pcset(pc+2);
920 sh4_x86.branch_taken = TRUE;
921 return 4;
922 }
923 }
924 break;
925 default:
926 UNDEF();
927 break;
928 }
929 break;
930 case 0xC:
931 { /* MOV.B @(R0, Rm), Rn */
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
933 load_reg( R_EAX, 0 );
934 load_reg( R_ECX, Rm );
935 ADD_r32_r32( R_EAX, R_ECX );
936 MEM_READ_BYTE( R_ECX, R_EAX );
937 store_reg( R_EAX, Rn );
938 sh4_x86.tstate = TSTATE_NONE;
939 }
940 break;
941 case 0xD:
942 { /* MOV.W @(R0, Rm), Rn */
943 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
944 load_reg( R_EAX, 0 );
945 load_reg( R_ECX, Rm );
946 ADD_r32_r32( R_EAX, R_ECX );
947 precheck();
948 check_ralign16( R_ECX );
949 MEM_READ_WORD( R_ECX, R_EAX );
950 store_reg( R_EAX, Rn );
951 sh4_x86.tstate = TSTATE_NONE;
952 }
953 break;
954 case 0xE:
955 { /* MOV.L @(R0, Rm), Rn */
956 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
957 load_reg( R_EAX, 0 );
958 load_reg( R_ECX, Rm );
959 ADD_r32_r32( R_EAX, R_ECX );
960 precheck();
961 check_ralign32( R_ECX );
962 MEM_READ_LONG( R_ECX, R_EAX );
963 store_reg( R_EAX, Rn );
964 sh4_x86.tstate = TSTATE_NONE;
965 }
966 break;
967 case 0xF:
968 { /* MAC.L @Rm+, @Rn+ */
969 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
970 load_reg( R_ECX, Rm );
971 precheck();
972 check_ralign32( R_ECX );
973 load_reg( R_ECX, Rn );
974 check_ralign32( R_ECX );
975 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
976 MEM_READ_LONG( R_ECX, R_EAX );
977 PUSH_r32( R_EAX );
978 load_reg( R_ECX, Rm );
979 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
980 MEM_READ_LONG( R_ECX, R_EAX );
981 POP_r32( R_ECX );
982 IMUL_r32( R_ECX );
983 ADD_r32_sh4r( R_EAX, R_MACL );
984 ADC_r32_sh4r( R_EDX, R_MACH );
986 load_spreg( R_ECX, R_S );
987 TEST_r32_r32(R_ECX, R_ECX);
988 JE_rel8( 7, nosat );
989 call_func0( signsat48 );
990 JMP_TARGET( nosat );
991 sh4_x86.tstate = TSTATE_NONE;
992 }
993 break;
994 default:
995 UNDEF();
996 break;
997 }
998 break;
999 case 0x1:
1000 { /* MOV.L Rm, @(disp, Rn) */
1001 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1002 load_reg( R_ECX, Rn );
1003 load_reg( R_EAX, Rm );
1004 ADD_imm32_r32( disp, R_ECX );
1005 precheck();
1006 check_walign32( R_ECX );
1007 MEM_WRITE_LONG( R_ECX, R_EAX );
1008 sh4_x86.tstate = TSTATE_NONE;
1009 }
1010 break;
1011 case 0x2:
1012 switch( ir&0xF ) {
1013 case 0x0:
1014 { /* MOV.B Rm, @Rn */
1015 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1016 load_reg( R_EAX, Rm );
1017 load_reg( R_ECX, Rn );
1018 MEM_WRITE_BYTE( R_ECX, R_EAX );
1019 sh4_x86.tstate = TSTATE_NONE;
1020 }
1021 break;
1022 case 0x1:
1023 { /* MOV.W Rm, @Rn */
1024 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1025 load_reg( R_ECX, Rn );
1026 precheck();
1027 check_walign16( R_ECX );
1028 load_reg( R_EAX, Rm );
1029 MEM_WRITE_WORD( R_ECX, R_EAX );
1030 sh4_x86.tstate = TSTATE_NONE;
1031 }
1032 break;
1033 case 0x2:
1034 { /* MOV.L Rm, @Rn */
1035 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1036 load_reg( R_EAX, Rm );
1037 load_reg( R_ECX, Rn );
1038 precheck();
1039 check_walign32(R_ECX);
1040 MEM_WRITE_LONG( R_ECX, R_EAX );
1041 sh4_x86.tstate = TSTATE_NONE;
1042 }
1043 break;
1044 case 0x4:
1045 { /* MOV.B Rm, @-Rn */
1046 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1047 load_reg( R_EAX, Rm );
1048 load_reg( R_ECX, Rn );
1049 ADD_imm8s_r32( -1, R_ECX );
1050 store_reg( R_ECX, Rn );
1051 MEM_WRITE_BYTE( R_ECX, R_EAX );
1052 sh4_x86.tstate = TSTATE_NONE;
1053 }
1054 break;
1055 case 0x5:
1056 { /* MOV.W Rm, @-Rn */
1057 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1058 load_reg( R_ECX, Rn );
1059 precheck();
1060 check_walign16( R_ECX );
1061 load_reg( R_EAX, Rm );
1062 ADD_imm8s_r32( -2, R_ECX );
1063 store_reg( R_ECX, Rn );
1064 MEM_WRITE_WORD( R_ECX, R_EAX );
1065 sh4_x86.tstate = TSTATE_NONE;
1066 }
1067 break;
1068 case 0x6:
1069 { /* MOV.L Rm, @-Rn */
1070 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1071 load_reg( R_EAX, Rm );
1072 load_reg( R_ECX, Rn );
1073 precheck();
1074 check_walign32( R_ECX );
1075 ADD_imm8s_r32( -4, R_ECX );
1076 store_reg( R_ECX, Rn );
1077 MEM_WRITE_LONG( R_ECX, R_EAX );
1078 sh4_x86.tstate = TSTATE_NONE;
1079 }
1080 break;
1081 case 0x7:
1082 { /* DIV0S Rm, Rn */
1083 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1084 load_reg( R_EAX, Rm );
1085 load_reg( R_ECX, Rn );
1086 SHR_imm8_r32( 31, R_EAX );
1087 SHR_imm8_r32( 31, R_ECX );
1088 store_spreg( R_EAX, R_M );
1089 store_spreg( R_ECX, R_Q );
1090 CMP_r32_r32( R_EAX, R_ECX );
1091 SETNE_t();
1092 sh4_x86.tstate = TSTATE_NE;
1093 }
1094 break;
1095 case 0x8:
1096 { /* TST Rm, Rn */
1097 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1098 load_reg( R_EAX, Rm );
1099 load_reg( R_ECX, Rn );
1100 TEST_r32_r32( R_EAX, R_ECX );
1101 SETE_t();
1102 sh4_x86.tstate = TSTATE_E;
1103 }
1104 break;
1105 case 0x9:
1106 { /* AND Rm, Rn */
1107 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1108 load_reg( R_EAX, Rm );
1109 load_reg( R_ECX, Rn );
1110 AND_r32_r32( R_EAX, R_ECX );
1111 store_reg( R_ECX, Rn );
1112 sh4_x86.tstate = TSTATE_NONE;
1113 }
1114 break;
1115 case 0xA:
1116 { /* XOR Rm, Rn */
1117 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1118 load_reg( R_EAX, Rm );
1119 load_reg( R_ECX, Rn );
1120 XOR_r32_r32( R_EAX, R_ECX );
1121 store_reg( R_ECX, Rn );
1122 sh4_x86.tstate = TSTATE_NONE;
1123 }
1124 break;
1125 case 0xB:
1126 { /* OR Rm, Rn */
1127 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1128 load_reg( R_EAX, Rm );
1129 load_reg( R_ECX, Rn );
1130 OR_r32_r32( R_EAX, R_ECX );
1131 store_reg( R_ECX, Rn );
1132 sh4_x86.tstate = TSTATE_NONE;
1133 }
1134 break;
1135 case 0xC:
1136 { /* CMP/STR Rm, Rn */
1137 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1138 load_reg( R_EAX, Rm );
1139 load_reg( R_ECX, Rn );
1140 XOR_r32_r32( R_ECX, R_EAX );
1141 TEST_r8_r8( R_AL, R_AL );
1142 JE_rel8(13, target1);
1143 TEST_r8_r8( R_AH, R_AH ); // 2
1144 JE_rel8(9, target2);
1145 SHR_imm8_r32( 16, R_EAX ); // 3
1146 TEST_r8_r8( R_AL, R_AL ); // 2
1147 JE_rel8(2, target3);
1148 TEST_r8_r8( R_AH, R_AH ); // 2
1149 JMP_TARGET(target1);
1150 JMP_TARGET(target2);
1151 JMP_TARGET(target3);
1152 SETE_t();
1153 sh4_x86.tstate = TSTATE_E;
1154 }
1155 break;
1156 case 0xD:
1157 { /* XTRCT Rm, Rn */
1158 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1159 load_reg( R_EAX, Rm );
1160 load_reg( R_ECX, Rn );
1161 SHL_imm8_r32( 16, R_EAX );
1162 SHR_imm8_r32( 16, R_ECX );
1163 OR_r32_r32( R_EAX, R_ECX );
1164 store_reg( R_ECX, Rn );
1165 sh4_x86.tstate = TSTATE_NONE;
1166 }
1167 break;
1168 case 0xE:
1169 { /* MULU.W Rm, Rn */
1170 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1171 load_reg16u( R_EAX, Rm );
1172 load_reg16u( R_ECX, Rn );
1173 MUL_r32( R_ECX );
1174 store_spreg( R_EAX, R_MACL );
1175 sh4_x86.tstate = TSTATE_NONE;
1176 }
1177 break;
1178 case 0xF:
1179 { /* MULS.W Rm, Rn */
1180 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1181 load_reg16s( R_EAX, Rm );
1182 load_reg16s( R_ECX, Rn );
1183 MUL_r32( R_ECX );
1184 store_spreg( R_EAX, R_MACL );
1185 sh4_x86.tstate = TSTATE_NONE;
1186 }
1187 break;
1188 default:
1189 UNDEF();
1190 break;
1191 }
1192 break;
1193 case 0x3:
1194 switch( ir&0xF ) {
1195 case 0x0:
1196 { /* CMP/EQ Rm, Rn */
1197 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1198 load_reg( R_EAX, Rm );
1199 load_reg( R_ECX, Rn );
1200 CMP_r32_r32( R_EAX, R_ECX );
1201 SETE_t();
1202 sh4_x86.tstate = TSTATE_E;
1203 }
1204 break;
1205 case 0x2:
1206 { /* CMP/HS Rm, Rn */
1207 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1208 load_reg( R_EAX, Rm );
1209 load_reg( R_ECX, Rn );
1210 CMP_r32_r32( R_EAX, R_ECX );
1211 SETAE_t();
1212 sh4_x86.tstate = TSTATE_AE;
1213 }
1214 break;
1215 case 0x3:
1216 { /* CMP/GE Rm, Rn */
1217 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1218 load_reg( R_EAX, Rm );
1219 load_reg( R_ECX, Rn );
1220 CMP_r32_r32( R_EAX, R_ECX );
1221 SETGE_t();
1222 sh4_x86.tstate = TSTATE_GE;
1223 }
1224 break;
1225 case 0x4:
1226 { /* DIV1 Rm, Rn */
1227 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1228 load_spreg( R_ECX, R_M );
1229 load_reg( R_EAX, Rn );
1230 if( sh4_x86.tstate != TSTATE_C ) {
1231 LDC_t();
1232 }
1233 RCL1_r32( R_EAX );
1234 SETC_r8( R_DL ); // Q'
1235 CMP_sh4r_r32( R_Q, R_ECX );
1236 JE_rel8(5, mqequal);
1237 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1238 JMP_rel8(3, end);
1239 JMP_TARGET(mqequal);
1240 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1241 JMP_TARGET(end);
1242 store_reg( R_EAX, Rn ); // Done with Rn now
1243 SETC_r8(R_AL); // tmp1
1244 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1245 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1246 store_spreg( R_ECX, R_Q );
1247 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1248 MOVZX_r8_r32( R_AL, R_EAX );
1249 store_spreg( R_EAX, R_T );
1250 sh4_x86.tstate = TSTATE_NONE;
1251 }
1252 break;
1253 case 0x5:
1254 { /* DMULU.L Rm, Rn */
1255 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1256 load_reg( R_EAX, Rm );
1257 load_reg( R_ECX, Rn );
1258 MUL_r32(R_ECX);
1259 store_spreg( R_EDX, R_MACH );
1260 store_spreg( R_EAX, R_MACL );
1261 sh4_x86.tstate = TSTATE_NONE;
1262 }
1263 break;
1264 case 0x6:
1265 { /* CMP/HI Rm, Rn */
1266 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1267 load_reg( R_EAX, Rm );
1268 load_reg( R_ECX, Rn );
1269 CMP_r32_r32( R_EAX, R_ECX );
1270 SETA_t();
1271 sh4_x86.tstate = TSTATE_A;
1272 }
1273 break;
1274 case 0x7:
1275 { /* CMP/GT Rm, Rn */
1276 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1277 load_reg( R_EAX, Rm );
1278 load_reg( R_ECX, Rn );
1279 CMP_r32_r32( R_EAX, R_ECX );
1280 SETG_t();
1281 sh4_x86.tstate = TSTATE_G;
1282 }
1283 break;
1284 case 0x8:
1285 { /* SUB Rm, Rn */
1286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1287 load_reg( R_EAX, Rm );
1288 load_reg( R_ECX, Rn );
1289 SUB_r32_r32( R_EAX, R_ECX );
1290 store_reg( R_ECX, Rn );
1291 sh4_x86.tstate = TSTATE_NONE;
1292 }
1293 break;
1294 case 0xA:
1295 { /* SUBC Rm, Rn */
1296 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1297 load_reg( R_EAX, Rm );
1298 load_reg( R_ECX, Rn );
1299 if( sh4_x86.tstate != TSTATE_C ) {
1300 LDC_t();
1301 }
1302 SBB_r32_r32( R_EAX, R_ECX );
1303 store_reg( R_ECX, Rn );
1304 SETC_t();
1305 sh4_x86.tstate = TSTATE_C;
1306 }
1307 break;
1308 case 0xB:
1309 { /* SUBV Rm, Rn */
1310 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1311 load_reg( R_EAX, Rm );
1312 load_reg( R_ECX, Rn );
1313 SUB_r32_r32( R_EAX, R_ECX );
1314 store_reg( R_ECX, Rn );
1315 SETO_t();
1316 sh4_x86.tstate = TSTATE_O;
1317 }
1318 break;
1319 case 0xC:
1320 { /* ADD Rm, Rn */
1321 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1322 load_reg( R_EAX, Rm );
1323 load_reg( R_ECX, Rn );
1324 ADD_r32_r32( R_EAX, R_ECX );
1325 store_reg( R_ECX, Rn );
1326 sh4_x86.tstate = TSTATE_NONE;
1327 }
1328 break;
1329 case 0xD:
1330 { /* DMULS.L Rm, Rn */
1331 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1332 load_reg( R_EAX, Rm );
1333 load_reg( R_ECX, Rn );
1334 IMUL_r32(R_ECX);
1335 store_spreg( R_EDX, R_MACH );
1336 store_spreg( R_EAX, R_MACL );
1337 sh4_x86.tstate = TSTATE_NONE;
1338 }
1339 break;
1340 case 0xE:
1341 { /* ADDC Rm, Rn */
1342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1343 if( sh4_x86.tstate != TSTATE_C ) {
1344 LDC_t();
1345 }
1346 load_reg( R_EAX, Rm );
1347 load_reg( R_ECX, Rn );
1348 ADC_r32_r32( R_EAX, R_ECX );
1349 store_reg( R_ECX, Rn );
1350 SETC_t();
1351 sh4_x86.tstate = TSTATE_C;
1352 }
1353 break;
1354 case 0xF:
1355 { /* ADDV Rm, Rn */
1356 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1357 load_reg( R_EAX, Rm );
1358 load_reg( R_ECX, Rn );
1359 ADD_r32_r32( R_EAX, R_ECX );
1360 store_reg( R_ECX, Rn );
1361 SETO_t();
1362 sh4_x86.tstate = TSTATE_O;
1363 }
1364 break;
1365 default:
1366 UNDEF();
1367 break;
1368 }
1369 break;
1370 case 0x4:
1371 switch( ir&0xF ) {
1372 case 0x0:
1373 switch( (ir&0xF0) >> 4 ) {
1374 case 0x0:
1375 { /* SHLL Rn */
1376 uint32_t Rn = ((ir>>8)&0xF);
1377 load_reg( R_EAX, Rn );
1378 SHL1_r32( R_EAX );
1379 SETC_t();
1380 store_reg( R_EAX, Rn );
1381 sh4_x86.tstate = TSTATE_C;
1382 }
1383 break;
1384 case 0x1:
1385 { /* DT Rn */
1386 uint32_t Rn = ((ir>>8)&0xF);
1387 load_reg( R_EAX, Rn );
1388 ADD_imm8s_r32( -1, R_EAX );
1389 store_reg( R_EAX, Rn );
1390 SETE_t();
1391 sh4_x86.tstate = TSTATE_E;
1392 }
1393 break;
1394 case 0x2:
1395 { /* SHAL Rn */
1396 uint32_t Rn = ((ir>>8)&0xF);
1397 load_reg( R_EAX, Rn );
1398 SHL1_r32( R_EAX );
1399 SETC_t();
1400 store_reg( R_EAX, Rn );
1401 sh4_x86.tstate = TSTATE_C;
1402 }
1403 break;
1404 default:
1405 UNDEF();
1406 break;
1407 }
1408 break;
1409 case 0x1:
1410 switch( (ir&0xF0) >> 4 ) {
1411 case 0x0:
1412 { /* SHLR Rn */
1413 uint32_t Rn = ((ir>>8)&0xF);
1414 load_reg( R_EAX, Rn );
1415 SHR1_r32( R_EAX );
1416 SETC_t();
1417 store_reg( R_EAX, Rn );
1418 sh4_x86.tstate = TSTATE_C;
1419 }
1420 break;
1421 case 0x1:
1422 { /* CMP/PZ Rn */
1423 uint32_t Rn = ((ir>>8)&0xF);
1424 load_reg( R_EAX, Rn );
1425 CMP_imm8s_r32( 0, R_EAX );
1426 SETGE_t();
1427 sh4_x86.tstate = TSTATE_GE;
1428 }
1429 break;
1430 case 0x2:
1431 { /* SHAR Rn */
1432 uint32_t Rn = ((ir>>8)&0xF);
1433 load_reg( R_EAX, Rn );
1434 SAR1_r32( R_EAX );
1435 SETC_t();
1436 store_reg( R_EAX, Rn );
1437 sh4_x86.tstate = TSTATE_C;
1438 }
1439 break;
1440 default:
1441 UNDEF();
1442 break;
1443 }
1444 break;
1445 case 0x2:
1446 switch( (ir&0xF0) >> 4 ) {
1447 case 0x0:
1448 { /* STS.L MACH, @-Rn */
1449 uint32_t Rn = ((ir>>8)&0xF);
1450 load_reg( R_ECX, Rn );
1451 precheck();
1452 check_walign32( R_ECX );
1453 ADD_imm8s_r32( -4, R_ECX );
1454 store_reg( R_ECX, Rn );
1455 load_spreg( R_EAX, R_MACH );
1456 MEM_WRITE_LONG( R_ECX, R_EAX );
1457 sh4_x86.tstate = TSTATE_NONE;
1458 }
1459 break;
1460 case 0x1:
1461 { /* STS.L MACL, @-Rn */
1462 uint32_t Rn = ((ir>>8)&0xF);
1463 load_reg( R_ECX, Rn );
1464 precheck();
1465 check_walign32( R_ECX );
1466 ADD_imm8s_r32( -4, R_ECX );
1467 store_reg( R_ECX, Rn );
1468 load_spreg( R_EAX, R_MACL );
1469 MEM_WRITE_LONG( R_ECX, R_EAX );
1470 sh4_x86.tstate = TSTATE_NONE;
1471 }
1472 break;
1473 case 0x2:
1474 { /* STS.L PR, @-Rn */
1475 uint32_t Rn = ((ir>>8)&0xF);
1476 load_reg( R_ECX, Rn );
1477 precheck();
1478 check_walign32( R_ECX );
1479 ADD_imm8s_r32( -4, R_ECX );
1480 store_reg( R_ECX, Rn );
1481 load_spreg( R_EAX, R_PR );
1482 MEM_WRITE_LONG( R_ECX, R_EAX );
1483 sh4_x86.tstate = TSTATE_NONE;
1484 }
1485 break;
1486 case 0x3:
1487 { /* STC.L SGR, @-Rn */
1488 uint32_t Rn = ((ir>>8)&0xF);
1489 precheck();
1490 check_priv_no_precheck();
1491 load_reg( R_ECX, Rn );
1492 check_walign32( R_ECX );
1493 ADD_imm8s_r32( -4, R_ECX );
1494 store_reg( R_ECX, Rn );
1495 load_spreg( R_EAX, R_SGR );
1496 MEM_WRITE_LONG( R_ECX, R_EAX );
1497 sh4_x86.tstate = TSTATE_NONE;
1498 }
1499 break;
1500 case 0x5:
1501 { /* STS.L FPUL, @-Rn */
1502 uint32_t Rn = ((ir>>8)&0xF);
1503 load_reg( R_ECX, Rn );
1504 precheck();
1505 check_walign32( R_ECX );
1506 ADD_imm8s_r32( -4, R_ECX );
1507 store_reg( R_ECX, Rn );
1508 load_spreg( R_EAX, R_FPUL );
1509 MEM_WRITE_LONG( R_ECX, R_EAX );
1510 sh4_x86.tstate = TSTATE_NONE;
1511 }
1512 break;
1513 case 0x6:
1514 { /* STS.L FPSCR, @-Rn */
1515 uint32_t Rn = ((ir>>8)&0xF);
1516 load_reg( R_ECX, Rn );
1517 precheck();
1518 check_walign32( R_ECX );
1519 ADD_imm8s_r32( -4, R_ECX );
1520 store_reg( R_ECX, Rn );
1521 load_spreg( R_EAX, R_FPSCR );
1522 MEM_WRITE_LONG( R_ECX, R_EAX );
1523 sh4_x86.tstate = TSTATE_NONE;
1524 }
1525 break;
1526 case 0xF:
1527 { /* STC.L DBR, @-Rn */
1528 uint32_t Rn = ((ir>>8)&0xF);
1529 precheck();
1530 check_priv_no_precheck();
1531 load_reg( R_ECX, Rn );
1532 check_walign32( R_ECX );
1533 ADD_imm8s_r32( -4, R_ECX );
1534 store_reg( R_ECX, Rn );
1535 load_spreg( R_EAX, R_DBR );
1536 MEM_WRITE_LONG( R_ECX, R_EAX );
1537 sh4_x86.tstate = TSTATE_NONE;
1538 }
1539 break;
1540 default:
1541 UNDEF();
1542 break;
1543 }
1544 break;
1545 case 0x3:
1546 switch( (ir&0x80) >> 7 ) {
1547 case 0x0:
1548 switch( (ir&0x70) >> 4 ) {
1549 case 0x0:
1550 { /* STC.L SR, @-Rn */
1551 uint32_t Rn = ((ir>>8)&0xF);
1552 precheck();
1553 check_priv_no_precheck();
1554 call_func0( sh4_read_sr );
1555 load_reg( R_ECX, Rn );
1556 check_walign32( R_ECX );
1557 ADD_imm8s_r32( -4, R_ECX );
1558 store_reg( R_ECX, Rn );
1559 MEM_WRITE_LONG( R_ECX, R_EAX );
1560 sh4_x86.tstate = TSTATE_NONE;
1561 }
1562 break;
1563 case 0x1:
1564 { /* STC.L GBR, @-Rn */
1565 uint32_t Rn = ((ir>>8)&0xF);
1566 load_reg( R_ECX, Rn );
1567 precheck();
1568 check_walign32( R_ECX );
1569 ADD_imm8s_r32( -4, R_ECX );
1570 store_reg( R_ECX, Rn );
1571 load_spreg( R_EAX, R_GBR );
1572 MEM_WRITE_LONG( R_ECX, R_EAX );
1573 sh4_x86.tstate = TSTATE_NONE;
1574 }
1575 break;
1576 case 0x2:
1577 { /* STC.L VBR, @-Rn */
1578 uint32_t Rn = ((ir>>8)&0xF);
1579 precheck();
1580 check_priv_no_precheck();
1581 load_reg( R_ECX, Rn );
1582 check_walign32( R_ECX );
1583 ADD_imm8s_r32( -4, R_ECX );
1584 store_reg( R_ECX, Rn );
1585 load_spreg( R_EAX, R_VBR );
1586 MEM_WRITE_LONG( R_ECX, R_EAX );
1587 sh4_x86.tstate = TSTATE_NONE;
1588 }
1589 break;
1590 case 0x3:
1591 { /* STC.L SSR, @-Rn */
1592 uint32_t Rn = ((ir>>8)&0xF);
1593 precheck();
1594 check_priv_no_precheck();
1595 load_reg( R_ECX, Rn );
1596 check_walign32( R_ECX );
1597 ADD_imm8s_r32( -4, R_ECX );
1598 store_reg( R_ECX, Rn );
1599 load_spreg( R_EAX, R_SSR );
1600 MEM_WRITE_LONG( R_ECX, R_EAX );
1601 sh4_x86.tstate = TSTATE_NONE;
1602 }
1603 break;
1604 case 0x4:
1605 { /* STC.L SPC, @-Rn */
1606 uint32_t Rn = ((ir>>8)&0xF);
1607 precheck();
1608 check_priv_no_precheck();
1609 load_reg( R_ECX, Rn );
1610 check_walign32( R_ECX );
1611 ADD_imm8s_r32( -4, R_ECX );
1612 store_reg( R_ECX, Rn );
1613 load_spreg( R_EAX, R_SPC );
1614 MEM_WRITE_LONG( R_ECX, R_EAX );
1615 sh4_x86.tstate = TSTATE_NONE;
1616 }
1617 break;
1618 default:
1619 UNDEF();
1620 break;
1621 }
1622 break;
1623 case 0x1:
1624 { /* STC.L Rm_BANK, @-Rn */
1625 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1626 precheck();
1627 check_priv_no_precheck();
1628 load_reg( R_ECX, Rn );
1629 check_walign32( R_ECX );
1630 ADD_imm8s_r32( -4, R_ECX );
1631 store_reg( R_ECX, Rn );
1632 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1633 MEM_WRITE_LONG( R_ECX, R_EAX );
1634 sh4_x86.tstate = TSTATE_NONE;
1635 }
1636 break;
1637 }
1638 break;
1639 case 0x4:
1640 switch( (ir&0xF0) >> 4 ) {
1641 case 0x0:
1642 { /* ROTL Rn */
1643 uint32_t Rn = ((ir>>8)&0xF);
1644 load_reg( R_EAX, Rn );
1645 ROL1_r32( R_EAX );
1646 store_reg( R_EAX, Rn );
1647 SETC_t();
1648 sh4_x86.tstate = TSTATE_C;
1649 }
1650 break;
1651 case 0x2:
1652 { /* ROTCL Rn */
1653 uint32_t Rn = ((ir>>8)&0xF);
1654 load_reg( R_EAX, Rn );
1655 if( sh4_x86.tstate != TSTATE_C ) {
1656 LDC_t();
1657 }
1658 RCL1_r32( R_EAX );
1659 store_reg( R_EAX, Rn );
1660 SETC_t();
1661 sh4_x86.tstate = TSTATE_C;
1662 }
1663 break;
1664 default:
1665 UNDEF();
1666 break;
1667 }
1668 break;
1669 case 0x5:
1670 switch( (ir&0xF0) >> 4 ) {
1671 case 0x0:
1672 { /* ROTR Rn */
1673 uint32_t Rn = ((ir>>8)&0xF);
1674 load_reg( R_EAX, Rn );
1675 ROR1_r32( R_EAX );
1676 store_reg( R_EAX, Rn );
1677 SETC_t();
1678 sh4_x86.tstate = TSTATE_C;
1679 }
1680 break;
1681 case 0x1:
1682 { /* CMP/PL Rn */
1683 uint32_t Rn = ((ir>>8)&0xF);
1684 load_reg( R_EAX, Rn );
1685 CMP_imm8s_r32( 0, R_EAX );
1686 SETG_t();
1687 sh4_x86.tstate = TSTATE_G;
1688 }
1689 break;
1690 case 0x2:
1691 { /* ROTCR Rn */
1692 uint32_t Rn = ((ir>>8)&0xF);
1693 load_reg( R_EAX, Rn );
1694 if( sh4_x86.tstate != TSTATE_C ) {
1695 LDC_t();
1696 }
1697 RCR1_r32( R_EAX );
1698 store_reg( R_EAX, Rn );
1699 SETC_t();
1700 sh4_x86.tstate = TSTATE_C;
1701 }
1702 break;
1703 default:
1704 UNDEF();
1705 break;
1706 }
1707 break;
1708 case 0x6:
1709 switch( (ir&0xF0) >> 4 ) {
1710 case 0x0:
1711 { /* LDS.L @Rm+, MACH */
1712 uint32_t Rm = ((ir>>8)&0xF);
1713 load_reg( R_EAX, Rm );
1714 precheck();
1715 check_ralign32( R_EAX );
1716 MOV_r32_r32( R_EAX, R_ECX );
1717 ADD_imm8s_r32( 4, R_EAX );
1718 store_reg( R_EAX, Rm );
1719 MEM_READ_LONG( R_ECX, R_EAX );
1720 store_spreg( R_EAX, R_MACH );
1721 sh4_x86.tstate = TSTATE_NONE;
1722 }
1723 break;
1724 case 0x1:
1725 { /* LDS.L @Rm+, MACL */
1726 uint32_t Rm = ((ir>>8)&0xF);
1727 load_reg( R_EAX, Rm );
1728 precheck();
1729 check_ralign32( R_EAX );
1730 MOV_r32_r32( R_EAX, R_ECX );
1731 ADD_imm8s_r32( 4, R_EAX );
1732 store_reg( R_EAX, Rm );
1733 MEM_READ_LONG( R_ECX, R_EAX );
1734 store_spreg( R_EAX, R_MACL );
1735 sh4_x86.tstate = TSTATE_NONE;
1736 }
1737 break;
1738 case 0x2:
1739 { /* LDS.L @Rm+, PR */
1740 uint32_t Rm = ((ir>>8)&0xF);
1741 load_reg( R_EAX, Rm );
1742 precheck();
1743 check_ralign32( R_EAX );
1744 MOV_r32_r32( R_EAX, R_ECX );
1745 ADD_imm8s_r32( 4, R_EAX );
1746 store_reg( R_EAX, Rm );
1747 MEM_READ_LONG( R_ECX, R_EAX );
1748 store_spreg( R_EAX, R_PR );
1749 sh4_x86.tstate = TSTATE_NONE;
1750 }
1751 break;
1752 case 0x3:
1753 { /* LDC.L @Rm+, SGR */
1754 uint32_t Rm = ((ir>>8)&0xF);
1755 precheck();
1756 check_priv_no_precheck();
1757 load_reg( R_EAX, Rm );
1758 check_ralign32( R_EAX );
1759 MOV_r32_r32( R_EAX, R_ECX );
1760 ADD_imm8s_r32( 4, R_EAX );
1761 store_reg( R_EAX, Rm );
1762 MEM_READ_LONG( R_ECX, R_EAX );
1763 store_spreg( R_EAX, R_SGR );
1764 sh4_x86.tstate = TSTATE_NONE;
1765 }
1766 break;
1767 case 0x5:
1768 { /* LDS.L @Rm+, FPUL */
1769 uint32_t Rm = ((ir>>8)&0xF);
1770 load_reg( R_EAX, Rm );
1771 precheck();
1772 check_ralign32( R_EAX );
1773 MOV_r32_r32( R_EAX, R_ECX );
1774 ADD_imm8s_r32( 4, R_EAX );
1775 store_reg( R_EAX, Rm );
1776 MEM_READ_LONG( R_ECX, R_EAX );
1777 store_spreg( R_EAX, R_FPUL );
1778 sh4_x86.tstate = TSTATE_NONE;
1779 }
1780 break;
1781 case 0x6:
1782 { /* LDS.L @Rm+, FPSCR */
1783 uint32_t Rm = ((ir>>8)&0xF);
1784 load_reg( R_EAX, Rm );
1785 precheck();
1786 check_ralign32( R_EAX );
1787 MOV_r32_r32( R_EAX, R_ECX );
1788 ADD_imm8s_r32( 4, R_EAX );
1789 store_reg( R_EAX, Rm );
1790 MEM_READ_LONG( R_ECX, R_EAX );
1791 store_spreg( R_EAX, R_FPSCR );
1792 update_fr_bank( R_EAX );
1793 sh4_x86.tstate = TSTATE_NONE;
1794 }
1795 break;
1796 case 0xF:
1797 { /* LDC.L @Rm+, DBR */
1798 uint32_t Rm = ((ir>>8)&0xF);
1799 precheck();
1800 check_priv_no_precheck();
1801 load_reg( R_EAX, Rm );
1802 check_ralign32( R_EAX );
1803 MOV_r32_r32( R_EAX, R_ECX );
1804 ADD_imm8s_r32( 4, R_EAX );
1805 store_reg( R_EAX, Rm );
1806 MEM_READ_LONG( R_ECX, R_EAX );
1807 store_spreg( R_EAX, R_DBR );
1808 sh4_x86.tstate = TSTATE_NONE;
1809 }
1810 break;
1811 default:
1812 UNDEF();
1813 break;
1814 }
1815 break;
1816 case 0x7:
1817 switch( (ir&0x80) >> 7 ) {
1818 case 0x0:
1819 switch( (ir&0x70) >> 4 ) {
1820 case 0x0:
1821 { /* LDC.L @Rm+, SR */
1822 uint32_t Rm = ((ir>>8)&0xF);
1823 if( sh4_x86.in_delay_slot ) {
1824 SLOTILLEGAL();
1825 } else {
1826 precheck();
1827 check_priv_no_precheck();
1828 load_reg( R_EAX, Rm );
1829 check_ralign32( R_EAX );
1830 MOV_r32_r32( R_EAX, R_ECX );
1831 ADD_imm8s_r32( 4, R_EAX );
1832 store_reg( R_EAX, Rm );
1833 MEM_READ_LONG( R_ECX, R_EAX );
1834 call_func1( sh4_write_sr, R_EAX );
1835 sh4_x86.priv_checked = FALSE;
1836 sh4_x86.fpuen_checked = FALSE;
1837 sh4_x86.tstate = TSTATE_NONE;
1838 }
1839 }
1840 break;
1841 case 0x1:
1842 { /* LDC.L @Rm+, GBR */
1843 uint32_t Rm = ((ir>>8)&0xF);
1844 load_reg( R_EAX, Rm );
1845 precheck();
1846 check_ralign32( R_EAX );
1847 MOV_r32_r32( R_EAX, R_ECX );
1848 ADD_imm8s_r32( 4, R_EAX );
1849 store_reg( R_EAX, Rm );
1850 MEM_READ_LONG( R_ECX, R_EAX );
1851 store_spreg( R_EAX, R_GBR );
1852 sh4_x86.tstate = TSTATE_NONE;
1853 }
1854 break;
1855 case 0x2:
1856 { /* LDC.L @Rm+, VBR */
1857 uint32_t Rm = ((ir>>8)&0xF);
1858 precheck();
1859 check_priv_no_precheck();
1860 load_reg( R_EAX, Rm );
1861 check_ralign32( R_EAX );
1862 MOV_r32_r32( R_EAX, R_ECX );
1863 ADD_imm8s_r32( 4, R_EAX );
1864 store_reg( R_EAX, Rm );
1865 MEM_READ_LONG( R_ECX, R_EAX );
1866 store_spreg( R_EAX, R_VBR );
1867 sh4_x86.tstate = TSTATE_NONE;
1868 }
1869 break;
1870 case 0x3:
1871 { /* LDC.L @Rm+, SSR */
1872 uint32_t Rm = ((ir>>8)&0xF);
1873 precheck();
1874 check_priv_no_precheck();
1875 load_reg( R_EAX, Rm );
1876 check_ralign32( R_EAX );
1877 MOV_r32_r32( R_EAX, R_ECX );
1878 ADD_imm8s_r32( 4, R_EAX );
1879 store_reg( R_EAX, Rm );
1880 MEM_READ_LONG( R_ECX, R_EAX );
1881 store_spreg( R_EAX, R_SSR );
1882 sh4_x86.tstate = TSTATE_NONE;
1883 }
1884 break;
1885 case 0x4:
1886 { /* LDC.L @Rm+, SPC */
1887 uint32_t Rm = ((ir>>8)&0xF);
1888 precheck();
1889 check_priv_no_precheck();
1890 load_reg( R_EAX, Rm );
1891 check_ralign32( R_EAX );
1892 MOV_r32_r32( R_EAX, R_ECX );
1893 ADD_imm8s_r32( 4, R_EAX );
1894 store_reg( R_EAX, Rm );
1895 MEM_READ_LONG( R_ECX, R_EAX );
1896 store_spreg( R_EAX, R_SPC );
1897 sh4_x86.tstate = TSTATE_NONE;
1898 }
1899 break;
1900 default:
1901 UNDEF();
1902 break;
1903 }
1904 break;
1905 case 0x1:
1906 { /* LDC.L @Rm+, Rn_BANK */
1907 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1908 precheck();
1909 check_priv_no_precheck();
1910 load_reg( R_EAX, Rm );
1911 check_ralign32( R_EAX );
1912 MOV_r32_r32( R_EAX, R_ECX );
1913 ADD_imm8s_r32( 4, R_EAX );
1914 store_reg( R_EAX, Rm );
1915 MEM_READ_LONG( R_ECX, R_EAX );
1916 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1917 sh4_x86.tstate = TSTATE_NONE;
1918 }
1919 break;
1920 }
1921 break;
1922 case 0x8:
1923 switch( (ir&0xF0) >> 4 ) {
1924 case 0x0:
1925 { /* SHLL2 Rn */
1926 uint32_t Rn = ((ir>>8)&0xF);
1927 load_reg( R_EAX, Rn );
1928 SHL_imm8_r32( 2, R_EAX );
1929 store_reg( R_EAX, Rn );
1930 sh4_x86.tstate = TSTATE_NONE;
1931 }
1932 break;
1933 case 0x1:
1934 { /* SHLL8 Rn */
1935 uint32_t Rn = ((ir>>8)&0xF);
1936 load_reg( R_EAX, Rn );
1937 SHL_imm8_r32( 8, R_EAX );
1938 store_reg( R_EAX, Rn );
1939 sh4_x86.tstate = TSTATE_NONE;
1940 }
1941 break;
1942 case 0x2:
1943 { /* SHLL16 Rn */
1944 uint32_t Rn = ((ir>>8)&0xF);
1945 load_reg( R_EAX, Rn );
1946 SHL_imm8_r32( 16, R_EAX );
1947 store_reg( R_EAX, Rn );
1948 sh4_x86.tstate = TSTATE_NONE;
1949 }
1950 break;
1951 default:
1952 UNDEF();
1953 break;
1954 }
1955 break;
1956 case 0x9:
1957 switch( (ir&0xF0) >> 4 ) {
1958 case 0x0:
1959 { /* SHLR2 Rn */
1960 uint32_t Rn = ((ir>>8)&0xF);
1961 load_reg( R_EAX, Rn );
1962 SHR_imm8_r32( 2, R_EAX );
1963 store_reg( R_EAX, Rn );
1964 sh4_x86.tstate = TSTATE_NONE;
1965 }
1966 break;
1967 case 0x1:
1968 { /* SHLR8 Rn */
1969 uint32_t Rn = ((ir>>8)&0xF);
1970 load_reg( R_EAX, Rn );
1971 SHR_imm8_r32( 8, R_EAX );
1972 store_reg( R_EAX, Rn );
1973 sh4_x86.tstate = TSTATE_NONE;
1974 }
1975 break;
1976 case 0x2:
1977 { /* SHLR16 Rn */
1978 uint32_t Rn = ((ir>>8)&0xF);
1979 load_reg( R_EAX, Rn );
1980 SHR_imm8_r32( 16, R_EAX );
1981 store_reg( R_EAX, Rn );
1982 sh4_x86.tstate = TSTATE_NONE;
1983 }
1984 break;
1985 default:
1986 UNDEF();
1987 break;
1988 }
1989 break;
1990 case 0xA:
1991 switch( (ir&0xF0) >> 4 ) {
1992 case 0x0:
1993 { /* LDS Rm, MACH */
1994 uint32_t Rm = ((ir>>8)&0xF);
1995 load_reg( R_EAX, Rm );
1996 store_spreg( R_EAX, R_MACH );
1997 }
1998 break;
1999 case 0x1:
2000 { /* LDS Rm, MACL */
2001 uint32_t Rm = ((ir>>8)&0xF);
2002 load_reg( R_EAX, Rm );
2003 store_spreg( R_EAX, R_MACL );
2004 }
2005 break;
2006 case 0x2:
2007 { /* LDS Rm, PR */
2008 uint32_t Rm = ((ir>>8)&0xF);
2009 load_reg( R_EAX, Rm );
2010 store_spreg( R_EAX, R_PR );
2011 }
2012 break;
2013 case 0x3:
2014 { /* LDC Rm, SGR */
2015 uint32_t Rm = ((ir>>8)&0xF);
2016 check_priv();
2017 load_reg( R_EAX, Rm );
2018 store_spreg( R_EAX, R_SGR );
2019 sh4_x86.tstate = TSTATE_NONE;
2020 }
2021 break;
2022 case 0x5:
2023 { /* LDS Rm, FPUL */
2024 uint32_t Rm = ((ir>>8)&0xF);
2025 load_reg( R_EAX, Rm );
2026 store_spreg( R_EAX, R_FPUL );
2027 }
2028 break;
2029 case 0x6:
2030 { /* LDS Rm, FPSCR */
2031 uint32_t Rm = ((ir>>8)&0xF);
2032 load_reg( R_EAX, Rm );
2033 store_spreg( R_EAX, R_FPSCR );
2034 update_fr_bank( R_EAX );
2035 sh4_x86.tstate = TSTATE_NONE;
2036 }
2037 break;
2038 case 0xF:
2039 { /* LDC Rm, DBR */
2040 uint32_t Rm = ((ir>>8)&0xF);
2041 check_priv();
2042 load_reg( R_EAX, Rm );
2043 store_spreg( R_EAX, R_DBR );
2044 sh4_x86.tstate = TSTATE_NONE;
2045 }
2046 break;
2047 default:
2048 UNDEF();
2049 break;
2050 }
2051 break;
2052 case 0xB:
2053 switch( (ir&0xF0) >> 4 ) {
2054 case 0x0:
2055 { /* JSR @Rn */
2056 uint32_t Rn = ((ir>>8)&0xF);
2057 if( sh4_x86.in_delay_slot ) {
2058 SLOTILLEGAL();
2059 } else {
2060 load_imm32( R_EAX, pc + 4 );
2061 store_spreg( R_EAX, R_PR );
2062 load_reg( R_ECX, Rn );
2063 store_spreg( R_ECX, REG_OFFSET(pc) );
2064 sh4_x86.in_delay_slot = TRUE;
2065 sh4_x86_translate_instruction(pc+2);
2066 exit_block_pcset(pc+2);
2067 sh4_x86.branch_taken = TRUE;
2068 return 4;
2069 }
2070 }
2071 break;
2072 case 0x1:
2073 { /* TAS.B @Rn */
2074 uint32_t Rn = ((ir>>8)&0xF);
2075 load_reg( R_ECX, Rn );
2076 MEM_READ_BYTE( R_ECX, R_EAX );
2077 TEST_r8_r8( R_AL, R_AL );
2078 SETE_t();
2079 OR_imm8_r8( 0x80, R_AL );
2080 load_reg( R_ECX, Rn );
2081 MEM_WRITE_BYTE( R_ECX, R_EAX );
2082 sh4_x86.tstate = TSTATE_NONE;
2083 }
2084 break;
2085 case 0x2:
2086 { /* JMP @Rn */
2087 uint32_t Rn = ((ir>>8)&0xF);
2088 if( sh4_x86.in_delay_slot ) {
2089 SLOTILLEGAL();
2090 } else {
2091 load_reg( R_ECX, Rn );
2092 store_spreg( R_ECX, REG_OFFSET(pc) );
2093 sh4_x86.in_delay_slot = TRUE;
2094 sh4_x86_translate_instruction(pc+2);
2095 exit_block_pcset(pc+2);
2096 sh4_x86.branch_taken = TRUE;
2097 return 4;
2098 }
2099 }
2100 break;
2101 default:
2102 UNDEF();
2103 break;
2104 }
2105 break;
2106 case 0xC:
2107 { /* SHAD Rm, Rn */
2108 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2109 /* Annoyingly enough, not directly convertible */
2110 load_reg( R_EAX, Rn );
2111 load_reg( R_ECX, Rm );
2112 CMP_imm32_r32( 0, R_ECX );
2113 JGE_rel8(16, doshl);
2115 NEG_r32( R_ECX ); // 2
2116 AND_imm8_r8( 0x1F, R_CL ); // 3
2117 JE_rel8( 4, emptysar); // 2
2118 SAR_r32_CL( R_EAX ); // 2
2119 JMP_rel8(10, end); // 2
2121 JMP_TARGET(emptysar);
2122 SAR_imm8_r32(31, R_EAX ); // 3
2123 JMP_rel8(5, end2);
2125 JMP_TARGET(doshl);
2126 AND_imm8_r8( 0x1F, R_CL ); // 3
2127 SHL_r32_CL( R_EAX ); // 2
2128 JMP_TARGET(end);
2129 JMP_TARGET(end2);
2130 store_reg( R_EAX, Rn );
2131 sh4_x86.tstate = TSTATE_NONE;
2132 }
2133 break;
2134 case 0xD:
2135 { /* SHLD Rm, Rn */
2136 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2137 load_reg( R_EAX, Rn );
2138 load_reg( R_ECX, Rm );
2139 CMP_imm32_r32( 0, R_ECX );
2140 JGE_rel8(15, doshl);
2142 NEG_r32( R_ECX ); // 2
2143 AND_imm8_r8( 0x1F, R_CL ); // 3
2144 JE_rel8( 4, emptyshr );
2145 SHR_r32_CL( R_EAX ); // 2
2146 JMP_rel8(9, end); // 2
2148 JMP_TARGET(emptyshr);
2149 XOR_r32_r32( R_EAX, R_EAX );
2150 JMP_rel8(5, end2);
2152 JMP_TARGET(doshl);
2153 AND_imm8_r8( 0x1F, R_CL ); // 3
2154 SHL_r32_CL( R_EAX ); // 2
2155 JMP_TARGET(end);
2156 JMP_TARGET(end2);
2157 store_reg( R_EAX, Rn );
2158 sh4_x86.tstate = TSTATE_NONE;
2159 }
2160 break;
2161 case 0xE:
2162 switch( (ir&0x80) >> 7 ) {
2163 case 0x0:
2164 switch( (ir&0x70) >> 4 ) {
2165 case 0x0:
2166 { /* LDC Rm, SR */
2167 uint32_t Rm = ((ir>>8)&0xF);
2168 if( sh4_x86.in_delay_slot ) {
2169 SLOTILLEGAL();
2170 } else {
2171 check_priv();
2172 load_reg( R_EAX, Rm );
2173 call_func1( sh4_write_sr, R_EAX );
2174 sh4_x86.priv_checked = FALSE;
2175 sh4_x86.fpuen_checked = FALSE;
2176 sh4_x86.tstate = TSTATE_NONE;
2177 }
2178 }
2179 break;
2180 case 0x1:
2181 { /* LDC Rm, GBR */
2182 uint32_t Rm = ((ir>>8)&0xF);
2183 load_reg( R_EAX, Rm );
2184 store_spreg( R_EAX, R_GBR );
2185 }
2186 break;
2187 case 0x2:
2188 { /* LDC Rm, VBR */
2189 uint32_t Rm = ((ir>>8)&0xF);
2190 check_priv();
2191 load_reg( R_EAX, Rm );
2192 store_spreg( R_EAX, R_VBR );
2193 sh4_x86.tstate = TSTATE_NONE;
2194 }
2195 break;
2196 case 0x3:
2197 { /* LDC Rm, SSR */
2198 uint32_t Rm = ((ir>>8)&0xF);
2199 check_priv();
2200 load_reg( R_EAX, Rm );
2201 store_spreg( R_EAX, R_SSR );
2202 sh4_x86.tstate = TSTATE_NONE;
2203 }
2204 break;
2205 case 0x4:
2206 { /* LDC Rm, SPC */
2207 uint32_t Rm = ((ir>>8)&0xF);
2208 check_priv();
2209 load_reg( R_EAX, Rm );
2210 store_spreg( R_EAX, R_SPC );
2211 sh4_x86.tstate = TSTATE_NONE;
2212 }
2213 break;
2214 default:
2215 UNDEF();
2216 break;
2217 }
2218 break;
2219 case 0x1:
2220 { /* LDC Rm, Rn_BANK */
2221 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2222 check_priv();
2223 load_reg( R_EAX, Rm );
2224 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2225 sh4_x86.tstate = TSTATE_NONE;
2226 }
2227 break;
2228 }
2229 break;
2230 case 0xF:
2231 { /* MAC.W @Rm+, @Rn+ */
2232 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2233 load_reg( R_ECX, Rm );
2234 precheck();
2235 check_ralign16( R_ECX );
2236 load_reg( R_ECX, Rn );
2237 check_ralign16( R_ECX );
2238 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2239 MEM_READ_WORD( R_ECX, R_EAX );
2240 PUSH_r32( R_EAX );
2241 load_reg( R_ECX, Rm );
2242 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2243 MEM_READ_WORD( R_ECX, R_EAX );
2244 POP_r32( R_ECX );
2245 IMUL_r32( R_ECX );
2247 load_spreg( R_ECX, R_S );
2248 TEST_r32_r32( R_ECX, R_ECX );
2249 JE_rel8( 47, nosat );
2251 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2252 JNO_rel8( 51, end ); // 2
2253 load_imm32( R_EDX, 1 ); // 5
2254 store_spreg( R_EDX, R_MACH ); // 6
2255 JS_rel8( 13, positive ); // 2
2256 load_imm32( R_EAX, 0x80000000 );// 5
2257 store_spreg( R_EAX, R_MACL ); // 6
2258 JMP_rel8( 25, end2 ); // 2
2260 JMP_TARGET(positive);
2261 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2262 store_spreg( R_EAX, R_MACL ); // 6
2263 JMP_rel8( 12, end3); // 2
2265 JMP_TARGET(nosat);
2266 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2267 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2268 JMP_TARGET(end);
2269 JMP_TARGET(end2);
2270 JMP_TARGET(end3);
2271 sh4_x86.tstate = TSTATE_NONE;
2272 }
2273 break;
2274 }
2275 break;
2276 case 0x5:
2277 { /* MOV.L @(disp, Rm), Rn */
2278 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2279 load_reg( R_ECX, Rm );
2280 ADD_imm8s_r32( disp, R_ECX );
2281 precheck();
2282 check_ralign32( R_ECX );
2283 MEM_READ_LONG( R_ECX, R_EAX );
2284 store_reg( R_EAX, Rn );
2285 sh4_x86.tstate = TSTATE_NONE;
2286 }
2287 break;
2288 case 0x6:
2289 switch( ir&0xF ) {
2290 case 0x0:
2291 { /* MOV.B @Rm, Rn */
2292 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2293 load_reg( R_ECX, Rm );
2294 MEM_READ_BYTE( R_ECX, R_EAX );
2295 store_reg( R_EAX, Rn );
2296 sh4_x86.tstate = TSTATE_NONE;
2297 }
2298 break;
2299 case 0x1:
2300 { /* MOV.W @Rm, Rn */
2301 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2302 load_reg( R_ECX, Rm );
2303 precheck();
2304 check_ralign16( R_ECX );
2305 MEM_READ_WORD( R_ECX, R_EAX );
2306 store_reg( R_EAX, Rn );
2307 sh4_x86.tstate = TSTATE_NONE;
2308 }
2309 break;
2310 case 0x2:
2311 { /* MOV.L @Rm, Rn */
2312 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2313 load_reg( R_ECX, Rm );
2314 precheck();
2315 check_ralign32( R_ECX );
2316 MEM_READ_LONG( R_ECX, R_EAX );
2317 store_reg( R_EAX, Rn );
2318 sh4_x86.tstate = TSTATE_NONE;
2319 }
2320 break;
2321 case 0x3:
2322 { /* MOV Rm, Rn */
2323 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2324 load_reg( R_EAX, Rm );
2325 store_reg( R_EAX, Rn );
2326 }
2327 break;
2328 case 0x4:
2329 { /* MOV.B @Rm+, Rn */
2330 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2331 load_reg( R_ECX, Rm );
2332 MOV_r32_r32( R_ECX, R_EAX );
2333 ADD_imm8s_r32( 1, R_EAX );
2334 store_reg( R_EAX, Rm );
2335 MEM_READ_BYTE( R_ECX, R_EAX );
2336 store_reg( R_EAX, Rn );
2337 sh4_x86.tstate = TSTATE_NONE;
2338 }
2339 break;
2340 case 0x5:
2341 { /* MOV.W @Rm+, Rn */
2342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2343 load_reg( R_EAX, Rm );
2344 precheck();
2345 check_ralign16( R_EAX );
2346 MOV_r32_r32( R_EAX, R_ECX );
2347 ADD_imm8s_r32( 2, R_EAX );
2348 store_reg( R_EAX, Rm );
2349 MEM_READ_WORD( R_ECX, R_EAX );
2350 store_reg( R_EAX, Rn );
2351 sh4_x86.tstate = TSTATE_NONE;
2352 }
2353 break;
2354 case 0x6:
2355 { /* MOV.L @Rm+, Rn */
2356 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2357 load_reg( R_EAX, Rm );
2358 precheck();
2359 check_ralign32( R_EAX );
2360 MOV_r32_r32( R_EAX, R_ECX );
2361 ADD_imm8s_r32( 4, R_EAX );
2362 store_reg( R_EAX, Rm );
2363 MEM_READ_LONG( R_ECX, R_EAX );
2364 store_reg( R_EAX, Rn );
2365 sh4_x86.tstate = TSTATE_NONE;
2366 }
2367 break;
2368 case 0x7:
2369 { /* NOT Rm, Rn */
2370 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2371 load_reg( R_EAX, Rm );
2372 NOT_r32( R_EAX );
2373 store_reg( R_EAX, Rn );
2374 sh4_x86.tstate = TSTATE_NONE;
2375 }
2376 break;
2377 case 0x8:
2378 { /* SWAP.B Rm, Rn */
2379 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2380 load_reg( R_EAX, Rm );
2381 XCHG_r8_r8( R_AL, R_AH );
2382 store_reg( R_EAX, Rn );
2383 }
2384 break;
2385 case 0x9:
2386 { /* SWAP.W Rm, Rn */
2387 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2388 load_reg( R_EAX, Rm );
2389 MOV_r32_r32( R_EAX, R_ECX );
2390 SHL_imm8_r32( 16, R_ECX );
2391 SHR_imm8_r32( 16, R_EAX );
2392 OR_r32_r32( R_EAX, R_ECX );
2393 store_reg( R_ECX, Rn );
2394 sh4_x86.tstate = TSTATE_NONE;
2395 }
2396 break;
2397 case 0xA:
2398 { /* NEGC Rm, Rn */
2399 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2400 load_reg( R_EAX, Rm );
2401 XOR_r32_r32( R_ECX, R_ECX );
2402 LDC_t();
2403 SBB_r32_r32( R_EAX, R_ECX );
2404 store_reg( R_ECX, Rn );
2405 SETC_t();
2406 sh4_x86.tstate = TSTATE_C;
2407 }
2408 break;
2409 case 0xB:
2410 { /* NEG Rm, Rn */
2411 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2412 load_reg( R_EAX, Rm );
2413 NEG_r32( R_EAX );
2414 store_reg( R_EAX, Rn );
2415 sh4_x86.tstate = TSTATE_NONE;
2416 }
2417 break;
2418 case 0xC:
2419 { /* EXTU.B Rm, Rn */
2420 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2421 load_reg( R_EAX, Rm );
2422 MOVZX_r8_r32( R_EAX, R_EAX );
2423 store_reg( R_EAX, Rn );
2424 }
2425 break;
2426 case 0xD:
2427 { /* EXTU.W Rm, Rn */
2428 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2429 load_reg( R_EAX, Rm );
2430 MOVZX_r16_r32( R_EAX, R_EAX );
2431 store_reg( R_EAX, Rn );
2432 }
2433 break;
2434 case 0xE:
2435 { /* EXTS.B Rm, Rn */
2436 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2437 load_reg( R_EAX, Rm );
2438 MOVSX_r8_r32( R_EAX, R_EAX );
2439 store_reg( R_EAX, Rn );
2440 }
2441 break;
2442 case 0xF:
2443 { /* EXTS.W Rm, Rn */
2444 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2445 load_reg( R_EAX, Rm );
2446 MOVSX_r16_r32( R_EAX, R_EAX );
2447 store_reg( R_EAX, Rn );
2448 }
2449 break;
2450 }
2451 break;
2452 case 0x7:
2453 { /* ADD #imm, Rn */
2454 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2455 load_reg( R_EAX, Rn );
2456 ADD_imm8s_r32( imm, R_EAX );
2457 store_reg( R_EAX, Rn );
2458 sh4_x86.tstate = TSTATE_NONE;
2459 }
2460 break;
2461 case 0x8:
2462 switch( (ir&0xF00) >> 8 ) {
2463 case 0x0:
2464 { /* MOV.B R0, @(disp, Rn) */
2465 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2466 load_reg( R_EAX, 0 );
2467 load_reg( R_ECX, Rn );
2468 ADD_imm32_r32( disp, R_ECX );
2469 MEM_WRITE_BYTE( R_ECX, R_EAX );
2470 sh4_x86.tstate = TSTATE_NONE;
2471 }
2472 break;
2473 case 0x1:
2474 { /* MOV.W R0, @(disp, Rn) */
2475 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2476 load_reg( R_ECX, Rn );
2477 load_reg( R_EAX, 0 );
2478 ADD_imm32_r32( disp, R_ECX );
2479 precheck();
2480 check_walign16( R_ECX );
2481 MEM_WRITE_WORD( R_ECX, R_EAX );
2482 sh4_x86.tstate = TSTATE_NONE;
2483 }
2484 break;
2485 case 0x4:
2486 { /* MOV.B @(disp, Rm), R0 */
2487 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2488 load_reg( R_ECX, Rm );
2489 ADD_imm32_r32( disp, R_ECX );
2490 MEM_READ_BYTE( R_ECX, R_EAX );
2491 store_reg( R_EAX, 0 );
2492 sh4_x86.tstate = TSTATE_NONE;
2493 }
2494 break;
2495 case 0x5:
2496 { /* MOV.W @(disp, Rm), R0 */
2497 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2498 load_reg( R_ECX, Rm );
2499 ADD_imm32_r32( disp, R_ECX );
2500 precheck();
2501 check_ralign16( R_ECX );
2502 MEM_READ_WORD( R_ECX, R_EAX );
2503 store_reg( R_EAX, 0 );
2504 sh4_x86.tstate = TSTATE_NONE;
2505 }
2506 break;
2507 case 0x8:
2508 { /* CMP/EQ #imm, R0 */
2509 int32_t imm = SIGNEXT8(ir&0xFF);
2510 load_reg( R_EAX, 0 );
2511 CMP_imm8s_r32(imm, R_EAX);
2512 SETE_t();
2513 sh4_x86.tstate = TSTATE_E;
2514 }
2515 break;
2516 case 0x9:
2517 { /* BT disp */
2518 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2519 if( sh4_x86.in_delay_slot ) {
2520 SLOTILLEGAL();
2521 } else {
2522 JF_rel8( 29, nottaken );
2523 exit_block( disp + pc + 4, pc+2 );
2524 JMP_TARGET(nottaken);
2525 return 2;
2526 }
2527 }
2528 break;
2529 case 0xB:
2530 { /* BF disp */
2531 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2532 if( sh4_x86.in_delay_slot ) {
2533 SLOTILLEGAL();
2534 } else {
2535 JT_rel8( 29, nottaken );
2536 exit_block( disp + pc + 4, pc+2 );
2537 JMP_TARGET(nottaken);
2538 return 2;
2539 }
2540 }
2541 break;
2542 case 0xD:
2543 { /* BT/S disp */
2544 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2545 if( sh4_x86.in_delay_slot ) {
2546 SLOTILLEGAL();
2547 } else {
2548 sh4_x86.in_delay_slot = TRUE;
2549 if( sh4_x86.tstate == TSTATE_NONE ) {
2550 CMP_imm8s_sh4r( 1, R_T );
2551 sh4_x86.tstate = TSTATE_E;
2552 }
2553 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2554 sh4_x86_translate_instruction(pc+2);
2555 exit_block( disp + pc + 4, pc+4 );
2556 // not taken
2557 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2558 sh4_x86_translate_instruction(pc+2);
2559 return 4;
2560 }
2561 }
2562 break;
2563 case 0xF:
2564 { /* BF/S disp */
2565 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2566 if( sh4_x86.in_delay_slot ) {
2567 SLOTILLEGAL();
2568 } else {
2569 sh4_x86.in_delay_slot = TRUE;
2570 if( sh4_x86.tstate == TSTATE_NONE ) {
2571 CMP_imm8s_sh4r( 1, R_T );
2572 sh4_x86.tstate = TSTATE_E;
2573 }
2574 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2575 sh4_x86_translate_instruction(pc+2);
2576 exit_block( disp + pc + 4, pc+4 );
2577 // not taken
2578 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2579 sh4_x86_translate_instruction(pc+2);
2580 return 4;
2581 }
2582 }
2583 break;
2584 default:
2585 UNDEF();
2586 break;
2587 }
2588 break;
2589 case 0x9:
2590 { /* MOV.W @(disp, PC), Rn */
2591 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2592 if( sh4_x86.in_delay_slot ) {
2593 SLOTILLEGAL();
2594 } else {
2595 load_imm32( R_ECX, pc + disp + 4 );
2596 MEM_READ_WORD( R_ECX, R_EAX );
2597 store_reg( R_EAX, Rn );
2598 sh4_x86.tstate = TSTATE_NONE;
2599 }
2600 }
2601 break;
2602 case 0xA:
2603 { /* BRA disp */
2604 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2605 if( sh4_x86.in_delay_slot ) {
2606 SLOTILLEGAL();
2607 } else {
2608 sh4_x86.in_delay_slot = TRUE;
2609 sh4_x86_translate_instruction( pc + 2 );
2610 exit_block( disp + pc + 4, pc+4 );
2611 sh4_x86.branch_taken = TRUE;
2612 return 4;
2613 }
2614 }
2615 break;
2616 case 0xB:
2617 { /* BSR disp */
2618 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2619 if( sh4_x86.in_delay_slot ) {
2620 SLOTILLEGAL();
2621 } else {
2622 load_imm32( R_EAX, pc + 4 );
2623 store_spreg( R_EAX, R_PR );
2624 sh4_x86.in_delay_slot = TRUE;
2625 sh4_x86_translate_instruction( pc + 2 );
2626 exit_block( disp + pc + 4, pc+4 );
2627 sh4_x86.branch_taken = TRUE;
2628 return 4;
2629 }
2630 }
2631 break;
2632 case 0xC:
2633 switch( (ir&0xF00) >> 8 ) {
2634 case 0x0:
2635 { /* MOV.B R0, @(disp, GBR) */
2636 uint32_t disp = (ir&0xFF);
2637 load_reg( R_EAX, 0 );
2638 load_spreg( R_ECX, R_GBR );
2639 ADD_imm32_r32( disp, R_ECX );
2640 MEM_WRITE_BYTE( R_ECX, R_EAX );
2641 sh4_x86.tstate = TSTATE_NONE;
2642 }
2643 break;
2644 case 0x1:
2645 { /* MOV.W R0, @(disp, GBR) */
2646 uint32_t disp = (ir&0xFF)<<1;
2647 load_spreg( R_ECX, R_GBR );
2648 load_reg( R_EAX, 0 );
2649 ADD_imm32_r32( disp, R_ECX );
2650 precheck();
2651 check_walign16( R_ECX );
2652 MEM_WRITE_WORD( R_ECX, R_EAX );
2653 sh4_x86.tstate = TSTATE_NONE;
2654 }
2655 break;
2656 case 0x2:
2657 { /* MOV.L R0, @(disp, GBR) */
2658 uint32_t disp = (ir&0xFF)<<2;
2659 load_spreg( R_ECX, R_GBR );
2660 load_reg( R_EAX, 0 );
2661 ADD_imm32_r32( disp, R_ECX );
2662 precheck();
2663 check_walign32( R_ECX );
2664 MEM_WRITE_LONG( R_ECX, R_EAX );
2665 sh4_x86.tstate = TSTATE_NONE;
2666 }
2667 break;
2668 case 0x3:
2669 { /* TRAPA #imm */
2670 uint32_t imm = (ir&0xFF);
2671 if( sh4_x86.in_delay_slot ) {
2672 SLOTILLEGAL();
2673 } else {
2674 PUSH_imm32( imm );
2675 call_func0( sh4_raise_trap );
2676 ADD_imm8s_r32( 4, R_ESP );
2677 sh4_x86.tstate = TSTATE_NONE;
2678 exit_block_pcset(pc);
2679 sh4_x86.branch_taken = TRUE;
2680 return 2;
2681 }
2682 }
2683 break;
2684 case 0x4:
2685 { /* MOV.B @(disp, GBR), R0 */
2686 uint32_t disp = (ir&0xFF);
2687 load_spreg( R_ECX, R_GBR );
2688 ADD_imm32_r32( disp, R_ECX );
2689 MEM_READ_BYTE( R_ECX, R_EAX );
2690 store_reg( R_EAX, 0 );
2691 sh4_x86.tstate = TSTATE_NONE;
2692 }
2693 break;
2694 case 0x5:
2695 { /* MOV.W @(disp, GBR), R0 */
2696 uint32_t disp = (ir&0xFF)<<1;
2697 load_spreg( R_ECX, R_GBR );
2698 ADD_imm32_r32( disp, R_ECX );
2699 precheck();
2700 check_ralign16( R_ECX );
2701 MEM_READ_WORD( R_ECX, R_EAX );
2702 store_reg( R_EAX, 0 );
2703 sh4_x86.tstate = TSTATE_NONE;
2704 }
2705 break;
2706 case 0x6:
2707 { /* MOV.L @(disp, GBR), R0 */
2708 uint32_t disp = (ir&0xFF)<<2;
2709 load_spreg( R_ECX, R_GBR );
2710 ADD_imm32_r32( disp, R_ECX );
2711 precheck();
2712 check_ralign32( R_ECX );
2713 MEM_READ_LONG( R_ECX, R_EAX );
2714 store_reg( R_EAX, 0 );
2715 sh4_x86.tstate = TSTATE_NONE;
2716 }
2717 break;
2718 case 0x7:
2719 { /* MOVA @(disp, PC), R0 */
2720 uint32_t disp = (ir&0xFF)<<2;
2721 if( sh4_x86.in_delay_slot ) {
2722 SLOTILLEGAL();
2723 } else {
2724 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2725 store_reg( R_ECX, 0 );
2726 }
2727 }
2728 break;
2729 case 0x8:
2730 { /* TST #imm, R0 */
2731 uint32_t imm = (ir&0xFF);
2732 load_reg( R_EAX, 0 );
2733 TEST_imm32_r32( imm, R_EAX );
2734 SETE_t();
2735 sh4_x86.tstate = TSTATE_E;
2736 }
2737 break;
2738 case 0x9:
2739 { /* AND #imm, R0 */
2740 uint32_t imm = (ir&0xFF);
2741 load_reg( R_EAX, 0 );
2742 AND_imm32_r32(imm, R_EAX);
2743 store_reg( R_EAX, 0 );
2744 sh4_x86.tstate = TSTATE_NONE;
2745 }
2746 break;
2747 case 0xA:
2748 { /* XOR #imm, R0 */
2749 uint32_t imm = (ir&0xFF);
2750 load_reg( R_EAX, 0 );
2751 XOR_imm32_r32( imm, R_EAX );
2752 store_reg( R_EAX, 0 );
2753 sh4_x86.tstate = TSTATE_NONE;
2754 }
2755 break;
2756 case 0xB:
2757 { /* OR #imm, R0 */
2758 uint32_t imm = (ir&0xFF);
2759 load_reg( R_EAX, 0 );
2760 OR_imm32_r32(imm, R_EAX);
2761 store_reg( R_EAX, 0 );
2762 sh4_x86.tstate = TSTATE_NONE;
2763 }
2764 break;
2765 case 0xC:
2766 { /* TST.B #imm, @(R0, GBR) */
2767 uint32_t imm = (ir&0xFF);
2768 load_reg( R_EAX, 0);
2769 load_reg( R_ECX, R_GBR);
2770 ADD_r32_r32( R_EAX, R_ECX );
2771 MEM_READ_BYTE( R_ECX, R_EAX );
2772 TEST_imm8_r8( imm, R_AL );
2773 SETE_t();
2774 sh4_x86.tstate = TSTATE_E;
2775 }
2776 break;
2777 case 0xD:
2778 { /* AND.B #imm, @(R0, GBR) */
2779 uint32_t imm = (ir&0xFF);
2780 load_reg( R_EAX, 0 );
2781 load_spreg( R_ECX, R_GBR );
2782 ADD_r32_r32( R_EAX, R_ECX );
2783 PUSH_r32(R_ECX);
2784 call_func0(sh4_read_byte);
2785 POP_r32(R_ECX);
2786 AND_imm32_r32(imm, R_EAX );
2787 MEM_WRITE_BYTE( R_ECX, R_EAX );
2788 sh4_x86.tstate = TSTATE_NONE;
2789 }
2790 break;
2791 case 0xE:
2792 { /* XOR.B #imm, @(R0, GBR) */
2793 uint32_t imm = (ir&0xFF);
2794 load_reg( R_EAX, 0 );
2795 load_spreg( R_ECX, R_GBR );
2796 ADD_r32_r32( R_EAX, R_ECX );
2797 PUSH_r32(R_ECX);
2798 call_func0(sh4_read_byte);
2799 POP_r32(R_ECX);
2800 XOR_imm32_r32( imm, R_EAX );
2801 MEM_WRITE_BYTE( R_ECX, R_EAX );
2802 sh4_x86.tstate = TSTATE_NONE;
2803 }
2804 break;
2805 case 0xF:
2806 { /* OR.B #imm, @(R0, GBR) */
2807 uint32_t imm = (ir&0xFF);
2808 load_reg( R_EAX, 0 );
2809 load_spreg( R_ECX, R_GBR );
2810 ADD_r32_r32( R_EAX, R_ECX );
2811 PUSH_r32(R_ECX);
2812 call_func0(sh4_read_byte);
2813 POP_r32(R_ECX);
2814 OR_imm32_r32(imm, R_EAX );
2815 MEM_WRITE_BYTE( R_ECX, R_EAX );
2816 sh4_x86.tstate = TSTATE_NONE;
2817 }
2818 break;
2819 }
2820 break;
2821 case 0xD:
2822 { /* MOV.L @(disp, PC), Rn */
2823 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2824 if( sh4_x86.in_delay_slot ) {
2825 SLOTILLEGAL();
2826 } else {
2827 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2828 char *ptr = mem_get_region(target);
2829 if( ptr != NULL ) {
2830 MOV_moff32_EAX( (uint32_t)ptr );
2831 } else {
2832 load_imm32( R_ECX, target );
2833 MEM_READ_LONG( R_ECX, R_EAX );
2834 }
2835 store_reg( R_EAX, Rn );
2836 sh4_x86.tstate = TSTATE_NONE;
2837 }
2838 }
2839 break;
2840 case 0xE:
2841 { /* MOV #imm, Rn */
2842 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2843 load_imm32( R_EAX, imm );
2844 store_reg( R_EAX, Rn );
2845 }
2846 break;
2847 case 0xF:
2848 switch( ir&0xF ) {
2849 case 0x0:
2850 { /* FADD FRm, FRn */
2851 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2852 check_fpuen();
2853 load_spreg( R_ECX, R_FPSCR );
2854 TEST_imm32_r32( FPSCR_PR, R_ECX );
2855 load_fr_bank( R_EDX );
2856 JNE_rel8(13,doubleprec);
2857 push_fr(R_EDX, FRm);
2858 push_fr(R_EDX, FRn);
2859 FADDP_st(1);
2860 pop_fr(R_EDX, FRn);
2861 JMP_rel8(11,end);
2862 JMP_TARGET(doubleprec);
2863 push_dr(R_EDX, FRm);
2864 push_dr(R_EDX, FRn);
2865 FADDP_st(1);
2866 pop_dr(R_EDX, FRn);
2867 JMP_TARGET(end);
2868 sh4_x86.tstate = TSTATE_NONE;
2869 }
2870 break;
2871 case 0x1:
2872 { /* FSUB FRm, FRn */
2873 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2874 check_fpuen();
2875 load_spreg( R_ECX, R_FPSCR );
2876 TEST_imm32_r32( FPSCR_PR, R_ECX );
2877 load_fr_bank( R_EDX );
2878 JNE_rel8(13, doubleprec);
2879 push_fr(R_EDX, FRn);
2880 push_fr(R_EDX, FRm);
2881 FSUBP_st(1);
2882 pop_fr(R_EDX, FRn);
2883 JMP_rel8(11, end);
2884 JMP_TARGET(doubleprec);
2885 push_dr(R_EDX, FRn);
2886 push_dr(R_EDX, FRm);
2887 FSUBP_st(1);
2888 pop_dr(R_EDX, FRn);
2889 JMP_TARGET(end);
2890 sh4_x86.tstate = TSTATE_NONE;
2891 }
2892 break;
2893 case 0x2:
2894 { /* FMUL FRm, FRn */
2895 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2896 check_fpuen();
2897 load_spreg( R_ECX, R_FPSCR );
2898 TEST_imm32_r32( FPSCR_PR, R_ECX );
2899 load_fr_bank( R_EDX );
2900 JNE_rel8(13, doubleprec);
2901 push_fr(R_EDX, FRm);
2902 push_fr(R_EDX, FRn);
2903 FMULP_st(1);
2904 pop_fr(R_EDX, FRn);
2905 JMP_rel8(11, end);
2906 JMP_TARGET(doubleprec);
2907 push_dr(R_EDX, FRm);
2908 push_dr(R_EDX, FRn);
2909 FMULP_st(1);
2910 pop_dr(R_EDX, FRn);
2911 JMP_TARGET(end);
2912 sh4_x86.tstate = TSTATE_NONE;
2913 }
2914 break;
2915 case 0x3:
2916 { /* FDIV FRm, FRn */
2917 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2918 check_fpuen();
2919 load_spreg( R_ECX, R_FPSCR );
2920 TEST_imm32_r32( FPSCR_PR, R_ECX );
2921 load_fr_bank( R_EDX );
2922 JNE_rel8(13, doubleprec);
2923 push_fr(R_EDX, FRn);
2924 push_fr(R_EDX, FRm);
2925 FDIVP_st(1);
2926 pop_fr(R_EDX, FRn);
2927 JMP_rel8(11, end);
2928 JMP_TARGET(doubleprec);
2929 push_dr(R_EDX, FRn);
2930 push_dr(R_EDX, FRm);
2931 FDIVP_st(1);
2932 pop_dr(R_EDX, FRn);
2933 JMP_TARGET(end);
2934 sh4_x86.tstate = TSTATE_NONE;
2935 }
2936 break;
2937 case 0x4:
2938 { /* FCMP/EQ FRm, FRn */
2939 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2940 check_fpuen();
2941 load_spreg( R_ECX, R_FPSCR );
2942 TEST_imm32_r32( FPSCR_PR, R_ECX );
2943 load_fr_bank( R_EDX );
2944 JNE_rel8(8, doubleprec);
2945 push_fr(R_EDX, FRm);
2946 push_fr(R_EDX, FRn);
2947 JMP_rel8(6, end);
2948 JMP_TARGET(doubleprec);
2949 push_dr(R_EDX, FRm);
2950 push_dr(R_EDX, FRn);
2951 JMP_TARGET(end);
2952 FCOMIP_st(1);
2953 SETE_t();
2954 FPOP_st();
2955 sh4_x86.tstate = TSTATE_NONE;
2956 }
2957 break;
2958 case 0x5:
2959 { /* FCMP/GT FRm, FRn */
2960 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2961 check_fpuen();
2962 load_spreg( R_ECX, R_FPSCR );
2963 TEST_imm32_r32( FPSCR_PR, R_ECX );
2964 load_fr_bank( R_EDX );
2965 JNE_rel8(8, doubleprec);
2966 push_fr(R_EDX, FRm);
2967 push_fr(R_EDX, FRn);
2968 JMP_rel8(6, end);
2969 JMP_TARGET(doubleprec);
2970 push_dr(R_EDX, FRm);
2971 push_dr(R_EDX, FRn);
2972 JMP_TARGET(end);
2973 FCOMIP_st(1);
2974 SETA_t();
2975 FPOP_st();
2976 sh4_x86.tstate = TSTATE_NONE;
2977 }
2978 break;
2979 case 0x6:
2980 { /* FMOV @(R0, Rm), FRn */
2981 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2982 precheck();
2983 check_fpuen_no_precheck();
2984 load_reg( R_ECX, Rm );
2985 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2986 check_ralign32( R_ECX );
2987 load_spreg( R_EDX, R_FPSCR );
2988 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2989 JNE_rel8(19, doublesize);
2990 MEM_READ_LONG( R_ECX, R_EAX );
2991 load_fr_bank( R_EDX );
2992 store_fr( R_EDX, R_EAX, FRn );
2993 if( FRn&1 ) {
2994 JMP_rel8(48, end);
2995 JMP_TARGET(doublesize);
2996 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2997 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2998 load_xf_bank( R_EDX );
2999 store_fr( R_EDX, R_EAX, FRn&0x0E );
3000 store_fr( R_EDX, R_ECX, FRn|0x01 );
3001 JMP_TARGET(end);
3002 } else {
3003 JMP_rel8(36, end);
3004 JMP_TARGET(doublesize);
3005 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3006 load_fr_bank( R_EDX );
3007 store_fr( R_EDX, R_EAX, FRn&0x0E );
3008 store_fr( R_EDX, R_ECX, FRn|0x01 );
3009 JMP_TARGET(end);
3010 }
3011 sh4_x86.tstate = TSTATE_NONE;
3012 }
3013 break;
3014 case 0x7:
3015 { /* FMOV FRm, @(R0, Rn) */
3016 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3017 precheck();
3018 check_fpuen_no_precheck();
3019 load_reg( R_ECX, Rn );
3020 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
3021 check_walign32( R_ECX );
3022 load_spreg( R_EDX, R_FPSCR );
3023 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3024 JNE_rel8(20, doublesize);
3025 load_fr_bank( R_EDX );
3026 load_fr( R_EDX, R_EAX, FRm );
3027 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3028 if( FRm&1 ) {
3029 JMP_rel8( 48, end );
3030 JMP_TARGET(doublesize);
3031 load_xf_bank( R_EDX );
3032 load_fr( R_EDX, R_EAX, FRm&0x0E );
3033 load_fr( R_EDX, R_EDX, FRm|0x01 );
3034 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3035 JMP_TARGET(end);
3036 } else {
3037 JMP_rel8( 39, end );
3038 JMP_TARGET(doublesize);
3039 load_fr_bank( R_EDX );
3040 load_fr( R_EDX, R_EAX, FRm&0x0E );
3041 load_fr( R_EDX, R_EDX, FRm|0x01 );
3042 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3043 JMP_TARGET(end);
3044 }
3045 sh4_x86.tstate = TSTATE_NONE;
3046 }
3047 break;
3048 case 0x8:
3049 { /* FMOV @Rm, FRn */
3050 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3051 precheck();
3052 check_fpuen_no_precheck();
3053 load_reg( R_ECX, Rm );
3054 check_ralign32( R_ECX );
3055 load_spreg( R_EDX, R_FPSCR );
3056 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3057 JNE_rel8(19, doublesize);
3058 MEM_READ_LONG( R_ECX, R_EAX );
3059 load_fr_bank( R_EDX );
3060 store_fr( R_EDX, R_EAX, FRn );
3061 if( FRn&1 ) {
3062 JMP_rel8(48, end);
3063 JMP_TARGET(doublesize);
3064 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3065 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3066 load_xf_bank( R_EDX );
3067 store_fr( R_EDX, R_EAX, FRn&0x0E );
3068 store_fr( R_EDX, R_ECX, FRn|0x01 );
3069 JMP_TARGET(end);
3070 } else {
3071 JMP_rel8(36, end);
3072 JMP_TARGET(doublesize);
3073 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3074 load_fr_bank( R_EDX );
3075 store_fr( R_EDX, R_EAX, FRn&0x0E );
3076 store_fr( R_EDX, R_ECX, FRn|0x01 );
3077 JMP_TARGET(end);
3078 }
3079 sh4_x86.tstate = TSTATE_NONE;
3080 }
3081 break;
3082 case 0x9:
3083 { /* FMOV @Rm+, FRn */
3084 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3085 precheck();
3086 check_fpuen_no_precheck();
3087 load_reg( R_ECX, Rm );
3088 check_ralign32( R_ECX );
3089 MOV_r32_r32( R_ECX, R_EAX );
3090 load_spreg( R_EDX, R_FPSCR );
3091 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3092 JNE_rel8(25, doublesize);
3093 ADD_imm8s_r32( 4, R_EAX );
3094 store_reg( R_EAX, Rm );
3095 MEM_READ_LONG( R_ECX, R_EAX );
3096 load_fr_bank( R_EDX );
3097 store_fr( R_EDX, R_EAX, FRn );
3098 if( FRn&1 ) {
3099 JMP_rel8(54, end);
3100 JMP_TARGET(doublesize);
3101 ADD_imm8s_r32( 8, R_EAX );
3102 store_reg(R_EAX, Rm);
3103 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3104 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3105 load_xf_bank( R_EDX );
3106 store_fr( R_EDX, R_EAX, FRn&0x0E );
3107 store_fr( R_EDX, R_ECX, FRn|0x01 );
3108 JMP_TARGET(end);
3109 } else {
3110 JMP_rel8(42, end);
3111 ADD_imm8s_r32( 8, R_EAX );
3112 store_reg(R_EAX, Rm);
3113 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3114 load_fr_bank( R_EDX );
3115 store_fr( R_EDX, R_EAX, FRn&0x0E );
3116 store_fr( R_EDX, R_ECX, FRn|0x01 );
3117 JMP_TARGET(end);
3118 }
3119 sh4_x86.tstate = TSTATE_NONE;
3120 }
3121 break;
3122 case 0xA:
3123 { /* FMOV FRm, @Rn */
3124 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3125 precheck();
3126 check_fpuen_no_precheck();
3127 load_reg( R_ECX, Rn );
3128 check_walign32( R_ECX );
3129 load_spreg( R_EDX, R_FPSCR );
3130 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3131 JNE_rel8(20, doublesize);
3132 load_fr_bank( R_EDX );
3133 load_fr( R_EDX, R_EAX, FRm );
3134 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3135 if( FRm&1 ) {
3136 JMP_rel8( 48, end );
3137 JMP_TARGET(doublesize);
3138 load_xf_bank( R_EDX );
3139 load_fr( R_EDX, R_EAX, FRm&0x0E );
3140 load_fr( R_EDX, R_EDX, FRm|0x01 );
3141 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3142 JMP_TARGET(end);
3143 } else {
3144 JMP_rel8( 39, end );
3145 JMP_TARGET(doublesize);
3146 load_fr_bank( R_EDX );
3147 load_fr( R_EDX, R_EAX, FRm&0x0E );
3148 load_fr( R_EDX, R_EDX, FRm|0x01 );
3149 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3150 JMP_TARGET(end);
3151 }
3152 sh4_x86.tstate = TSTATE_NONE;
3153 }
3154 break;
3155 case 0xB:
3156 { /* FMOV FRm, @-Rn */
3157 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3158 precheck();
3159 check_fpuen_no_precheck();
3160 load_reg( R_ECX, Rn );
3161 check_walign32( R_ECX );
3162 load_spreg( R_EDX, R_FPSCR );
3163 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3164 JNE_rel8(26, doublesize);
3165 load_fr_bank( R_EDX );
3166 load_fr( R_EDX, R_EAX, FRm );
3167 ADD_imm8s_r32(-4,R_ECX);
3168 store_reg( R_ECX, Rn );
3169 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3170 if( FRm&1 ) {
3171 JMP_rel8( 54, end );
3172 JMP_TARGET(doublesize);
3173 load_xf_bank( R_EDX );
3174 load_fr( R_EDX, R_EAX, FRm&0x0E );
3175 load_fr( R_EDX, R_EDX, FRm|0x01 );
3176 ADD_imm8s_r32(-8,R_ECX);
3177 store_reg( R_ECX, Rn );
3178 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3179 JMP_TARGET(end);
3180 } else {
3181 JMP_rel8( 45, end );
3182 JMP_TARGET(doublesize);
3183 load_fr_bank( R_EDX );
3184 load_fr( R_EDX, R_EAX, FRm&0x0E );
3185 load_fr( R_EDX, R_EDX, FRm|0x01 );
3186 ADD_imm8s_r32(-8,R_ECX);
3187 store_reg( R_ECX, Rn );
3188 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3189 JMP_TARGET(end);
3190 }
3191 sh4_x86.tstate = TSTATE_NONE;
3192 }
3193 break;
3194 case 0xC:
3195 { /* FMOV FRm, FRn */
3196 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3197 /* As horrible as this looks, it's actually covering 5 separate cases:
3198 * 1. 32-bit fr-to-fr (PR=0)
3199 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3200 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3201 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3202 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3203 */
3204 check_fpuen();
3205 load_spreg( R_ECX, R_FPSCR );
3206 load_fr_bank( R_EDX );
3207 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3208 JNE_rel8(8, doublesize);
3209 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3210 store_fr( R_EDX, R_EAX, FRn );
3211 if( FRm&1 ) {
3212 JMP_rel8(24, end);
3213 JMP_TARGET(doublesize);
3214 load_xf_bank( R_ECX );
3215 load_fr( R_ECX, R_EAX, FRm-1 );
3216 if( FRn&1 ) {
3217 load_fr( R_ECX, R_EDX, FRm );
3218 store_fr( R_ECX, R_EAX, FRn-1 );
3219 store_fr( R_ECX, R_EDX, FRn );
3220 } else /* FRn&1 == 0 */ {
3221 load_fr( R_ECX, R_ECX, FRm );
3222 store_fr( R_EDX, R_EAX, FRn );
3223 store_fr( R_EDX, R_ECX, FRn+1 );
3224 }
3225 JMP_TARGET(end);
3226 } else /* FRm&1 == 0 */ {
3227 if( FRn&1 ) {
3228 JMP_rel8(24, end);
3229 load_xf_bank( R_ECX );
3230 load_fr( R_EDX, R_EAX, FRm );
3231 load_fr( R_EDX, R_EDX, FRm+1 );
3232 store_fr( R_ECX, R_EAX, FRn-1 );
3233 store_fr( R_ECX, R_EDX, FRn );
3234 JMP_TARGET(end);
3235 } else /* FRn&1 == 0 */ {
3236 JMP_rel8(12, end);
3237 load_fr( R_EDX, R_EAX, FRm );
3238 load_fr( R_EDX, R_ECX, FRm+1 );
3239 store_fr( R_EDX, R_EAX, FRn );
3240 store_fr( R_EDX, R_ECX, FRn+1 );
3241 JMP_TARGET(end);
3242 }
3243 }
3244 sh4_x86.tstate = TSTATE_NONE;
3245 }
3246 break;
3247 case 0xD:
3248 switch( (ir&0xF0) >> 4 ) {
3249 case 0x0:
3250 { /* FSTS FPUL, FRn */
3251 uint32_t FRn = ((ir>>8)&0xF);
3252 check_fpuen();
3253 load_fr_bank( R_ECX );
3254 load_spreg( R_EAX, R_FPUL );
3255 store_fr( R_ECX, R_EAX, FRn );
3256 sh4_x86.tstate = TSTATE_NONE;
3257 }
3258 break;
3259 case 0x1:
3260 { /* FLDS FRm, FPUL */
3261 uint32_t FRm = ((ir>>8)&0xF);
3262 check_fpuen();
3263 load_fr_bank( R_ECX );
3264 load_fr( R_ECX, R_EAX, FRm );
3265 store_spreg( R_EAX, R_FPUL );
3266 sh4_x86.tstate = TSTATE_NONE;
3267 }
3268 break;
3269 case 0x2:
3270 { /* FLOAT FPUL, FRn */
3271 uint32_t FRn = ((ir>>8)&0xF);
3272 check_fpuen();
3273 load_spreg( R_ECX, R_FPSCR );
3274 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3275 FILD_sh4r(R_FPUL);
3276 TEST_imm32_r32( FPSCR_PR, R_ECX );
3277 JNE_rel8(5, doubleprec);
3278 pop_fr( R_EDX, FRn );
3279 JMP_rel8(3, end);
3280 JMP_TARGET(doubleprec);
3281 pop_dr( R_EDX, FRn );
3282 JMP_TARGET(end);
3283 sh4_x86.tstate = TSTATE_NONE;
3284 }
3285 break;
3286 case 0x3:
3287 { /* FTRC FRm, FPUL */
3288 uint32_t FRm = ((ir>>8)&0xF);
3289 check_fpuen();
3290 load_spreg( R_ECX, R_FPSCR );
3291 load_fr_bank( R_EDX );
3292 TEST_imm32_r32( FPSCR_PR, R_ECX );
3293 JNE_rel8(5, doubleprec);
3294 push_fr( R_EDX, FRm );
3295 JMP_rel8(3, doop);
3296 JMP_TARGET(doubleprec);
3297 push_dr( R_EDX, FRm );
3298 JMP_TARGET( doop );
3299 load_imm32( R_ECX, (uint32_t)&max_int );
3300 FILD_r32ind( R_ECX );
3301 FCOMIP_st(1);
3302 JNA_rel8( 32, sat );
3303 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3304 FILD_r32ind( R_ECX ); // 2
3305 FCOMIP_st(1); // 2
3306 JAE_rel8( 21, sat2 ); // 2
3307 load_imm32( R_EAX, (uint32_t)&save_fcw );
3308 FNSTCW_r32ind( R_EAX );
3309 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3310 FLDCW_r32ind( R_EDX );
3311 FISTP_sh4r(R_FPUL); // 3
3312 FLDCW_r32ind( R_EAX );
3313 JMP_rel8( 9, end ); // 2
3315 JMP_TARGET(sat);
3316 JMP_TARGET(sat2);
3317 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3318 store_spreg( R_ECX, R_FPUL );
3319 FPOP_st();
3320 JMP_TARGET(end);
3321 sh4_x86.tstate = TSTATE_NONE;
3322 }
3323 break;
3324 case 0x4:
3325 { /* FNEG FRn */
3326 uint32_t FRn = ((ir>>8)&0xF);
3327 check_fpuen();
3328 load_spreg( R_ECX, R_FPSCR );
3329 TEST_imm32_r32( FPSCR_PR, R_ECX );
3330 load_fr_bank( R_EDX );
3331 JNE_rel8(10, doubleprec);
3332 push_fr(R_EDX, FRn);
3333 FCHS_st0();
3334 pop_fr(R_EDX, FRn);
3335 JMP_rel8(8, end);
3336 JMP_TARGET(doubleprec);
3337 push_dr(R_EDX, FRn);
3338 FCHS_st0();
3339 pop_dr(R_EDX, FRn);
3340 JMP_TARGET(end);
3341 sh4_x86.tstate = TSTATE_NONE;
3342 }
3343 break;
3344 case 0x5:
3345 { /* FABS FRn */
3346 uint32_t FRn = ((ir>>8)&0xF);
3347 check_fpuen();
3348 load_spreg( R_ECX, R_FPSCR );
3349 load_fr_bank( R_EDX );
3350 TEST_imm32_r32( FPSCR_PR, R_ECX );
3351 JNE_rel8(10, doubleprec);
3352 push_fr(R_EDX, FRn); // 3
3353 FABS_st0(); // 2
3354 pop_fr( R_EDX, FRn); //3
3355 JMP_rel8(8,end); // 2
3356 JMP_TARGET(doubleprec);
3357 push_dr(R_EDX, FRn);
3358 FABS_st0();
3359 pop_dr(R_EDX, FRn);
3360 JMP_TARGET(end);
3361 sh4_x86.tstate = TSTATE_NONE;
3362 }
3363 break;
3364 case 0x6:
3365 { /* FSQRT FRn */
3366 uint32_t FRn = ((ir>>8)&0xF);
3367 check_fpuen();
3368 load_spreg( R_ECX, R_FPSCR );
3369 TEST_imm32_r32( FPSCR_PR, R_ECX );
3370 load_fr_bank( R_EDX );
3371 JNE_rel8(10, doubleprec);
3372 push_fr(R_EDX, FRn);
3373 FSQRT_st0();
3374 pop_fr(R_EDX, FRn);
3375 JMP_rel8(8, end);
3376 JMP_TARGET(doubleprec);
3377 push_dr(R_EDX, FRn);
3378 FSQRT_st0();
3379 pop_dr(R_EDX, FRn);
3380 JMP_TARGET(end);
3381 sh4_x86.tstate = TSTATE_NONE;
3382 }
3383 break;
3384 case 0x7:
3385 { /* FSRRA FRn */
3386 uint32_t FRn = ((ir>>8)&0xF);
3387 check_fpuen();
3388 load_spreg( R_ECX, R_FPSCR );
3389 TEST_imm32_r32( FPSCR_PR, R_ECX );
3390 load_fr_bank( R_EDX );
3391 JNE_rel8(12, end); // PR=0 only
3392 FLD1_st0();
3393 push_fr(R_EDX, FRn);
3394 FSQRT_st0();
3395 FDIVP_st(1);
3396 pop_fr(R_EDX, FRn);
3397 JMP_TARGET(end);
3398 sh4_x86.tstate = TSTATE_NONE;
3399 }
3400 break;
3401 case 0x8:
3402 { /* FLDI0 FRn */
3403 uint32_t FRn = ((ir>>8)&0xF);
3404 /* IFF PR=0 */
3405 check_fpuen();
3406 load_spreg( R_ECX, R_FPSCR );
3407 TEST_imm32_r32( FPSCR_PR, R_ECX );
3408 JNE_rel8(8, end);
3409 XOR_r32_r32( R_EAX, R_EAX );
3410 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3411 store_fr( R_ECX, R_EAX, FRn );
3412 JMP_TARGET(end);
3413 sh4_x86.tstate = TSTATE_NONE;
3414 }
3415 break;
3416 case 0x9:
3417 { /* FLDI1 FRn */
3418 uint32_t FRn = ((ir>>8)&0xF);
3419 /* IFF PR=0 */
3420 check_fpuen();
3421 load_spreg( R_ECX, R_FPSCR );
3422 TEST_imm32_r32( FPSCR_PR, R_ECX );
3423 JNE_rel8(11, end);
3424 load_imm32(R_EAX, 0x3F800000);
3425 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3426 store_fr( R_ECX, R_EAX, FRn );
3427 JMP_TARGET(end);
3428 sh4_x86.tstate = TSTATE_NONE;
3429 }
3430 break;
3431 case 0xA:
3432 { /* FCNVSD FPUL, FRn */
3433 uint32_t FRn = ((ir>>8)&0xF);
3434 check_fpuen();
3435 load_spreg( R_ECX, R_FPSCR );
3436 TEST_imm32_r32( FPSCR_PR, R_ECX );
3437 JE_rel8(9, end); // only when PR=1
3438 load_fr_bank( R_ECX );
3439 push_fpul();
3440 pop_dr( R_ECX, FRn );
3441 JMP_TARGET(end);
3442 sh4_x86.tstate = TSTATE_NONE;
3443 }
3444 break;
3445 case 0xB:
3446 { /* FCNVDS FRm, FPUL */
3447 uint32_t FRm = ((ir>>8)&0xF);
3448 check_fpuen();
3449 load_spreg( R_ECX, R_FPSCR );
3450 TEST_imm32_r32( FPSCR_PR, R_ECX );
3451 JE_rel8(9, end); // only when PR=1
3452 load_fr_bank( R_ECX );
3453 push_dr( R_ECX, FRm );
3454 pop_fpul();
3455 JMP_TARGET(end);
3456 sh4_x86.tstate = TSTATE_NONE;
3457 }
3458 break;
3459 case 0xE:
3460 { /* FIPR FVm, FVn */
3461 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3462 check_fpuen();
3463 load_spreg( R_ECX, R_FPSCR );
3464 TEST_imm32_r32( FPSCR_PR, R_ECX );
3465 JNE_rel8(44, doubleprec);
3467 load_fr_bank( R_ECX );
3468 push_fr( R_ECX, FVm<<2 );
3469 push_fr( R_ECX, FVn<<2 );
3470 FMULP_st(1);
3471 push_fr( R_ECX, (FVm<<2)+1);
3472 push_fr( R_ECX, (FVn<<2)+1);
3473 FMULP_st(1);
3474 FADDP_st(1);
3475 push_fr( R_ECX, (FVm<<2)+2);
3476 push_fr( R_ECX, (FVn<<2)+2);
3477 FMULP_st(1);
3478 FADDP_st(1);
3479 push_fr( R_ECX, (FVm<<2)+3);
3480 push_fr( R_ECX, (FVn<<2)+3);
3481 FMULP_st(1);
3482 FADDP_st(1);
3483 pop_fr( R_ECX, (FVn<<2)+3);
3484 JMP_TARGET(doubleprec);
3485 sh4_x86.tstate = TSTATE_NONE;
3486 }
3487 break;
3488 case 0xF:
3489 switch( (ir&0x100) >> 8 ) {
3490 case 0x0:
3491 { /* FSCA FPUL, FRn */
3492 uint32_t FRn = ((ir>>9)&0x7)<<1;
3493 check_fpuen();
3494 load_spreg( R_ECX, R_FPSCR );
3495 TEST_imm32_r32( FPSCR_PR, R_ECX );
3496 JNE_rel8( 21, doubleprec );
3497 load_fr_bank( R_ECX );
3498 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3499 load_spreg( R_EDX, R_FPUL );
3500 call_func2( sh4_fsca, R_EDX, R_ECX );
3501 JMP_TARGET(doubleprec);
3502 sh4_x86.tstate = TSTATE_NONE;
3503 }
3504 break;
3505 case 0x1:
3506 switch( (ir&0x200) >> 9 ) {
3507 case 0x0:
3508 { /* FTRV XMTRX, FVn */
3509 uint32_t FVn = ((ir>>10)&0x3);
3510 check_fpuen();
3511 load_spreg( R_ECX, R_FPSCR );
3512 TEST_imm32_r32( FPSCR_PR, R_ECX );
3513 JNE_rel8( 30, doubleprec );
3514 load_fr_bank( R_EDX ); // 3
3515 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3516 load_xf_bank( R_ECX ); // 12
3517 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3518 JMP_TARGET(doubleprec);
3519 sh4_x86.tstate = TSTATE_NONE;
3520 }
3521 break;
3522 case 0x1:
3523 switch( (ir&0xC00) >> 10 ) {
3524 case 0x0:
3525 { /* FSCHG */
3526 check_fpuen();
3527 load_spreg( R_ECX, R_FPSCR );
3528 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3529 store_spreg( R_ECX, R_FPSCR );
3530 sh4_x86.tstate = TSTATE_NONE;
3531 }
3532 break;
3533 case 0x2:
3534 { /* FRCHG */
3535 check_fpuen();
3536 load_spreg( R_ECX, R_FPSCR );
3537 XOR_imm32_r32( FPSCR_FR, R_ECX );
3538 store_spreg( R_ECX, R_FPSCR );
3539 update_fr_bank( R_ECX );
3540 sh4_x86.tstate = TSTATE_NONE;
3541 }
3542 break;
3543 case 0x3:
3544 { /* UNDEF */
3545 if( sh4_x86.in_delay_slot ) {
3546 SLOTILLEGAL();
3547 } else {
3548 precheck();
3549 JMP_exit(EXIT_ILLEGAL);
3550 return 2;
3551 }
3552 }
3553 break;
3554 default:
3555 UNDEF();
3556 break;
3557 }
3558 break;
3559 }
3560 break;
3561 }
3562 break;
3563 default:
3564 UNDEF();
3565 break;
3566 }
3567 break;
3568 case 0xE:
3569 { /* FMAC FR0, FRm, FRn */
3570 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3571 check_fpuen();
3572 load_spreg( R_ECX, R_FPSCR );
3573 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3574 TEST_imm32_r32( FPSCR_PR, R_ECX );
3575 JNE_rel8(18, doubleprec);
3576 push_fr( R_EDX, 0 );
3577 push_fr( R_EDX, FRm );
3578 FMULP_st(1);
3579 push_fr( R_EDX, FRn );
3580 FADDP_st(1);
3581 pop_fr( R_EDX, FRn );
3582 JMP_rel8(16, end);
3583 JMP_TARGET(doubleprec);
3584 push_dr( R_EDX, 0 );
3585 push_dr( R_EDX, FRm );
3586 FMULP_st(1);
3587 push_dr( R_EDX, FRn );
3588 FADDP_st(1);
3589 pop_dr( R_EDX, FRn );
3590 JMP_TARGET(end);
3591 sh4_x86.tstate = TSTATE_NONE;
3592 }
3593 break;
3594 default:
3595 UNDEF();
3596 break;
3597 }
3598 break;
3599 }
3601 sh4_x86.in_delay_slot = FALSE;
3602 return 0;
3603 }
.