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