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