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