Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 586:2a3ba82cf243
prev553:4e6166258c22
next590:4db6a084ca3c
author nkeynes
date Tue Jan 15 20:50:23 2008 +0000 (16 years ago)
permissions -rw-r--r--
last change Merged lxdream-mmu r570:596 to trunk
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Thu Dec 20 09:56:07 2007 +0000
1.2 +++ b/src/sh4/sh4x86.in Tue Jan 15 20:50:23 2008 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $
1.6 + * $Id$
1.7 *
1.8 * SH4 => x86 translation. This version does no real optimization, it just
1.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
1.10 @@ -34,6 +34,14 @@
1.11
1.12 #define DEFAULT_BACKPATCH_SIZE 4096
1.13
1.14 +struct backpatch_record {
1.15 + uint32_t *fixup_addr;
1.16 + uint32_t fixup_icount;
1.17 + uint32_t exc_code;
1.18 +};
1.19 +
1.20 +#define MAX_RECOVERY_SIZE 2048
1.21 +
1.22 /**
1.23 * Struct to manage internal translation state. This state is not saved -
1.24 * it is only valid between calls to sh4_translate_begin_block() and
1.25 @@ -48,10 +56,15 @@
1.26 uint32_t stack_posn; /* Trace stack height for alignment purposes */
1.27 int tstate;
1.28
1.29 + /* mode flags */
1.30 + gboolean tlb_on; /* True if tlb translation is active */
1.31 +
1.32 /* Allocated memory for the (block-wide) back-patch list */
1.33 - uint32_t **backpatch_list;
1.34 + struct backpatch_record *backpatch_list;
1.35 uint32_t backpatch_posn;
1.36 uint32_t backpatch_size;
1.37 + struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];
1.38 + uint32_t recovery_posn;
1.39 };
1.40
1.41 #define TSTATE_NONE -1
1.42 @@ -75,14 +88,6 @@
1.43 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
1.44 MARK_JMP(rel8, label)
1.45
1.46 -
1.47 -#define EXIT_DATA_ADDR_READ 0
1.48 -#define EXIT_DATA_ADDR_WRITE 7
1.49 -#define EXIT_ILLEGAL 14
1.50 -#define EXIT_SLOT_ILLEGAL 21
1.51 -#define EXIT_FPU_DISABLED 28
1.52 -#define EXIT_SLOT_FPU_DISABLED 35
1.53 -
1.54 static struct sh4_x86_state sh4_x86;
1.55
1.56 static uint32_t max_int = 0x7FFFFFFF;
1.57 @@ -93,26 +98,32 @@
1.58 void sh4_x86_init()
1.59 {
1.60 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
1.61 - sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
1.62 + sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
1.63 }
1.64
1.65
1.66 -static void sh4_x86_add_backpatch( uint8_t *ptr )
1.67 +static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
1.68 {
1.69 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
1.70 sh4_x86.backpatch_size <<= 1;
1.71 - sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
1.72 + sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
1.73 + sh4_x86.backpatch_size * sizeof(struct backpatch_record));
1.74 assert( sh4_x86.backpatch_list != NULL );
1.75 }
1.76 - sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
1.77 + if( sh4_x86.in_delay_slot ) {
1.78 + fixup_pc -= 2;
1.79 + }
1.80 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
1.81 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
1.82 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
1.83 + sh4_x86.backpatch_posn++;
1.84 }
1.85
1.86 -static void sh4_x86_do_backpatch( uint8_t *reloc_base )
1.87 +void sh4_x86_add_recovery( uint32_t pc )
1.88 {
1.89 - unsigned int i;
1.90 - for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
1.91 - *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
1.92 - }
1.93 + xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;
1.94 + xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
1.95 + xlat_recovery_posn++;
1.96 }
1.97
1.98 /**
1.99 @@ -266,86 +277,46 @@
1.100 }
1.101
1.102 /* Exception checks - Note that all exception checks will clobber EAX */
1.103 -#define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
1.104
1.105 #define check_priv( ) \
1.106 if( !sh4_x86.priv_checked ) { \
1.107 sh4_x86.priv_checked = TRUE;\
1.108 - precheck();\
1.109 load_spreg( R_EAX, R_SR );\
1.110 AND_imm32_r32( SR_MD, R_EAX );\
1.111 if( sh4_x86.in_delay_slot ) {\
1.112 - JE_exit( EXIT_SLOT_ILLEGAL );\
1.113 + JE_exc( EXC_SLOT_ILLEGAL );\
1.114 } else {\
1.115 - JE_exit( EXIT_ILLEGAL );\
1.116 + JE_exc( EXC_ILLEGAL );\
1.117 }\
1.118 }\
1.119
1.120 -
1.121 -static void check_priv_no_precheck()
1.122 -{
1.123 - if( !sh4_x86.priv_checked ) {
1.124 - sh4_x86.priv_checked = TRUE;
1.125 - load_spreg( R_EAX, R_SR );
1.126 - AND_imm32_r32( SR_MD, R_EAX );
1.127 - if( sh4_x86.in_delay_slot ) {
1.128 - JE_exit( EXIT_SLOT_ILLEGAL );
1.129 - } else {
1.130 - JE_exit( EXIT_ILLEGAL );
1.131 - }
1.132 - }
1.133 -}
1.134 -
1.135 #define check_fpuen( ) \
1.136 if( !sh4_x86.fpuen_checked ) {\
1.137 sh4_x86.fpuen_checked = TRUE;\
1.138 - precheck();\
1.139 load_spreg( R_EAX, R_SR );\
1.140 AND_imm32_r32( SR_FD, R_EAX );\
1.141 if( sh4_x86.in_delay_slot ) {\
1.142 - JNE_exit(EXIT_SLOT_FPU_DISABLED);\
1.143 + JNE_exc(EXC_SLOT_FPU_DISABLED);\
1.144 } else {\
1.145 - JNE_exit(EXIT_FPU_DISABLED);\
1.146 + JNE_exc(EXC_FPU_DISABLED);\
1.147 }\
1.148 }
1.149
1.150 -static void check_fpuen_no_precheck()
1.151 -{
1.152 - if( !sh4_x86.fpuen_checked ) {
1.153 - sh4_x86.fpuen_checked = TRUE;
1.154 - load_spreg( R_EAX, R_SR );
1.155 - AND_imm32_r32( SR_FD, R_EAX );
1.156 - if( sh4_x86.in_delay_slot ) {
1.157 - JNE_exit(EXIT_SLOT_FPU_DISABLED);
1.158 - } else {
1.159 - JNE_exit(EXIT_FPU_DISABLED);
1.160 - }
1.161 - }
1.162 +#define check_ralign16( x86reg ) \
1.163 + TEST_imm32_r32( 0x00000001, x86reg ); \
1.164 + JNE_exc(EXC_DATA_ADDR_READ)
1.165
1.166 -}
1.167 +#define check_walign16( x86reg ) \
1.168 + TEST_imm32_r32( 0x00000001, x86reg ); \
1.169 + JNE_exc(EXC_DATA_ADDR_WRITE);
1.170
1.171 -static void check_ralign16( int x86reg )
1.172 -{
1.173 - TEST_imm32_r32( 0x00000001, x86reg );
1.174 - JNE_exit(EXIT_DATA_ADDR_READ);
1.175 -}
1.176 +#define check_ralign32( x86reg ) \
1.177 + TEST_imm32_r32( 0x00000003, x86reg ); \
1.178 + JNE_exc(EXC_DATA_ADDR_READ)
1.179
1.180 -static void check_walign16( int x86reg )
1.181 -{
1.182 - TEST_imm32_r32( 0x00000001, x86reg );
1.183 - JNE_exit(EXIT_DATA_ADDR_WRITE);
1.184 -}
1.185 -
1.186 -static void check_ralign32( int x86reg )
1.187 -{
1.188 - TEST_imm32_r32( 0x00000003, x86reg );
1.189 - JNE_exit(EXIT_DATA_ADDR_READ);
1.190 -}
1.191 -static void check_walign32( int x86reg )
1.192 -{
1.193 - TEST_imm32_r32( 0x00000003, x86reg );
1.194 - JNE_exit(EXIT_DATA_ADDR_WRITE);
1.195 -}
1.196 +#define check_walign32( x86reg ) \
1.197 + TEST_imm32_r32( 0x00000003, x86reg ); \
1.198 + JNE_exc(EXC_DATA_ADDR_WRITE);
1.199
1.200 #define UNDEF()
1.201 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
1.202 @@ -356,10 +327,22 @@
1.203 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
1.204 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
1.205
1.206 -#define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.207 +/**
1.208 + * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
1.209 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
1.210 + */
1.211 +#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); }
1.212 +/**
1.213 + * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
1.214 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
1.215 + */
1.216 +#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); }
1.217
1.218 -extern uint16_t *sh4_icache;
1.219 -extern uint32_t sh4_icache_addr;
1.220 +#define MEM_READ_SIZE (CALL_FUNC1_SIZE)
1.221 +#define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
1.222 +#define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
1.223 +
1.224 +#define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.225
1.226 /****** Import appropriate calling conventions ******/
1.227 #if SH4_TRANSLATOR == TARGET_X86_64
1.228 @@ -372,11 +355,18 @@
1.229 #endif
1.230 #endif
1.231
1.232 +void sh4_translate_emit_breakpoint( sh4vma_t pc )
1.233 +{
1.234 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );
1.235 + call_func1( sh4_translate_exit, R_EAX );
1.236 +}
1.237 +
1.238
1.239 /**
1.240 * Translate a single instruction. Delayed branches are handled specially
1.241 * by translating both branch and delayed instruction as a single unit (as
1.242 *
1.243 + * The instruction MUST be in the icache (assert check)
1.244 *
1.245 * @return true if the instruction marks the end of a basic block
1.246 * (eg a branch or
1.247 @@ -384,24 +374,23 @@
1.248 uint32_t sh4_translate_instruction( sh4addr_t pc )
1.249 {
1.250 uint32_t ir;
1.251 - /* Read instruction */
1.252 - uint32_t pageaddr = pc >> 12;
1.253 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
1.254 - ir = sh4_icache[(pc&0xFFF)>>1];
1.255 - } else {
1.256 - sh4_icache = (uint16_t *)mem_get_page(pc);
1.257 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
1.258 - /* If someone's actually been so daft as to try to execute out of an IO
1.259 - * region, fallback on the full-blown memory read
1.260 - */
1.261 - sh4_icache = NULL;
1.262 - ir = sh4_read_word(pc);
1.263 - } else {
1.264 - sh4_icache_addr = pageaddr;
1.265 - ir = sh4_icache[(pc&0xFFF)>>1];
1.266 - }
1.267 + /* Read instruction from icache */
1.268 + assert( IS_IN_ICACHE(pc) );
1.269 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);
1.270 +
1.271 + /* PC is not in the current icache - this usually means we're running
1.272 + * with MMU on, and we've gone past the end of the page. And since
1.273 + * sh4_translate_block is pretty careful about this, it means we're
1.274 + * almost certainly in a delay slot.
1.275 + *
1.276 + * Since we can't assume the page is present (and we can't fault it in
1.277 + * at this point, inline a call to sh4_execute_instruction (with a few
1.278 + * small repairs to cope with the different environment).
1.279 + */
1.280 +
1.281 + if( !sh4_x86.in_delay_slot ) {
1.282 + sh4_x86_add_recovery(pc);
1.283 }
1.284 -
1.285 %%
1.286 /* ALU operations */
1.287 ADD Rm, Rn {:
1.288 @@ -452,9 +441,10 @@
1.289 AND.B #imm, @(R0, GBR) {:
1.290 load_reg( R_EAX, 0 );
1.291 load_spreg( R_ECX, R_GBR );
1.292 - ADD_r32_r32( R_EAX, R_ECX );
1.293 - PUSH_realigned_r32(R_ECX);
1.294 - MEM_READ_BYTE( R_ECX, R_EAX );
1.295 + ADD_r32_r32( R_ECX, R_EAX );
1.296 + MMU_TRANSLATE_WRITE( R_EAX );
1.297 + PUSH_realigned_r32(R_EAX);
1.298 + MEM_READ_BYTE( R_EAX, R_EAX );
1.299 POP_realigned_r32(R_ECX);
1.300 AND_imm32_r32(imm, R_EAX );
1.301 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.302 @@ -617,19 +607,35 @@
1.303 MOVZX_r16_r32( R_EAX, R_EAX );
1.304 store_reg( R_EAX, Rn );
1.305 :}
1.306 -MAC.L @Rm+, @Rn+ {:
1.307 - load_reg( R_ECX, Rm );
1.308 - precheck();
1.309 - check_ralign32( R_ECX );
1.310 - load_reg( R_ECX, Rn );
1.311 - check_ralign32( R_ECX );
1.312 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.313 - MEM_READ_LONG( R_ECX, R_EAX );
1.314 - PUSH_realigned_r32( R_EAX );
1.315 - load_reg( R_ECX, Rm );
1.316 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.317 +MAC.L @Rm+, @Rn+ {:
1.318 + if( Rm == Rn ) {
1.319 + load_reg( R_EAX, Rm );
1.320 + check_ralign32( R_EAX );
1.321 + MMU_TRANSLATE_READ( R_EAX );
1.322 + PUSH_realigned_r32( R_EAX );
1.323 + load_reg( R_EAX, Rn );
1.324 + ADD_imm8s_r32( 4, R_EAX );
1.325 + MMU_TRANSLATE_READ( R_EAX );
1.326 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
1.327 + // Note translate twice in case of page boundaries. Maybe worth
1.328 + // adding a page-boundary check to skip the second translation
1.329 + } else {
1.330 + load_reg( R_EAX, Rm );
1.331 + check_ralign32( R_EAX );
1.332 + MMU_TRANSLATE_READ( R_EAX );
1.333 + PUSH_realigned_r32( R_EAX );
1.334 + load_reg( R_EAX, Rn );
1.335 + check_ralign32( R_EAX );
1.336 + MMU_TRANSLATE_READ( R_EAX );
1.337 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.338 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.339 + }
1.340 + MEM_READ_LONG( R_EAX, R_EAX );
1.341 + POP_r32( R_ECX );
1.342 + PUSH_r32( R_EAX );
1.343 MEM_READ_LONG( R_ECX, R_EAX );
1.344 POP_realigned_r32( R_ECX );
1.345 +
1.346 IMUL_r32( R_ECX );
1.347 ADD_r32_sh4r( R_EAX, R_MACL );
1.348 ADC_r32_sh4r( R_EDX, R_MACH );
1.349 @@ -642,16 +648,31 @@
1.350 sh4_x86.tstate = TSTATE_NONE;
1.351 :}
1.352 MAC.W @Rm+, @Rn+ {:
1.353 - load_reg( R_ECX, Rm );
1.354 - precheck();
1.355 - check_ralign16( R_ECX );
1.356 - load_reg( R_ECX, Rn );
1.357 - check_ralign16( R_ECX );
1.358 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
1.359 - MEM_READ_WORD( R_ECX, R_EAX );
1.360 - PUSH_realigned_r32( R_EAX );
1.361 - load_reg( R_ECX, Rm );
1.362 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.363 + if( Rm == Rn ) {
1.364 + load_reg( R_EAX, Rm );
1.365 + check_ralign16( R_EAX );
1.366 + MMU_TRANSLATE_READ( R_EAX );
1.367 + PUSH_realigned_r32( R_EAX );
1.368 + load_reg( R_EAX, Rn );
1.369 + ADD_imm8s_r32( 2, R_EAX );
1.370 + MMU_TRANSLATE_READ( R_EAX );
1.371 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.372 + // Note translate twice in case of page boundaries. Maybe worth
1.373 + // adding a page-boundary check to skip the second translation
1.374 + } else {
1.375 + load_reg( R_EAX, Rm );
1.376 + check_ralign16( R_EAX );
1.377 + MMU_TRANSLATE_READ( R_EAX );
1.378 + PUSH_realigned_r32( R_EAX );
1.379 + load_reg( R_EAX, Rn );
1.380 + check_ralign16( R_EAX );
1.381 + MMU_TRANSLATE_READ( R_EAX );
1.382 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
1.383 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.384 + }
1.385 + MEM_READ_WORD( R_EAX, R_EAX );
1.386 + POP_r32( R_ECX );
1.387 + PUSH_r32( R_EAX );
1.388 MEM_READ_WORD( R_ECX, R_EAX );
1.389 POP_realigned_r32( R_ECX );
1.390 IMUL_r32( R_ECX );
1.391 @@ -744,9 +765,10 @@
1.392 OR.B #imm, @(R0, GBR) {:
1.393 load_reg( R_EAX, 0 );
1.394 load_spreg( R_ECX, R_GBR );
1.395 - ADD_r32_r32( R_EAX, R_ECX );
1.396 - PUSH_realigned_r32(R_ECX);
1.397 - MEM_READ_BYTE( R_ECX, R_EAX );
1.398 + ADD_r32_r32( R_ECX, R_EAX );
1.399 + MMU_TRANSLATE_WRITE( R_EAX );
1.400 + PUSH_realigned_r32(R_EAX);
1.401 + MEM_READ_BYTE( R_EAX, R_EAX );
1.402 POP_realigned_r32(R_ECX);
1.403 OR_imm32_r32(imm, R_EAX );
1.404 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.405 @@ -940,12 +962,14 @@
1.406 sh4_x86.tstate = TSTATE_NONE;
1.407 :}
1.408 TAS.B @Rn {:
1.409 - load_reg( R_ECX, Rn );
1.410 - MEM_READ_BYTE( R_ECX, R_EAX );
1.411 + load_reg( R_EAX, Rn );
1.412 + MMU_TRANSLATE_WRITE( R_EAX );
1.413 + PUSH_realigned_r32( R_EAX );
1.414 + MEM_READ_BYTE( R_EAX, R_EAX );
1.415 TEST_r8_r8( R_AL, R_AL );
1.416 SETE_t();
1.417 OR_imm8_r8( 0x80, R_AL );
1.418 - load_reg( R_ECX, Rn );
1.419 + POP_realigned_r32( R_ECX );
1.420 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.421 sh4_x86.tstate = TSTATE_NONE;
1.422 :}
1.423 @@ -965,8 +989,9 @@
1.424 TST.B #imm, @(R0, GBR) {:
1.425 load_reg( R_EAX, 0);
1.426 load_reg( R_ECX, R_GBR);
1.427 - ADD_r32_r32( R_EAX, R_ECX );
1.428 - MEM_READ_BYTE( R_ECX, R_EAX );
1.429 + ADD_r32_r32( R_ECX, R_EAX );
1.430 + MMU_TRANSLATE_READ( R_EAX );
1.431 + MEM_READ_BYTE( R_EAX, R_EAX );
1.432 TEST_imm8_r8( imm, R_AL );
1.433 SETE_t();
1.434 sh4_x86.tstate = TSTATE_E;
1.435 @@ -987,9 +1012,10 @@
1.436 XOR.B #imm, @(R0, GBR) {:
1.437 load_reg( R_EAX, 0 );
1.438 load_spreg( R_ECX, R_GBR );
1.439 - ADD_r32_r32( R_EAX, R_ECX );
1.440 - PUSH_realigned_r32(R_ECX);
1.441 - MEM_READ_BYTE(R_ECX, R_EAX);
1.442 + ADD_r32_r32( R_ECX, R_EAX );
1.443 + MMU_TRANSLATE_WRITE( R_EAX );
1.444 + PUSH_realigned_r32(R_EAX);
1.445 + MEM_READ_BYTE(R_EAX, R_EAX);
1.446 POP_realigned_r32(R_ECX);
1.447 XOR_imm32_r32( imm, R_EAX );
1.448 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.449 @@ -1015,159 +1041,165 @@
1.450 store_reg( R_EAX, Rn );
1.451 :}
1.452 MOV.B Rm, @Rn {:
1.453 - load_reg( R_EAX, Rm );
1.454 - load_reg( R_ECX, Rn );
1.455 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.456 + load_reg( R_EAX, Rn );
1.457 + MMU_TRANSLATE_WRITE( R_EAX );
1.458 + load_reg( R_EDX, Rm );
1.459 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.460 sh4_x86.tstate = TSTATE_NONE;
1.461 :}
1.462 MOV.B Rm, @-Rn {:
1.463 - load_reg( R_EAX, Rm );
1.464 - load_reg( R_ECX, Rn );
1.465 - ADD_imm8s_r32( -1, R_ECX );
1.466 - store_reg( R_ECX, Rn );
1.467 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.468 + load_reg( R_EAX, Rn );
1.469 + ADD_imm8s_r32( -1, R_EAX );
1.470 + MMU_TRANSLATE_WRITE( R_EAX );
1.471 + load_reg( R_EDX, Rm );
1.472 + ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
1.473 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.474 sh4_x86.tstate = TSTATE_NONE;
1.475 :}
1.476 MOV.B Rm, @(R0, Rn) {:
1.477 load_reg( R_EAX, 0 );
1.478 load_reg( R_ECX, Rn );
1.479 - ADD_r32_r32( R_EAX, R_ECX );
1.480 - load_reg( R_EAX, Rm );
1.481 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.482 + ADD_r32_r32( R_ECX, R_EAX );
1.483 + MMU_TRANSLATE_WRITE( R_EAX );
1.484 + load_reg( R_EDX, Rm );
1.485 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.486 sh4_x86.tstate = TSTATE_NONE;
1.487 :}
1.488 MOV.B R0, @(disp, GBR) {:
1.489 - load_reg( R_EAX, 0 );
1.490 - load_spreg( R_ECX, R_GBR );
1.491 - ADD_imm32_r32( disp, R_ECX );
1.492 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.493 + load_spreg( R_EAX, R_GBR );
1.494 + ADD_imm32_r32( disp, R_EAX );
1.495 + MMU_TRANSLATE_WRITE( R_EAX );
1.496 + load_reg( R_EDX, 0 );
1.497 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.498 sh4_x86.tstate = TSTATE_NONE;
1.499 :}
1.500 MOV.B R0, @(disp, Rn) {:
1.501 - load_reg( R_EAX, 0 );
1.502 - load_reg( R_ECX, Rn );
1.503 - ADD_imm32_r32( disp, R_ECX );
1.504 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.505 + load_reg( R_EAX, Rn );
1.506 + ADD_imm32_r32( disp, R_EAX );
1.507 + MMU_TRANSLATE_WRITE( R_EAX );
1.508 + load_reg( R_EDX, 0 );
1.509 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.510 sh4_x86.tstate = TSTATE_NONE;
1.511 :}
1.512 MOV.B @Rm, Rn {:
1.513 - load_reg( R_ECX, Rm );
1.514 - MEM_READ_BYTE( R_ECX, R_EAX );
1.515 + load_reg( R_EAX, Rm );
1.516 + MMU_TRANSLATE_READ( R_EAX );
1.517 + MEM_READ_BYTE( R_EAX, R_EAX );
1.518 store_reg( R_EAX, Rn );
1.519 sh4_x86.tstate = TSTATE_NONE;
1.520 :}
1.521 MOV.B @Rm+, Rn {:
1.522 - load_reg( R_ECX, Rm );
1.523 - MOV_r32_r32( R_ECX, R_EAX );
1.524 - ADD_imm8s_r32( 1, R_EAX );
1.525 - store_reg( R_EAX, Rm );
1.526 - MEM_READ_BYTE( R_ECX, R_EAX );
1.527 + load_reg( R_EAX, Rm );
1.528 + MMU_TRANSLATE_READ( R_EAX );
1.529 + ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
1.530 + MEM_READ_BYTE( R_EAX, R_EAX );
1.531 store_reg( R_EAX, Rn );
1.532 sh4_x86.tstate = TSTATE_NONE;
1.533 :}
1.534 MOV.B @(R0, Rm), Rn {:
1.535 load_reg( R_EAX, 0 );
1.536 load_reg( R_ECX, Rm );
1.537 - ADD_r32_r32( R_EAX, R_ECX );
1.538 - MEM_READ_BYTE( R_ECX, R_EAX );
1.539 + ADD_r32_r32( R_ECX, R_EAX );
1.540 + MMU_TRANSLATE_READ( R_EAX )
1.541 + MEM_READ_BYTE( R_EAX, R_EAX );
1.542 store_reg( R_EAX, Rn );
1.543 sh4_x86.tstate = TSTATE_NONE;
1.544 :}
1.545 MOV.B @(disp, GBR), R0 {:
1.546 - load_spreg( R_ECX, R_GBR );
1.547 - ADD_imm32_r32( disp, R_ECX );
1.548 - MEM_READ_BYTE( R_ECX, R_EAX );
1.549 + load_spreg( R_EAX, R_GBR );
1.550 + ADD_imm32_r32( disp, R_EAX );
1.551 + MMU_TRANSLATE_READ( R_EAX );
1.552 + MEM_READ_BYTE( R_EAX, R_EAX );
1.553 store_reg( R_EAX, 0 );
1.554 sh4_x86.tstate = TSTATE_NONE;
1.555 :}
1.556 MOV.B @(disp, Rm), R0 {:
1.557 - load_reg( R_ECX, Rm );
1.558 - ADD_imm32_r32( disp, R_ECX );
1.559 - MEM_READ_BYTE( R_ECX, R_EAX );
1.560 + load_reg( R_EAX, Rm );
1.561 + ADD_imm32_r32( disp, R_EAX );
1.562 + MMU_TRANSLATE_READ( R_EAX );
1.563 + MEM_READ_BYTE( R_EAX, R_EAX );
1.564 store_reg( R_EAX, 0 );
1.565 sh4_x86.tstate = TSTATE_NONE;
1.566 :}
1.567 MOV.L Rm, @Rn {:
1.568 - load_reg( R_EAX, Rm );
1.569 - load_reg( R_ECX, Rn );
1.570 - precheck();
1.571 - check_walign32(R_ECX);
1.572 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.573 + load_reg( R_EAX, Rn );
1.574 + check_walign32(R_EAX);
1.575 + MMU_TRANSLATE_WRITE( R_EAX );
1.576 + load_reg( R_EDX, Rm );
1.577 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.578 sh4_x86.tstate = TSTATE_NONE;
1.579 :}
1.580 MOV.L Rm, @-Rn {:
1.581 - load_reg( R_EAX, Rm );
1.582 - load_reg( R_ECX, Rn );
1.583 - precheck();
1.584 - check_walign32( R_ECX );
1.585 - ADD_imm8s_r32( -4, R_ECX );
1.586 - store_reg( R_ECX, Rn );
1.587 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.588 + load_reg( R_EAX, Rn );
1.589 + ADD_imm8s_r32( -4, R_EAX );
1.590 + check_walign32( R_EAX );
1.591 + MMU_TRANSLATE_WRITE( R_EAX );
1.592 + load_reg( R_EDX, Rm );
1.593 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.594 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.595 sh4_x86.tstate = TSTATE_NONE;
1.596 :}
1.597 MOV.L Rm, @(R0, Rn) {:
1.598 load_reg( R_EAX, 0 );
1.599 load_reg( R_ECX, Rn );
1.600 - ADD_r32_r32( R_EAX, R_ECX );
1.601 - precheck();
1.602 - check_walign32( R_ECX );
1.603 - load_reg( R_EAX, Rm );
1.604 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.605 + ADD_r32_r32( R_ECX, R_EAX );
1.606 + check_walign32( R_EAX );
1.607 + MMU_TRANSLATE_WRITE( R_EAX );
1.608 + load_reg( R_EDX, Rm );
1.609 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.610 sh4_x86.tstate = TSTATE_NONE;
1.611 :}
1.612 MOV.L R0, @(disp, GBR) {:
1.613 - load_spreg( R_ECX, R_GBR );
1.614 - load_reg( R_EAX, 0 );
1.615 - ADD_imm32_r32( disp, R_ECX );
1.616 - precheck();
1.617 - check_walign32( R_ECX );
1.618 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.619 + load_spreg( R_EAX, R_GBR );
1.620 + ADD_imm32_r32( disp, R_EAX );
1.621 + check_walign32( R_EAX );
1.622 + MMU_TRANSLATE_WRITE( R_EAX );
1.623 + load_reg( R_EDX, 0 );
1.624 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.625 sh4_x86.tstate = TSTATE_NONE;
1.626 :}
1.627 MOV.L Rm, @(disp, Rn) {:
1.628 - load_reg( R_ECX, Rn );
1.629 - load_reg( R_EAX, Rm );
1.630 - ADD_imm32_r32( disp, R_ECX );
1.631 - precheck();
1.632 - check_walign32( R_ECX );
1.633 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.634 + load_reg( R_EAX, Rn );
1.635 + ADD_imm32_r32( disp, R_EAX );
1.636 + check_walign32( R_EAX );
1.637 + MMU_TRANSLATE_WRITE( R_EAX );
1.638 + load_reg( R_EDX, Rm );
1.639 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.640 sh4_x86.tstate = TSTATE_NONE;
1.641 :}
1.642 MOV.L @Rm, Rn {:
1.643 - load_reg( R_ECX, Rm );
1.644 - precheck();
1.645 - check_ralign32( R_ECX );
1.646 - MEM_READ_LONG( R_ECX, R_EAX );
1.647 + load_reg( R_EAX, Rm );
1.648 + check_ralign32( R_EAX );
1.649 + MMU_TRANSLATE_READ( R_EAX );
1.650 + MEM_READ_LONG( R_EAX, R_EAX );
1.651 store_reg( R_EAX, Rn );
1.652 sh4_x86.tstate = TSTATE_NONE;
1.653 :}
1.654 MOV.L @Rm+, Rn {:
1.655 load_reg( R_EAX, Rm );
1.656 - precheck();
1.657 check_ralign32( R_EAX );
1.658 - MOV_r32_r32( R_EAX, R_ECX );
1.659 - ADD_imm8s_r32( 4, R_EAX );
1.660 - store_reg( R_EAX, Rm );
1.661 - MEM_READ_LONG( R_ECX, R_EAX );
1.662 + MMU_TRANSLATE_READ( R_EAX );
1.663 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.664 + MEM_READ_LONG( R_EAX, R_EAX );
1.665 store_reg( R_EAX, Rn );
1.666 sh4_x86.tstate = TSTATE_NONE;
1.667 :}
1.668 MOV.L @(R0, Rm), Rn {:
1.669 load_reg( R_EAX, 0 );
1.670 load_reg( R_ECX, Rm );
1.671 - ADD_r32_r32( R_EAX, R_ECX );
1.672 - precheck();
1.673 - check_ralign32( R_ECX );
1.674 - MEM_READ_LONG( R_ECX, R_EAX );
1.675 + ADD_r32_r32( R_ECX, R_EAX );
1.676 + check_ralign32( R_EAX );
1.677 + MMU_TRANSLATE_READ( R_EAX );
1.678 + MEM_READ_LONG( R_EAX, R_EAX );
1.679 store_reg( R_EAX, Rn );
1.680 sh4_x86.tstate = TSTATE_NONE;
1.681 :}
1.682 MOV.L @(disp, GBR), R0 {:
1.683 - load_spreg( R_ECX, R_GBR );
1.684 - ADD_imm32_r32( disp, R_ECX );
1.685 - precheck();
1.686 - check_ralign32( R_ECX );
1.687 - MEM_READ_LONG( R_ECX, R_EAX );
1.688 + load_spreg( R_EAX, R_GBR );
1.689 + ADD_imm32_r32( disp, R_EAX );
1.690 + check_ralign32( R_EAX );
1.691 + MMU_TRANSLATE_READ( R_EAX );
1.692 + MEM_READ_LONG( R_EAX, R_EAX );
1.693 store_reg( R_EAX, 0 );
1.694 sh4_x86.tstate = TSTATE_NONE;
1.695 :}
1.696 @@ -1176,107 +1208,119 @@
1.697 SLOTILLEGAL();
1.698 } else {
1.699 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1.700 - sh4ptr_t ptr = mem_get_region(target);
1.701 - if( ptr != NULL ) {
1.702 + if( IS_IN_ICACHE(target) ) {
1.703 + // If the target address is in the same page as the code, it's
1.704 + // pretty safe to just ref it directly and circumvent the whole
1.705 + // memory subsystem. (this is a big performance win)
1.706 +
1.707 + // FIXME: There's a corner-case that's not handled here when
1.708 + // the current code-page is in the ITLB but not in the UTLB.
1.709 + // (should generate a TLB miss although need to test SH4
1.710 + // behaviour to confirm) Unlikely to be anyone depending on this
1.711 + // behaviour though.
1.712 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.713 MOV_moff32_EAX( ptr );
1.714 } else {
1.715 - load_imm32( R_ECX, target );
1.716 - MEM_READ_LONG( R_ECX, R_EAX );
1.717 + // Note: we use sh4r.pc for the calc as we could be running at a
1.718 + // different virtual address than the translation was done with,
1.719 + // but we can safely assume that the low bits are the same.
1.720 + load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.721 + ADD_sh4r_r32( R_PC, R_EAX );
1.722 + MMU_TRANSLATE_READ( R_EAX );
1.723 + MEM_READ_LONG( R_EAX, R_EAX );
1.724 + sh4_x86.tstate = TSTATE_NONE;
1.725 }
1.726 store_reg( R_EAX, Rn );
1.727 - sh4_x86.tstate = TSTATE_NONE;
1.728 }
1.729 :}
1.730 MOV.L @(disp, Rm), Rn {:
1.731 - load_reg( R_ECX, Rm );
1.732 - ADD_imm8s_r32( disp, R_ECX );
1.733 - precheck();
1.734 - check_ralign32( R_ECX );
1.735 - MEM_READ_LONG( R_ECX, R_EAX );
1.736 + load_reg( R_EAX, Rm );
1.737 + ADD_imm8s_r32( disp, R_EAX );
1.738 + check_ralign32( R_EAX );
1.739 + MMU_TRANSLATE_READ( R_EAX );
1.740 + MEM_READ_LONG( R_EAX, R_EAX );
1.741 store_reg( R_EAX, Rn );
1.742 sh4_x86.tstate = TSTATE_NONE;
1.743 :}
1.744 MOV.W Rm, @Rn {:
1.745 - load_reg( R_ECX, Rn );
1.746 - precheck();
1.747 - check_walign16( R_ECX );
1.748 - load_reg( R_EAX, Rm );
1.749 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.750 + load_reg( R_EAX, Rn );
1.751 + check_walign16( R_EAX );
1.752 + MMU_TRANSLATE_WRITE( R_EAX )
1.753 + load_reg( R_EDX, Rm );
1.754 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.755 sh4_x86.tstate = TSTATE_NONE;
1.756 :}
1.757 MOV.W Rm, @-Rn {:
1.758 - load_reg( R_ECX, Rn );
1.759 - precheck();
1.760 - check_walign16( R_ECX );
1.761 - load_reg( R_EAX, Rm );
1.762 - ADD_imm8s_r32( -2, R_ECX );
1.763 - store_reg( R_ECX, Rn );
1.764 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.765 + load_reg( R_EAX, Rn );
1.766 + ADD_imm8s_r32( -2, R_EAX );
1.767 + check_walign16( R_EAX );
1.768 + MMU_TRANSLATE_WRITE( R_EAX );
1.769 + load_reg( R_EDX, Rm );
1.770 + ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1.771 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.772 sh4_x86.tstate = TSTATE_NONE;
1.773 :}
1.774 MOV.W Rm, @(R0, Rn) {:
1.775 load_reg( R_EAX, 0 );
1.776 load_reg( R_ECX, Rn );
1.777 - ADD_r32_r32( R_EAX, R_ECX );
1.778 - precheck();
1.779 - check_walign16( R_ECX );
1.780 - load_reg( R_EAX, Rm );
1.781 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.782 + ADD_r32_r32( R_ECX, R_EAX );
1.783 + check_walign16( R_EAX );
1.784 + MMU_TRANSLATE_WRITE( R_EAX );
1.785 + load_reg( R_EDX, Rm );
1.786 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.787 sh4_x86.tstate = TSTATE_NONE;
1.788 :}
1.789 MOV.W R0, @(disp, GBR) {:
1.790 - load_spreg( R_ECX, R_GBR );
1.791 - load_reg( R_EAX, 0 );
1.792 - ADD_imm32_r32( disp, R_ECX );
1.793 - precheck();
1.794 - check_walign16( R_ECX );
1.795 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.796 + load_spreg( R_EAX, R_GBR );
1.797 + ADD_imm32_r32( disp, R_EAX );
1.798 + check_walign16( R_EAX );
1.799 + MMU_TRANSLATE_WRITE( R_EAX );
1.800 + load_reg( R_EDX, 0 );
1.801 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.802 sh4_x86.tstate = TSTATE_NONE;
1.803 :}
1.804 MOV.W R0, @(disp, Rn) {:
1.805 - load_reg( R_ECX, Rn );
1.806 - load_reg( R_EAX, 0 );
1.807 - ADD_imm32_r32( disp, R_ECX );
1.808 - precheck();
1.809 - check_walign16( R_ECX );
1.810 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.811 + load_reg( R_EAX, Rn );
1.812 + ADD_imm32_r32( disp, R_EAX );
1.813 + check_walign16( R_EAX );
1.814 + MMU_TRANSLATE_WRITE( R_EAX );
1.815 + load_reg( R_EDX, 0 );
1.816 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.817 sh4_x86.tstate = TSTATE_NONE;
1.818 :}
1.819 MOV.W @Rm, Rn {:
1.820 - load_reg( R_ECX, Rm );
1.821 - precheck();
1.822 - check_ralign16( R_ECX );
1.823 - MEM_READ_WORD( R_ECX, R_EAX );
1.824 + load_reg( R_EAX, Rm );
1.825 + check_ralign16( R_EAX );
1.826 + MMU_TRANSLATE_READ( R_EAX );
1.827 + MEM_READ_WORD( R_EAX, R_EAX );
1.828 store_reg( R_EAX, Rn );
1.829 sh4_x86.tstate = TSTATE_NONE;
1.830 :}
1.831 MOV.W @Rm+, Rn {:
1.832 load_reg( R_EAX, Rm );
1.833 - precheck();
1.834 check_ralign16( R_EAX );
1.835 - MOV_r32_r32( R_EAX, R_ECX );
1.836 - ADD_imm8s_r32( 2, R_EAX );
1.837 - store_reg( R_EAX, Rm );
1.838 - MEM_READ_WORD( R_ECX, R_EAX );
1.839 + MMU_TRANSLATE_READ( R_EAX );
1.840 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.841 + MEM_READ_WORD( R_EAX, R_EAX );
1.842 store_reg( R_EAX, Rn );
1.843 sh4_x86.tstate = TSTATE_NONE;
1.844 :}
1.845 MOV.W @(R0, Rm), Rn {:
1.846 load_reg( R_EAX, 0 );
1.847 load_reg( R_ECX, Rm );
1.848 - ADD_r32_r32( R_EAX, R_ECX );
1.849 - precheck();
1.850 - check_ralign16( R_ECX );
1.851 - MEM_READ_WORD( R_ECX, R_EAX );
1.852 + ADD_r32_r32( R_ECX, R_EAX );
1.853 + check_ralign16( R_EAX );
1.854 + MMU_TRANSLATE_READ( R_EAX );
1.855 + MEM_READ_WORD( R_EAX, R_EAX );
1.856 store_reg( R_EAX, Rn );
1.857 sh4_x86.tstate = TSTATE_NONE;
1.858 :}
1.859 MOV.W @(disp, GBR), R0 {:
1.860 - load_spreg( R_ECX, R_GBR );
1.861 - ADD_imm32_r32( disp, R_ECX );
1.862 - precheck();
1.863 - check_ralign16( R_ECX );
1.864 - MEM_READ_WORD( R_ECX, R_EAX );
1.865 + load_spreg( R_EAX, R_GBR );
1.866 + ADD_imm32_r32( disp, R_EAX );
1.867 + check_ralign16( R_EAX );
1.868 + MMU_TRANSLATE_READ( R_EAX );
1.869 + MEM_READ_WORD( R_EAX, R_EAX );
1.870 store_reg( R_EAX, 0 );
1.871 sh4_x86.tstate = TSTATE_NONE;
1.872 :}
1.873 @@ -1284,18 +1328,28 @@
1.874 if( sh4_x86.in_delay_slot ) {
1.875 SLOTILLEGAL();
1.876 } else {
1.877 - load_imm32( R_ECX, pc + disp + 4 );
1.878 - MEM_READ_WORD( R_ECX, R_EAX );
1.879 + // See comments for MOV.L @(disp, PC), Rn
1.880 + uint32_t target = pc + disp + 4;
1.881 + if( IS_IN_ICACHE(target) ) {
1.882 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.883 + MOV_moff32_EAX( ptr );
1.884 + MOVSX_r16_r32( R_EAX, R_EAX );
1.885 + } else {
1.886 + load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1.887 + ADD_sh4r_r32( R_PC, R_EAX );
1.888 + MMU_TRANSLATE_READ( R_EAX );
1.889 + MEM_READ_WORD( R_EAX, R_EAX );
1.890 + sh4_x86.tstate = TSTATE_NONE;
1.891 + }
1.892 store_reg( R_EAX, Rn );
1.893 - sh4_x86.tstate = TSTATE_NONE;
1.894 }
1.895 :}
1.896 MOV.W @(disp, Rm), R0 {:
1.897 - load_reg( R_ECX, Rm );
1.898 - ADD_imm32_r32( disp, R_ECX );
1.899 - precheck();
1.900 - check_ralign16( R_ECX );
1.901 - MEM_READ_WORD( R_ECX, R_EAX );
1.902 + load_reg( R_EAX, Rm );
1.903 + ADD_imm32_r32( disp, R_EAX );
1.904 + check_ralign16( R_EAX );
1.905 + MMU_TRANSLATE_READ( R_EAX );
1.906 + MEM_READ_WORD( R_EAX, R_EAX );
1.907 store_reg( R_EAX, 0 );
1.908 sh4_x86.tstate = TSTATE_NONE;
1.909 :}
1.910 @@ -1303,16 +1357,18 @@
1.911 if( sh4_x86.in_delay_slot ) {
1.912 SLOTILLEGAL();
1.913 } else {
1.914 - load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
1.915 + load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.916 + ADD_sh4r_r32( R_PC, R_ECX );
1.917 store_reg( R_ECX, 0 );
1.918 + sh4_x86.tstate = TSTATE_NONE;
1.919 }
1.920 :}
1.921 MOVCA.L R0, @Rn {:
1.922 - load_reg( R_EAX, 0 );
1.923 - load_reg( R_ECX, Rn );
1.924 - precheck();
1.925 - check_walign32( R_ECX );
1.926 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.927 + load_reg( R_EAX, Rn );
1.928 + check_walign32( R_EAX );
1.929 + MMU_TRANSLATE_WRITE( R_EAX );
1.930 + load_reg( R_EDX, 0 );
1.931 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.932 sh4_x86.tstate = TSTATE_NONE;
1.933 :}
1.934
1.935 @@ -1321,8 +1377,9 @@
1.936 if( sh4_x86.in_delay_slot ) {
1.937 SLOTILLEGAL();
1.938 } else {
1.939 - JT_rel8( EXIT_BLOCK_SIZE, nottaken );
1.940 - exit_block( disp + pc + 4, pc+2 );
1.941 + sh4vma_t target = disp + pc + 4;
1.942 + JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1.943 + exit_block_rel(target, pc+2 );
1.944 JMP_TARGET(nottaken);
1.945 return 2;
1.946 }
1.947 @@ -1331,6 +1388,7 @@
1.948 if( sh4_x86.in_delay_slot ) {
1.949 SLOTILLEGAL();
1.950 } else {
1.951 + sh4vma_t target = disp + pc + 4;
1.952 sh4_x86.in_delay_slot = TRUE;
1.953 if( sh4_x86.tstate == TSTATE_NONE ) {
1.954 CMP_imm8s_sh4r( 1, R_T );
1.955 @@ -1338,7 +1396,7 @@
1.956 }
1.957 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
1.958 sh4_translate_instruction(pc+2);
1.959 - exit_block( disp + pc + 4, pc+4 );
1.960 + exit_block_rel( target, pc+4 );
1.961 // not taken
1.962 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.963 sh4_translate_instruction(pc+2);
1.964 @@ -1351,7 +1409,7 @@
1.965 } else {
1.966 sh4_x86.in_delay_slot = TRUE;
1.967 sh4_translate_instruction( pc + 2 );
1.968 - exit_block( disp + pc + 4, pc+4 );
1.969 + exit_block_rel( disp + pc + 4, pc+4 );
1.970 sh4_x86.branch_taken = TRUE;
1.971 return 4;
1.972 }
1.973 @@ -1379,7 +1437,7 @@
1.974 store_spreg( R_EAX, R_PR );
1.975 sh4_x86.in_delay_slot = TRUE;
1.976 sh4_translate_instruction( pc + 2 );
1.977 - exit_block( disp + pc + 4, pc+4 );
1.978 + exit_block_rel( disp + pc + 4, pc+4 );
1.979 sh4_x86.branch_taken = TRUE;
1.980 return 4;
1.981 }
1.982 @@ -1404,8 +1462,9 @@
1.983 if( sh4_x86.in_delay_slot ) {
1.984 SLOTILLEGAL();
1.985 } else {
1.986 - JF_rel8( EXIT_BLOCK_SIZE, nottaken );
1.987 - exit_block( disp + pc + 4, pc+2 );
1.988 + sh4vma_t target = disp + pc + 4;
1.989 + JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1.990 + exit_block_rel(target, pc+2 );
1.991 JMP_TARGET(nottaken);
1.992 return 2;
1.993 }
1.994 @@ -1421,7 +1480,7 @@
1.995 }
1.996 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
1.997 sh4_translate_instruction(pc+2);
1.998 - exit_block( disp + pc + 4, pc+4 );
1.999 + exit_block_rel( disp + pc + 4, pc+4 );
1.1000 // not taken
1.1001 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.1002 sh4_translate_instruction(pc+2);
1.1003 @@ -1506,8 +1565,7 @@
1.1004 if( sh4_x86.in_delay_slot ) {
1.1005 SLOTILLEGAL();
1.1006 } else {
1.1007 - precheck();
1.1008 - JMP_exit(EXIT_ILLEGAL);
1.1009 + JMP_exc(EXC_ILLEGAL);
1.1010 return 2;
1.1011 }
1.1012 :}
1.1013 @@ -1591,198 +1649,196 @@
1.1014 sh4_x86.tstate = TSTATE_NONE;
1.1015 :}
1.1016 FMOV FRm, @Rn {:
1.1017 - precheck();
1.1018 - check_fpuen_no_precheck();
1.1019 - load_reg( R_ECX, Rn );
1.1020 - check_walign32( R_ECX );
1.1021 + check_fpuen();
1.1022 + load_reg( R_EAX, Rn );
1.1023 + check_walign32( R_EAX );
1.1024 + MMU_TRANSLATE_WRITE( R_EAX );
1.1025 load_spreg( R_EDX, R_FPSCR );
1.1026 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1027 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
1.1028 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1.1029 load_fr_bank( R_EDX );
1.1030 - load_fr( R_EDX, R_EAX, FRm );
1.1031 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1032 + load_fr( R_EDX, R_ECX, FRm );
1.1033 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1034 if( FRm&1 ) {
1.1035 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1.1036 JMP_TARGET(doublesize);
1.1037 load_xf_bank( R_EDX );
1.1038 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1039 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1040 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1041 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1042 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1043 JMP_TARGET(end);
1.1044 } else {
1.1045 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1.1046 JMP_TARGET(doublesize);
1.1047 load_fr_bank( R_EDX );
1.1048 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1049 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1050 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1051 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1052 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1053 JMP_TARGET(end);
1.1054 }
1.1055 sh4_x86.tstate = TSTATE_NONE;
1.1056 :}
1.1057 FMOV @Rm, FRn {:
1.1058 - precheck();
1.1059 - check_fpuen_no_precheck();
1.1060 - load_reg( R_ECX, Rm );
1.1061 - check_ralign32( R_ECX );
1.1062 + check_fpuen();
1.1063 + load_reg( R_EAX, Rm );
1.1064 + check_ralign32( R_EAX );
1.1065 + MMU_TRANSLATE_READ( R_EAX );
1.1066 load_spreg( R_EDX, R_FPSCR );
1.1067 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1068 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
1.1069 - MEM_READ_LONG( R_ECX, R_EAX );
1.1070 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1.1071 + MEM_READ_LONG( R_EAX, R_EAX );
1.1072 load_fr_bank( R_EDX );
1.1073 store_fr( R_EDX, R_EAX, FRn );
1.1074 if( FRn&1 ) {
1.1075 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1.1076 JMP_TARGET(doublesize);
1.1077 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1078 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1079 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1080 load_xf_bank( R_EDX );
1.1081 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1082 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1083 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1084 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1085 JMP_TARGET(end);
1.1086 } else {
1.1087 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1.1088 JMP_TARGET(doublesize);
1.1089 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1090 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1091 load_fr_bank( R_EDX );
1.1092 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1093 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1094 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1095 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1096 JMP_TARGET(end);
1.1097 }
1.1098 sh4_x86.tstate = TSTATE_NONE;
1.1099 :}
1.1100 FMOV FRm, @-Rn {:
1.1101 - precheck();
1.1102 - check_fpuen_no_precheck();
1.1103 - load_reg( R_ECX, Rn );
1.1104 - check_walign32( R_ECX );
1.1105 + check_fpuen();
1.1106 + load_reg( R_EAX, Rn );
1.1107 + check_walign32( R_EAX );
1.1108 load_spreg( R_EDX, R_FPSCR );
1.1109 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1110 - JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);
1.1111 + JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
1.1112 + ADD_imm8s_r32( -4, R_EAX );
1.1113 + MMU_TRANSLATE_WRITE( R_EAX );
1.1114 load_fr_bank( R_EDX );
1.1115 - load_fr( R_EDX, R_EAX, FRm );
1.1116 - ADD_imm8s_r32(-4,R_ECX);
1.1117 - store_reg( R_ECX, Rn );
1.1118 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1119 + load_fr( R_EDX, R_ECX, FRm );
1.1120 + ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1.1121 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1122 if( FRm&1 ) {
1.1123 - JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
1.1124 + JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1.1125 JMP_TARGET(doublesize);
1.1126 + ADD_imm8s_r32(-8,R_EAX);
1.1127 + MMU_TRANSLATE_WRITE( R_EAX );
1.1128 load_xf_bank( R_EDX );
1.1129 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1130 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1131 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1132 - ADD_imm8s_r32(-8,R_ECX);
1.1133 - store_reg( R_ECX, Rn );
1.1134 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1135 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.1136 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1137 JMP_TARGET(end);
1.1138 } else {
1.1139 - JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
1.1140 + JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1.1141 JMP_TARGET(doublesize);
1.1142 + ADD_imm8s_r32(-8,R_EAX);
1.1143 + MMU_TRANSLATE_WRITE( R_EAX );
1.1144 load_fr_bank( R_EDX );
1.1145 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1146 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1147 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1148 - ADD_imm8s_r32(-8,R_ECX);
1.1149 - store_reg( R_ECX, Rn );
1.1150 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1151 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.1152 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1153 JMP_TARGET(end);
1.1154 }
1.1155 sh4_x86.tstate = TSTATE_NONE;
1.1156 :}
1.1157 FMOV @Rm+, FRn {:
1.1158 - precheck();
1.1159 - check_fpuen_no_precheck();
1.1160 - load_reg( R_ECX, Rm );
1.1161 - check_ralign32( R_ECX );
1.1162 - MOV_r32_r32( R_ECX, R_EAX );
1.1163 + check_fpuen();
1.1164 + load_reg( R_EAX, Rm );
1.1165 + check_ralign32( R_EAX );
1.1166 + MMU_TRANSLATE_READ( R_EAX );
1.1167 load_spreg( R_EDX, R_FPSCR );
1.1168 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1169 - JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);
1.1170 - ADD_imm8s_r32( 4, R_EAX );
1.1171 - store_reg( R_EAX, Rm );
1.1172 - MEM_READ_LONG( R_ECX, R_EAX );
1.1173 + JNE_rel8(12 + MEM_READ_SIZE, doublesize);
1.1174 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1175 + MEM_READ_LONG( R_EAX, R_EAX );
1.1176 load_fr_bank( R_EDX );
1.1177 store_fr( R_EDX, R_EAX, FRn );
1.1178 if( FRn&1 ) {
1.1179 - JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
1.1180 + JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
1.1181 JMP_TARGET(doublesize);
1.1182 - ADD_imm8s_r32( 8, R_EAX );
1.1183 - store_reg(R_EAX, Rm);
1.1184 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1185 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.1186 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1187 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1188 load_xf_bank( R_EDX );
1.1189 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1190 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1191 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1192 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1193 JMP_TARGET(end);
1.1194 } else {
1.1195 - JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
1.1196 - ADD_imm8s_r32( 8, R_EAX );
1.1197 - store_reg(R_EAX, Rm);
1.1198 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1199 + JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
1.1200 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.1201 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1202 load_fr_bank( R_EDX );
1.1203 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1204 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1205 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1206 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1207 JMP_TARGET(end);
1.1208 }
1.1209 sh4_x86.tstate = TSTATE_NONE;
1.1210 :}
1.1211 FMOV FRm, @(R0, Rn) {:
1.1212 - precheck();
1.1213 - check_fpuen_no_precheck();
1.1214 - load_reg( R_ECX, Rn );
1.1215 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.1216 - check_walign32( R_ECX );
1.1217 + check_fpuen();
1.1218 + load_reg( R_EAX, Rn );
1.1219 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.1220 + check_walign32( R_EAX );
1.1221 + MMU_TRANSLATE_WRITE( R_EAX );
1.1222 load_spreg( R_EDX, R_FPSCR );
1.1223 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1224 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
1.1225 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1.1226 load_fr_bank( R_EDX );
1.1227 - load_fr( R_EDX, R_EAX, FRm );
1.1228 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1229 + load_fr( R_EDX, R_ECX, FRm );
1.1230 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1231 if( FRm&1 ) {
1.1232 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1.1233 JMP_TARGET(doublesize);
1.1234 load_xf_bank( R_EDX );
1.1235 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1236 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1237 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1238 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1239 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1240 JMP_TARGET(end);
1.1241 } else {
1.1242 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1.1243 JMP_TARGET(doublesize);
1.1244 load_fr_bank( R_EDX );
1.1245 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1246 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1247 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1248 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1249 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1250 JMP_TARGET(end);
1.1251 }
1.1252 sh4_x86.tstate = TSTATE_NONE;
1.1253 :}
1.1254 FMOV @(R0, Rm), FRn {:
1.1255 - precheck();
1.1256 - check_fpuen_no_precheck();
1.1257 - load_reg( R_ECX, Rm );
1.1258 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.1259 - check_ralign32( R_ECX );
1.1260 + check_fpuen();
1.1261 + load_reg( R_EAX, Rm );
1.1262 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.1263 + check_ralign32( R_EAX );
1.1264 + MMU_TRANSLATE_READ( R_EAX );
1.1265 load_spreg( R_EDX, R_FPSCR );
1.1266 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1267 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
1.1268 - MEM_READ_LONG( R_ECX, R_EAX );
1.1269 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1.1270 + MEM_READ_LONG( R_EAX, R_EAX );
1.1271 load_fr_bank( R_EDX );
1.1272 store_fr( R_EDX, R_EAX, FRn );
1.1273 if( FRn&1 ) {
1.1274 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1.1275 JMP_TARGET(doublesize);
1.1276 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1277 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1278 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1279 load_xf_bank( R_EDX );
1.1280 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1281 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1282 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1283 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1284 JMP_TARGET(end);
1.1285 } else {
1.1286 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1.1287 JMP_TARGET(doublesize);
1.1288 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1289 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1290 load_fr_bank( R_EDX );
1.1291 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1292 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1293 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1294 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1295 JMP_TARGET(end);
1.1296 }
1.1297 sh4_x86.tstate = TSTATE_NONE;
1.1298 @@ -2222,12 +2278,10 @@
1.1299 :}
1.1300 LDC.L @Rm+, GBR {:
1.1301 load_reg( R_EAX, Rm );
1.1302 - precheck();
1.1303 check_ralign32( R_EAX );
1.1304 - MOV_r32_r32( R_EAX, R_ECX );
1.1305 - ADD_imm8s_r32( 4, R_EAX );
1.1306 - store_reg( R_EAX, Rm );
1.1307 - MEM_READ_LONG( R_ECX, R_EAX );
1.1308 + MMU_TRANSLATE_READ( R_EAX );
1.1309 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1310 + MEM_READ_LONG( R_EAX, R_EAX );
1.1311 store_spreg( R_EAX, R_GBR );
1.1312 sh4_x86.tstate = TSTATE_NONE;
1.1313 :}
1.1314 @@ -2235,14 +2289,12 @@
1.1315 if( sh4_x86.in_delay_slot ) {
1.1316 SLOTILLEGAL();
1.1317 } else {
1.1318 - precheck();
1.1319 - check_priv_no_precheck();
1.1320 + check_priv();
1.1321 load_reg( R_EAX, Rm );
1.1322 check_ralign32( R_EAX );
1.1323 - MOV_r32_r32( R_EAX, R_ECX );
1.1324 - ADD_imm8s_r32( 4, R_EAX );
1.1325 - store_reg( R_EAX, Rm );
1.1326 - MEM_READ_LONG( R_ECX, R_EAX );
1.1327 + MMU_TRANSLATE_READ( R_EAX );
1.1328 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1329 + MEM_READ_LONG( R_EAX, R_EAX );
1.1330 call_func1( sh4_write_sr, R_EAX );
1.1331 sh4_x86.priv_checked = FALSE;
1.1332 sh4_x86.fpuen_checked = FALSE;
1.1333 @@ -2250,74 +2302,62 @@
1.1334 }
1.1335 :}
1.1336 LDC.L @Rm+, VBR {:
1.1337 - precheck();
1.1338 - check_priv_no_precheck();
1.1339 + check_priv();
1.1340 load_reg( R_EAX, Rm );
1.1341 check_ralign32( R_EAX );
1.1342 - MOV_r32_r32( R_EAX, R_ECX );
1.1343 - ADD_imm8s_r32( 4, R_EAX );
1.1344 - store_reg( R_EAX, Rm );
1.1345 - MEM_READ_LONG( R_ECX, R_EAX );
1.1346 + MMU_TRANSLATE_READ( R_EAX );
1.1347 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1348 + MEM_READ_LONG( R_EAX, R_EAX );
1.1349 store_spreg( R_EAX, R_VBR );
1.1350 sh4_x86.tstate = TSTATE_NONE;
1.1351 :}
1.1352 LDC.L @Rm+, SSR {:
1.1353 - precheck();
1.1354 - check_priv_no_precheck();
1.1355 + check_priv();
1.1356 load_reg( R_EAX, Rm );
1.1357 check_ralign32( R_EAX );
1.1358 - MOV_r32_r32( R_EAX, R_ECX );
1.1359 - ADD_imm8s_r32( 4, R_EAX );
1.1360 - store_reg( R_EAX, Rm );
1.1361 - MEM_READ_LONG( R_ECX, R_EAX );
1.1362 + MMU_TRANSLATE_READ( R_EAX );
1.1363 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1364 + MEM_READ_LONG( R_EAX, R_EAX );
1.1365 store_spreg( R_EAX, R_SSR );
1.1366 sh4_x86.tstate = TSTATE_NONE;
1.1367 :}
1.1368 LDC.L @Rm+, SGR {:
1.1369 - precheck();
1.1370 - check_priv_no_precheck();
1.1371 + check_priv();
1.1372 load_reg( R_EAX, Rm );
1.1373 check_ralign32( R_EAX );
1.1374 - MOV_r32_r32( R_EAX, R_ECX );
1.1375 - ADD_imm8s_r32( 4, R_EAX );
1.1376 - store_reg( R_EAX, Rm );
1.1377 - MEM_READ_LONG( R_ECX, R_EAX );
1.1378 + MMU_TRANSLATE_READ( R_EAX );
1.1379 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1380 + MEM_READ_LONG( R_EAX, R_EAX );
1.1381 store_spreg( R_EAX, R_SGR );
1.1382 sh4_x86.tstate = TSTATE_NONE;
1.1383 :}
1.1384 LDC.L @Rm+, SPC {:
1.1385 - precheck();
1.1386 - check_priv_no_precheck();
1.1387 + check_priv();
1.1388 load_reg( R_EAX, Rm );
1.1389 check_ralign32( R_EAX );
1.1390 - MOV_r32_r32( R_EAX, R_ECX );
1.1391 - ADD_imm8s_r32( 4, R_EAX );
1.1392 - store_reg( R_EAX, Rm );
1.1393 - MEM_READ_LONG( R_ECX, R_EAX );
1.1394 + MMU_TRANSLATE_READ( R_EAX );
1.1395 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1396 + MEM_READ_LONG( R_EAX, R_EAX );
1.1397 store_spreg( R_EAX, R_SPC );
1.1398 sh4_x86.tstate = TSTATE_NONE;
1.1399 :}
1.1400 LDC.L @Rm+, DBR {:
1.1401 - precheck();
1.1402 - check_priv_no_precheck();
1.1403 + check_priv();
1.1404 load_reg( R_EAX, Rm );
1.1405 check_ralign32( R_EAX );
1.1406 - MOV_r32_r32( R_EAX, R_ECX );
1.1407 - ADD_imm8s_r32( 4, R_EAX );
1.1408 - store_reg( R_EAX, Rm );
1.1409 - MEM_READ_LONG( R_ECX, R_EAX );
1.1410 + MMU_TRANSLATE_READ( R_EAX );
1.1411 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1412 + MEM_READ_LONG( R_EAX, R_EAX );
1.1413 store_spreg( R_EAX, R_DBR );
1.1414 sh4_x86.tstate = TSTATE_NONE;
1.1415 :}
1.1416 LDC.L @Rm+, Rn_BANK {:
1.1417 - precheck();
1.1418 - check_priv_no_precheck();
1.1419 + check_priv();
1.1420 load_reg( R_EAX, Rm );
1.1421 check_ralign32( R_EAX );
1.1422 - MOV_r32_r32( R_EAX, R_ECX );
1.1423 - ADD_imm8s_r32( 4, R_EAX );
1.1424 - store_reg( R_EAX, Rm );
1.1425 - MEM_READ_LONG( R_ECX, R_EAX );
1.1426 + MMU_TRANSLATE_READ( R_EAX );
1.1427 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1428 + MEM_READ_LONG( R_EAX, R_EAX );
1.1429 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.1430 sh4_x86.tstate = TSTATE_NONE;
1.1431 :}
1.1432 @@ -2329,12 +2369,10 @@
1.1433 :}
1.1434 LDS.L @Rm+, FPSCR {:
1.1435 load_reg( R_EAX, Rm );
1.1436 - precheck();
1.1437 check_ralign32( R_EAX );
1.1438 - MOV_r32_r32( R_EAX, R_ECX );
1.1439 - ADD_imm8s_r32( 4, R_EAX );
1.1440 - store_reg( R_EAX, Rm );
1.1441 - MEM_READ_LONG( R_ECX, R_EAX );
1.1442 + MMU_TRANSLATE_READ( R_EAX );
1.1443 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1444 + MEM_READ_LONG( R_EAX, R_EAX );
1.1445 store_spreg( R_EAX, R_FPSCR );
1.1446 update_fr_bank( R_EAX );
1.1447 sh4_x86.tstate = TSTATE_NONE;
1.1448 @@ -2345,12 +2383,10 @@
1.1449 :}
1.1450 LDS.L @Rm+, FPUL {:
1.1451 load_reg( R_EAX, Rm );
1.1452 - precheck();
1.1453 check_ralign32( R_EAX );
1.1454 - MOV_r32_r32( R_EAX, R_ECX );
1.1455 - ADD_imm8s_r32( 4, R_EAX );
1.1456 - store_reg( R_EAX, Rm );
1.1457 - MEM_READ_LONG( R_ECX, R_EAX );
1.1458 + MMU_TRANSLATE_READ( R_EAX );
1.1459 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1460 + MEM_READ_LONG( R_EAX, R_EAX );
1.1461 store_spreg( R_EAX, R_FPUL );
1.1462 sh4_x86.tstate = TSTATE_NONE;
1.1463 :}
1.1464 @@ -2360,12 +2396,10 @@
1.1465 :}
1.1466 LDS.L @Rm+, MACH {:
1.1467 load_reg( R_EAX, Rm );
1.1468 - precheck();
1.1469 check_ralign32( R_EAX );
1.1470 - MOV_r32_r32( R_EAX, R_ECX );
1.1471 - ADD_imm8s_r32( 4, R_EAX );
1.1472 - store_reg( R_EAX, Rm );
1.1473 - MEM_READ_LONG( R_ECX, R_EAX );
1.1474 + MMU_TRANSLATE_READ( R_EAX );
1.1475 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1476 + MEM_READ_LONG( R_EAX, R_EAX );
1.1477 store_spreg( R_EAX, R_MACH );
1.1478 sh4_x86.tstate = TSTATE_NONE;
1.1479 :}
1.1480 @@ -2375,12 +2409,10 @@
1.1481 :}
1.1482 LDS.L @Rm+, MACL {:
1.1483 load_reg( R_EAX, Rm );
1.1484 - precheck();
1.1485 check_ralign32( R_EAX );
1.1486 - MOV_r32_r32( R_EAX, R_ECX );
1.1487 - ADD_imm8s_r32( 4, R_EAX );
1.1488 - store_reg( R_EAX, Rm );
1.1489 - MEM_READ_LONG( R_ECX, R_EAX );
1.1490 + MMU_TRANSLATE_READ( R_EAX );
1.1491 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1492 + MEM_READ_LONG( R_EAX, R_EAX );
1.1493 store_spreg( R_EAX, R_MACL );
1.1494 sh4_x86.tstate = TSTATE_NONE;
1.1495 :}
1.1496 @@ -2390,12 +2422,10 @@
1.1497 :}
1.1498 LDS.L @Rm+, PR {:
1.1499 load_reg( R_EAX, Rm );
1.1500 - precheck();
1.1501 check_ralign32( R_EAX );
1.1502 - MOV_r32_r32( R_EAX, R_ECX );
1.1503 - ADD_imm8s_r32( 4, R_EAX );
1.1504 - store_reg( R_EAX, Rm );
1.1505 - MEM_READ_LONG( R_ECX, R_EAX );
1.1506 + MMU_TRANSLATE_READ( R_EAX );
1.1507 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1508 + MEM_READ_LONG( R_EAX, R_EAX );
1.1509 store_spreg( R_EAX, R_PR );
1.1510 sh4_x86.tstate = TSTATE_NONE;
1.1511 :}
1.1512 @@ -2410,8 +2440,10 @@
1.1513 MOV_r32_r32( R_EAX, R_ECX );
1.1514 AND_imm32_r32( 0xFC000000, R_EAX );
1.1515 CMP_imm32_r32( 0xE0000000, R_EAX );
1.1516 - JNE_rel8(CALL_FUNC1_SIZE, end);
1.1517 + JNE_rel8(8+CALL_FUNC1_SIZE, end);
1.1518 call_func1( sh4_flush_store_queue, R_ECX );
1.1519 + TEST_r32_r32( R_EAX, R_EAX );
1.1520 + JE_exc(-1);
1.1521 JMP_TARGET(end);
1.1522 sh4_x86.tstate = TSTATE_NONE;
1.1523 :}
1.1524 @@ -2469,90 +2501,92 @@
1.1525 sh4_x86.tstate = TSTATE_NONE;
1.1526 :}
1.1527 STC.L SR, @-Rn {:
1.1528 - precheck();
1.1529 - check_priv_no_precheck();
1.1530 + check_priv();
1.1531 + load_reg( R_EAX, Rn );
1.1532 + check_walign32( R_EAX );
1.1533 + ADD_imm8s_r32( -4, R_EAX );
1.1534 + MMU_TRANSLATE_WRITE( R_EAX );
1.1535 + PUSH_realigned_r32( R_EAX );
1.1536 call_func0( sh4_read_sr );
1.1537 - load_reg( R_ECX, Rn );
1.1538 - check_walign32( R_ECX );
1.1539 - ADD_imm8s_r32( -4, R_ECX );
1.1540 - store_reg( R_ECX, Rn );
1.1541 + POP_realigned_r32( R_ECX );
1.1542 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1543 MEM_WRITE_LONG( R_ECX, R_EAX );
1.1544 sh4_x86.tstate = TSTATE_NONE;
1.1545 :}
1.1546 STC.L VBR, @-Rn {:
1.1547 - precheck();
1.1548 - check_priv_no_precheck();
1.1549 - load_reg( R_ECX, Rn );
1.1550 - check_walign32( R_ECX );
1.1551 - ADD_imm8s_r32( -4, R_ECX );
1.1552 - store_reg( R_ECX, Rn );
1.1553 - load_spreg( R_EAX, R_VBR );
1.1554 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1555 + check_priv();
1.1556 + load_reg( R_EAX, Rn );
1.1557 + check_walign32( R_EAX );
1.1558 + ADD_imm8s_r32( -4, R_EAX );
1.1559 + MMU_TRANSLATE_WRITE( R_EAX );
1.1560 + load_spreg( R_EDX, R_VBR );
1.1561 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1562 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1563 sh4_x86.tstate = TSTATE_NONE;
1.1564 :}
1.1565 STC.L SSR, @-Rn {:
1.1566 - precheck();
1.1567 - check_priv_no_precheck();
1.1568 - load_reg( R_ECX, Rn );
1.1569 - check_walign32( R_ECX );
1.1570 - ADD_imm8s_r32( -4, R_ECX );
1.1571 - store_reg( R_ECX, Rn );
1.1572 - load_spreg( R_EAX, R_SSR );
1.1573 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1574 + check_priv();
1.1575 + load_reg( R_EAX, Rn );
1.1576 + check_walign32( R_EAX );
1.1577 + ADD_imm8s_r32( -4, R_EAX );
1.1578 + MMU_TRANSLATE_WRITE( R_EAX );
1.1579 + load_spreg( R_EDX, R_SSR );
1.1580 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1581 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1582 sh4_x86.tstate = TSTATE_NONE;
1.1583 :}
1.1584 STC.L SPC, @-Rn {:
1.1585 - precheck();
1.1586 - check_priv_no_precheck();
1.1587 - load_reg( R_ECX, Rn );
1.1588 - check_walign32( R_ECX );
1.1589 - ADD_imm8s_r32( -4, R_ECX );
1.1590 - store_reg( R_ECX, Rn );
1.1591 - load_spreg( R_EAX, R_SPC );
1.1592 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1593 + check_priv();
1.1594 + load_reg( R_EAX, Rn );
1.1595 + check_walign32( R_EAX );
1.1596 + ADD_imm8s_r32( -4, R_EAX );
1.1597 + MMU_TRANSLATE_WRITE( R_EAX );
1.1598 + load_spreg( R_EDX, R_SPC );
1.1599 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1600 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1601 sh4_x86.tstate = TSTATE_NONE;
1.1602 :}
1.1603 STC.L SGR, @-Rn {:
1.1604 - precheck();
1.1605 - check_priv_no_precheck();
1.1606 - load_reg( R_ECX, Rn );
1.1607 - check_walign32( R_ECX );
1.1608 - ADD_imm8s_r32( -4, R_ECX );
1.1609 - store_reg( R_ECX, Rn );
1.1610 - load_spreg( R_EAX, R_SGR );
1.1611 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1612 + check_priv();
1.1613 + load_reg( R_EAX, Rn );
1.1614 + check_walign32( R_EAX );
1.1615 + ADD_imm8s_r32( -4, R_EAX );
1.1616 + MMU_TRANSLATE_WRITE( R_EAX );
1.1617 + load_spreg( R_EDX, R_SGR );
1.1618 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1619 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1620 sh4_x86.tstate = TSTATE_NONE;
1.1621 :}
1.1622 STC.L DBR, @-Rn {:
1.1623 - precheck();
1.1624 - check_priv_no_precheck();
1.1625 - load_reg( R_ECX, Rn );
1.1626 - check_walign32( R_ECX );
1.1627 - ADD_imm8s_r32( -4, R_ECX );
1.1628 - store_reg( R_ECX, Rn );
1.1629 - load_spreg( R_EAX, R_DBR );
1.1630 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1631 + check_priv();
1.1632 + load_reg( R_EAX, Rn );
1.1633 + check_walign32( R_EAX );
1.1634 + ADD_imm8s_r32( -4, R_EAX );
1.1635 + MMU_TRANSLATE_WRITE( R_EAX );
1.1636 + load_spreg( R_EDX, R_DBR );
1.1637 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1638 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1639 sh4_x86.tstate = TSTATE_NONE;
1.1640 :}
1.1641 STC.L Rm_BANK, @-Rn {:
1.1642 - precheck();
1.1643 - check_priv_no_precheck();
1.1644 - load_reg( R_ECX, Rn );
1.1645 - check_walign32( R_ECX );
1.1646 - ADD_imm8s_r32( -4, R_ECX );
1.1647 - store_reg( R_ECX, Rn );
1.1648 - load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1.1649 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1650 + check_priv();
1.1651 + load_reg( R_EAX, Rn );
1.1652 + check_walign32( R_EAX );
1.1653 + ADD_imm8s_r32( -4, R_EAX );
1.1654 + MMU_TRANSLATE_WRITE( R_EAX );
1.1655 + load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1.1656 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1657 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1658 sh4_x86.tstate = TSTATE_NONE;
1.1659 :}
1.1660 STC.L GBR, @-Rn {:
1.1661 - load_reg( R_ECX, Rn );
1.1662 - precheck();
1.1663 - check_walign32( R_ECX );
1.1664 - ADD_imm8s_r32( -4, R_ECX );
1.1665 - store_reg( R_ECX, Rn );
1.1666 - load_spreg( R_EAX, R_GBR );
1.1667 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1668 + load_reg( R_EAX, Rn );
1.1669 + check_walign32( R_EAX );
1.1670 + ADD_imm8s_r32( -4, R_EAX );
1.1671 + MMU_TRANSLATE_WRITE( R_EAX );
1.1672 + load_spreg( R_EDX, R_GBR );
1.1673 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1674 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1675 sh4_x86.tstate = TSTATE_NONE;
1.1676 :}
1.1677 STS FPSCR, Rn {:
1.1678 @@ -2560,13 +2594,13 @@
1.1679 store_reg( R_EAX, Rn );
1.1680 :}
1.1681 STS.L FPSCR, @-Rn {:
1.1682 - load_reg( R_ECX, Rn );
1.1683 - precheck();
1.1684 - check_walign32( R_ECX );
1.1685 - ADD_imm8s_r32( -4, R_ECX );
1.1686 - store_reg( R_ECX, Rn );
1.1687 - load_spreg( R_EAX, R_FPSCR );
1.1688 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1689 + load_reg( R_EAX, Rn );
1.1690 + check_walign32( R_EAX );
1.1691 + ADD_imm8s_r32( -4, R_EAX );
1.1692 + MMU_TRANSLATE_WRITE( R_EAX );
1.1693 + load_spreg( R_EDX, R_FPSCR );
1.1694 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1695 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1696 sh4_x86.tstate = TSTATE_NONE;
1.1697 :}
1.1698 STS FPUL, Rn {:
1.1699 @@ -2574,13 +2608,13 @@
1.1700 store_reg( R_EAX, Rn );
1.1701 :}
1.1702 STS.L FPUL, @-Rn {:
1.1703 - load_reg( R_ECX, Rn );
1.1704 - precheck();
1.1705 - check_walign32( R_ECX );
1.1706 - ADD_imm8s_r32( -4, R_ECX );
1.1707 - store_reg( R_ECX, Rn );
1.1708 - load_spreg( R_EAX, R_FPUL );
1.1709 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1710 + load_reg( R_EAX, Rn );
1.1711 + check_walign32( R_EAX );
1.1712 + ADD_imm8s_r32( -4, R_EAX );
1.1713 + MMU_TRANSLATE_WRITE( R_EAX );
1.1714 + load_spreg( R_EDX, R_FPUL );
1.1715 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1716 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1717 sh4_x86.tstate = TSTATE_NONE;
1.1718 :}
1.1719 STS MACH, Rn {:
1.1720 @@ -2588,13 +2622,13 @@
1.1721 store_reg( R_EAX, Rn );
1.1722 :}
1.1723 STS.L MACH, @-Rn {:
1.1724 - load_reg( R_ECX, Rn );
1.1725 - precheck();
1.1726 - check_walign32( R_ECX );
1.1727 - ADD_imm8s_r32( -4, R_ECX );
1.1728 - store_reg( R_ECX, Rn );
1.1729 - load_spreg( R_EAX, R_MACH );
1.1730 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1731 + load_reg( R_EAX, Rn );
1.1732 + check_walign32( R_EAX );
1.1733 + ADD_imm8s_r32( -4, R_EAX );
1.1734 + MMU_TRANSLATE_WRITE( R_EAX );
1.1735 + load_spreg( R_EDX, R_MACH );
1.1736 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1737 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1738 sh4_x86.tstate = TSTATE_NONE;
1.1739 :}
1.1740 STS MACL, Rn {:
1.1741 @@ -2602,13 +2636,13 @@
1.1742 store_reg( R_EAX, Rn );
1.1743 :}
1.1744 STS.L MACL, @-Rn {:
1.1745 - load_reg( R_ECX, Rn );
1.1746 - precheck();
1.1747 - check_walign32( R_ECX );
1.1748 - ADD_imm8s_r32( -4, R_ECX );
1.1749 - store_reg( R_ECX, Rn );
1.1750 - load_spreg( R_EAX, R_MACL );
1.1751 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1752 + load_reg( R_EAX, Rn );
1.1753 + check_walign32( R_EAX );
1.1754 + ADD_imm8s_r32( -4, R_EAX );
1.1755 + MMU_TRANSLATE_WRITE( R_EAX );
1.1756 + load_spreg( R_EDX, R_MACL );
1.1757 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1758 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1759 sh4_x86.tstate = TSTATE_NONE;
1.1760 :}
1.1761 STS PR, Rn {:
1.1762 @@ -2616,13 +2650,13 @@
1.1763 store_reg( R_EAX, Rn );
1.1764 :}
1.1765 STS.L PR, @-Rn {:
1.1766 - load_reg( R_ECX, Rn );
1.1767 - precheck();
1.1768 - check_walign32( R_ECX );
1.1769 - ADD_imm8s_r32( -4, R_ECX );
1.1770 - store_reg( R_ECX, Rn );
1.1771 - load_spreg( R_EAX, R_PR );
1.1772 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1773 + load_reg( R_EAX, Rn );
1.1774 + check_walign32( R_EAX );
1.1775 + ADD_imm8s_r32( -4, R_EAX );
1.1776 + MMU_TRANSLATE_WRITE( R_EAX );
1.1777 + load_spreg( R_EDX, R_PR );
1.1778 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.1779 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1780 sh4_x86.tstate = TSTATE_NONE;
1.1781 :}
1.1782
.