Search
lxdream.org :: lxdream/src/sh4/sh4x86.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.c
changeset 571:9bc09948d0f2
prev570:d2893980fbf5
next577:a181aeacd6e8
author nkeynes
date Thu Jan 10 08:28:37 2008 +0000 (14 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change More MMU work in progess. Much better now...
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.c Sun Jan 06 12:24:18 2008 +0000
1.2 +++ b/src/sh4/sh4x86.c Thu Jan 10 08:28:37 2008 +0000
1.3 @@ -40,6 +40,8 @@
1.4 uint32_t exc_code;
1.5 };
1.6
1.7 +#define MAX_RECOVERY_SIZE 2048
1.8 +
1.9 /**
1.10 * Struct to manage internal translation state. This state is not saved -
1.11 * it is only valid between calls to sh4_translate_begin_block() and
1.12 @@ -61,6 +63,8 @@
1.13 struct backpatch_record *backpatch_list;
1.14 uint32_t backpatch_posn;
1.15 uint32_t backpatch_size;
1.16 + struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];
1.17 + uint32_t recovery_posn;
1.18 };
1.19
1.20 #define TSTATE_NONE -1
1.21 @@ -115,6 +119,13 @@
1.22 sh4_x86.backpatch_posn++;
1.23 }
1.24
1.25 +void sh4_x86_add_recovery( uint32_t pc )
1.26 +{
1.27 + xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;
1.28 + xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
1.29 + xlat_recovery_posn++;
1.30 +}
1.31 +
1.32 /**
1.33 * Emit an instruction to load an SH4 reg into a real register
1.34 */
1.35 @@ -309,34 +320,27 @@
1.36
1.37 #define UNDEF()
1.38 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
1.39 -#define MEM_READ_BYTE_PHYS( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
1.40 -#define MEM_READ_WORD_PHYS( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
1.41 -#define MEM_READ_LONG_PHYS( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
1.42 -#define MEM_WRITE_BYTE_PHYS( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
1.43 -#define MEM_WRITE_WORD_PHYS( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
1.44 -#define MEM_WRITE_LONG_PHYS( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
1.45 +#define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
1.46 +#define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
1.47 +#define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
1.48 +#define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
1.49 +#define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
1.50 +#define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
1.51
1.52 -#define MEM_READ_BYTE_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func1(sh4_read_byte, R_EAX); MEM_RESULT(value_reg)
1.53 -#define MEM_READ_WORD_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func1(sh4_read_word, R_EAX); MEM_RESULT(value_reg)
1.54 -#define MEM_READ_LONG_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func1(sh4_read_long, R_EAX); MEM_RESULT(value_reg)
1.55 -#define MEM_WRITE_BYTE_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func2(sh4_write_byte, R_EAX, value_reg)
1.56 -#define MEM_WRITE_WORD_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func2(sh4_write_word, R_EAX, value_reg)
1.57 -#define MEM_WRITE_LONG_VMA( addr_reg, value_reg ) call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); call_func2(sh4_write_long, R_EAX, value_reg)
1.58 +/**
1.59 + * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
1.60 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
1.61 + */
1.62 +#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.63 +/**
1.64 + * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
1.65 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
1.66 + */
1.67 +#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.68
1.69 -#define MEM_READ_BYTE( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_READ_BYTE_VMA(addr_reg,value_reg);}else{MEM_READ_BYTE_PHYS(addr_reg, value_reg);}
1.70 -#define MEM_READ_WORD( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_READ_WORD_VMA(addr_reg,value_reg);}else{MEM_READ_WORD_PHYS(addr_reg, value_reg);}
1.71 -#define MEM_READ_LONG( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_READ_LONG_VMA(addr_reg,value_reg);}else{MEM_READ_LONG_PHYS(addr_reg, value_reg);}
1.72 -#define MEM_WRITE_BYTE( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_WRITE_BYTE_VMA(addr_reg,value_reg);}else{MEM_WRITE_BYTE_PHYS(addr_reg, value_reg);}
1.73 -#define MEM_WRITE_WORD( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_WRITE_WORD_VMA(addr_reg,value_reg);}else{MEM_WRITE_WORD_PHYS(addr_reg, value_reg);}
1.74 -#define MEM_WRITE_LONG( addr_reg, value_reg ) if(sh4_x86.tlb_on){MEM_WRITE_LONG_VMA(addr_reg,value_reg);}else{MEM_WRITE_LONG_PHYS(addr_reg, value_reg);}
1.75 -
1.76 -#define MEM_READ_SIZE_PHYS (CALL_FUNC1_SIZE)
1.77 -#define MEM_WRITE_SIZE_PHYS (CALL_FUNC2_SIZE)
1.78 -#define MEM_READ_SIZE_VMA (CALL_FUNC1_SIZE + CALL_FUNC1_SIZE + 12)
1.79 -#define MEM_WRITE_SIZE_VMA (CALL_FUNC1_SIZE + CALL_FUNC2_SIZE + 12)
1.80 -
1.81 -#define MEM_READ_SIZE (sh4_x86.tlb_on?MEM_READ_SIZE_VMA:MEM_READ_SIZE_PHYS)
1.82 -#define MEM_WRITE_SIZE (sh4_x86.tlb_on?MEM_WRITE_SIZE_VMA:MEM_WRITE_SIZE_PHYS)
1.83 +#define MEM_READ_SIZE (CALL_FUNC1_SIZE)
1.84 +#define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
1.85 +#define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
1.86
1.87 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.88
1.89 @@ -369,6 +373,9 @@
1.90 } else {
1.91 ir = sh4_read_word(pc);
1.92 }
1.93 + if( !sh4_x86.in_delay_slot ) {
1.94 + sh4_x86_add_recovery(pc);
1.95 + }
1.96 switch( (ir&0xF000) >> 12 ) {
1.97 case 0x0:
1.98 switch( ir&0xF ) {
1.99 @@ -505,10 +512,11 @@
1.100 case 0xC:
1.101 { /* MOVCA.L R0, @Rn */
1.102 uint32_t Rn = ((ir>>8)&0xF);
1.103 - load_reg( R_EAX, 0 );
1.104 - load_reg( R_ECX, Rn );
1.105 - check_walign32( R_ECX );
1.106 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.107 + load_reg( R_EAX, Rn );
1.108 + check_walign32( R_EAX );
1.109 + MMU_TRANSLATE_WRITE( R_EAX );
1.110 + load_reg( R_EDX, 0 );
1.111 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.112 sh4_x86.tstate = TSTATE_NONE;
1.113 }
1.114 break;
1.115 @@ -522,9 +530,10 @@
1.116 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.117 load_reg( R_EAX, 0 );
1.118 load_reg( R_ECX, Rn );
1.119 - ADD_r32_r32( R_EAX, R_ECX );
1.120 - load_reg( R_EAX, Rm );
1.121 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.122 + ADD_r32_r32( R_ECX, R_EAX );
1.123 + MMU_TRANSLATE_WRITE( R_EAX );
1.124 + load_reg( R_EDX, Rm );
1.125 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.126 sh4_x86.tstate = TSTATE_NONE;
1.127 }
1.128 break;
1.129 @@ -533,10 +542,11 @@
1.130 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.131 load_reg( R_EAX, 0 );
1.132 load_reg( R_ECX, Rn );
1.133 - ADD_r32_r32( R_EAX, R_ECX );
1.134 - check_walign16( R_ECX );
1.135 - load_reg( R_EAX, Rm );
1.136 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.137 + ADD_r32_r32( R_ECX, R_EAX );
1.138 + check_walign16( R_EAX );
1.139 + MMU_TRANSLATE_WRITE( R_EAX );
1.140 + load_reg( R_EDX, Rm );
1.141 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.142 sh4_x86.tstate = TSTATE_NONE;
1.143 }
1.144 break;
1.145 @@ -545,10 +555,11 @@
1.146 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.147 load_reg( R_EAX, 0 );
1.148 load_reg( R_ECX, Rn );
1.149 - ADD_r32_r32( R_EAX, R_ECX );
1.150 - check_walign32( R_ECX );
1.151 - load_reg( R_EAX, Rm );
1.152 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.153 + ADD_r32_r32( R_ECX, R_EAX );
1.154 + check_walign32( R_EAX );
1.155 + MMU_TRANSLATE_WRITE( R_EAX );
1.156 + load_reg( R_EDX, Rm );
1.157 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.158 sh4_x86.tstate = TSTATE_NONE;
1.159 }
1.160 break;
1.161 @@ -755,8 +766,9 @@
1.162 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.163 load_reg( R_EAX, 0 );
1.164 load_reg( R_ECX, Rm );
1.165 - ADD_r32_r32( R_EAX, R_ECX );
1.166 - MEM_READ_BYTE( R_ECX, R_EAX );
1.167 + ADD_r32_r32( R_ECX, R_EAX );
1.168 + MMU_TRANSLATE_READ( R_EAX )
1.169 + MEM_READ_BYTE( R_EAX, R_EAX );
1.170 store_reg( R_EAX, Rn );
1.171 sh4_x86.tstate = TSTATE_NONE;
1.172 }
1.173 @@ -766,9 +778,10 @@
1.174 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.175 load_reg( R_EAX, 0 );
1.176 load_reg( R_ECX, Rm );
1.177 - ADD_r32_r32( R_EAX, R_ECX );
1.178 - check_ralign16( R_ECX );
1.179 - MEM_READ_WORD( R_ECX, R_EAX );
1.180 + ADD_r32_r32( R_ECX, R_EAX );
1.181 + check_ralign16( R_EAX );
1.182 + MMU_TRANSLATE_READ( R_EAX );
1.183 + MEM_READ_WORD( R_EAX, R_EAX );
1.184 store_reg( R_EAX, Rn );
1.185 sh4_x86.tstate = TSTATE_NONE;
1.186 }
1.187 @@ -778,9 +791,10 @@
1.188 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.189 load_reg( R_EAX, 0 );
1.190 load_reg( R_ECX, Rm );
1.191 - ADD_r32_r32( R_EAX, R_ECX );
1.192 - check_ralign32( R_ECX );
1.193 - MEM_READ_LONG( R_ECX, R_EAX );
1.194 + ADD_r32_r32( R_ECX, R_EAX );
1.195 + check_ralign32( R_EAX );
1.196 + MMU_TRANSLATE_READ( R_EAX );
1.197 + MEM_READ_LONG( R_EAX, R_EAX );
1.198 store_reg( R_EAX, Rn );
1.199 sh4_x86.tstate = TSTATE_NONE;
1.200 }
1.201 @@ -788,17 +802,34 @@
1.202 case 0xF:
1.203 { /* MAC.L @Rm+, @Rn+ */
1.204 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.205 - load_reg( R_ECX, Rm );
1.206 - check_ralign32( R_ECX );
1.207 - load_reg( R_ECX, Rn );
1.208 - check_ralign32( R_ECX );
1.209 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.210 - MEM_READ_LONG( R_ECX, R_EAX );
1.211 - PUSH_realigned_r32( R_EAX );
1.212 - load_reg( R_ECX, Rm );
1.213 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.214 + if( Rm == Rn ) {
1.215 + load_reg( R_EAX, Rm );
1.216 + check_ralign32( R_EAX );
1.217 + MMU_TRANSLATE_READ( R_EAX );
1.218 + PUSH_realigned_r32( R_EAX );
1.219 + load_reg( R_EAX, Rn );
1.220 + ADD_imm8s_r32( 4, R_EAX );
1.221 + MMU_TRANSLATE_READ( R_EAX );
1.222 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
1.223 + // Note translate twice in case of page boundaries. Maybe worth
1.224 + // adding a page-boundary check to skip the second translation
1.225 + } else {
1.226 + load_reg( R_EAX, Rm );
1.227 + check_ralign32( R_EAX );
1.228 + MMU_TRANSLATE_READ( R_EAX );
1.229 + PUSH_realigned_r32( R_EAX );
1.230 + load_reg( R_EAX, Rn );
1.231 + check_ralign32( R_EAX );
1.232 + MMU_TRANSLATE_READ( R_EAX );
1.233 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.234 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.235 + }
1.236 + MEM_READ_LONG( R_EAX, R_EAX );
1.237 + POP_r32( R_ECX );
1.238 + PUSH_r32( R_EAX );
1.239 MEM_READ_LONG( R_ECX, R_EAX );
1.240 POP_realigned_r32( R_ECX );
1.241 +
1.242 IMUL_r32( R_ECX );
1.243 ADD_r32_sh4r( R_EAX, R_MACL );
1.244 ADC_r32_sh4r( R_EDX, R_MACH );
1.245 @@ -819,11 +850,12 @@
1.246 case 0x1:
1.247 { /* MOV.L Rm, @(disp, Rn) */
1.248 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1.249 - load_reg( R_ECX, Rn );
1.250 - load_reg( R_EAX, Rm );
1.251 - ADD_imm32_r32( disp, R_ECX );
1.252 - check_walign32( R_ECX );
1.253 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.254 + load_reg( R_EAX, Rn );
1.255 + ADD_imm32_r32( disp, R_EAX );
1.256 + check_walign32( R_EAX );
1.257 + MMU_TRANSLATE_WRITE( R_EAX );
1.258 + load_reg( R_EDX, Rm );
1.259 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.260 sh4_x86.tstate = TSTATE_NONE;
1.261 }
1.262 break;
1.263 @@ -832,64 +864,70 @@
1.264 case 0x0:
1.265 { /* MOV.B Rm, @Rn */
1.266 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.267 - load_reg( R_EAX, Rm );
1.268 - load_reg( R_ECX, Rn );
1.269 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.270 + load_reg( R_EAX, Rn );
1.271 + MMU_TRANSLATE_WRITE( R_EAX );
1.272 + load_reg( R_EDX, Rm );
1.273 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.274 sh4_x86.tstate = TSTATE_NONE;
1.275 }
1.276 break;
1.277 case 0x1:
1.278 { /* MOV.W Rm, @Rn */
1.279 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.280 - load_reg( R_ECX, Rn );
1.281 - check_walign16( R_ECX );
1.282 - load_reg( R_EAX, Rm );
1.283 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.284 + load_reg( R_EAX, Rn );
1.285 + check_walign16( R_EAX );
1.286 + MMU_TRANSLATE_WRITE( R_EAX )
1.287 + load_reg( R_EDX, Rm );
1.288 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.289 sh4_x86.tstate = TSTATE_NONE;
1.290 }
1.291 break;
1.292 case 0x2:
1.293 { /* MOV.L Rm, @Rn */
1.294 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.295 - load_reg( R_EAX, Rm );
1.296 - load_reg( R_ECX, Rn );
1.297 - check_walign32(R_ECX);
1.298 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.299 + load_reg( R_EAX, Rn );
1.300 + check_walign32(R_EAX);
1.301 + MMU_TRANSLATE_WRITE( R_EAX );
1.302 + load_reg( R_EDX, Rm );
1.303 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.304 sh4_x86.tstate = TSTATE_NONE;
1.305 }
1.306 break;
1.307 case 0x4:
1.308 { /* MOV.B Rm, @-Rn */
1.309 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.310 - load_reg( R_EAX, Rm );
1.311 - load_reg( R_ECX, Rn );
1.312 - ADD_imm8s_r32( -1, R_ECX );
1.313 - store_reg( R_ECX, Rn );
1.314 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.315 + load_reg( R_EAX, Rn );
1.316 + ADD_imm8s_r32( -1, R_EAX );
1.317 + MMU_TRANSLATE_WRITE( R_EAX );
1.318 + load_reg( R_EDX, Rm );
1.319 + ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
1.320 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.321 sh4_x86.tstate = TSTATE_NONE;
1.322 }
1.323 break;
1.324 case 0x5:
1.325 { /* MOV.W Rm, @-Rn */
1.326 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.327 - load_reg( R_ECX, Rn );
1.328 - check_walign16( R_ECX );
1.329 - load_reg( R_EAX, Rm );
1.330 - ADD_imm8s_r32( -2, R_ECX );
1.331 - store_reg( R_ECX, Rn );
1.332 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.333 + load_reg( R_EAX, Rn );
1.334 + ADD_imm8s_r32( -2, R_EAX );
1.335 + check_walign16( R_EAX );
1.336 + MMU_TRANSLATE_WRITE( R_EAX );
1.337 + load_reg( R_EDX, Rm );
1.338 + ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1.339 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.340 sh4_x86.tstate = TSTATE_NONE;
1.341 }
1.342 break;
1.343 case 0x6:
1.344 { /* MOV.L Rm, @-Rn */
1.345 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.346 - load_reg( R_EAX, Rm );
1.347 - load_reg( R_ECX, Rn );
1.348 - check_walign32( R_ECX );
1.349 - ADD_imm8s_r32( -4, R_ECX );
1.350 - store_reg( R_ECX, Rn );
1.351 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.352 + load_reg( R_EAX, Rn );
1.353 + ADD_imm8s_r32( -4, R_EAX );
1.354 + check_walign32( R_EAX );
1.355 + MMU_TRANSLATE_WRITE( R_EAX );
1.356 + load_reg( R_EDX, Rm );
1.357 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.358 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.359 sh4_x86.tstate = TSTATE_NONE;
1.360 }
1.361 break;
1.362 @@ -1262,36 +1300,39 @@
1.363 case 0x0:
1.364 { /* STS.L MACH, @-Rn */
1.365 uint32_t Rn = ((ir>>8)&0xF);
1.366 - load_reg( R_ECX, Rn );
1.367 - check_walign32( R_ECX );
1.368 - ADD_imm8s_r32( -4, R_ECX );
1.369 - store_reg( R_ECX, Rn );
1.370 - load_spreg( R_EAX, R_MACH );
1.371 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.372 + load_reg( R_EAX, Rn );
1.373 + check_walign32( R_EAX );
1.374 + ADD_imm8s_r32( -4, R_EAX );
1.375 + MMU_TRANSLATE_WRITE( R_EAX );
1.376 + load_spreg( R_EDX, R_MACH );
1.377 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.378 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.379 sh4_x86.tstate = TSTATE_NONE;
1.380 }
1.381 break;
1.382 case 0x1:
1.383 { /* STS.L MACL, @-Rn */
1.384 uint32_t Rn = ((ir>>8)&0xF);
1.385 - load_reg( R_ECX, Rn );
1.386 - check_walign32( R_ECX );
1.387 - ADD_imm8s_r32( -4, R_ECX );
1.388 - store_reg( R_ECX, Rn );
1.389 - load_spreg( R_EAX, R_MACL );
1.390 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.391 + load_reg( R_EAX, Rn );
1.392 + check_walign32( R_EAX );
1.393 + ADD_imm8s_r32( -4, R_EAX );
1.394 + MMU_TRANSLATE_WRITE( R_EAX );
1.395 + load_spreg( R_EDX, R_MACL );
1.396 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.397 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.398 sh4_x86.tstate = TSTATE_NONE;
1.399 }
1.400 break;
1.401 case 0x2:
1.402 { /* STS.L PR, @-Rn */
1.403 uint32_t Rn = ((ir>>8)&0xF);
1.404 - load_reg( R_ECX, Rn );
1.405 - check_walign32( R_ECX );
1.406 - ADD_imm8s_r32( -4, R_ECX );
1.407 - store_reg( R_ECX, Rn );
1.408 - load_spreg( R_EAX, R_PR );
1.409 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.410 + load_reg( R_EAX, Rn );
1.411 + check_walign32( R_EAX );
1.412 + ADD_imm8s_r32( -4, R_EAX );
1.413 + MMU_TRANSLATE_WRITE( R_EAX );
1.414 + load_spreg( R_EDX, R_PR );
1.415 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.416 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.417 sh4_x86.tstate = TSTATE_NONE;
1.418 }
1.419 break;
1.420 @@ -1299,36 +1340,39 @@
1.421 { /* STC.L SGR, @-Rn */
1.422 uint32_t Rn = ((ir>>8)&0xF);
1.423 check_priv();
1.424 - load_reg( R_ECX, Rn );
1.425 - check_walign32( R_ECX );
1.426 - ADD_imm8s_r32( -4, R_ECX );
1.427 - store_reg( R_ECX, Rn );
1.428 - load_spreg( R_EAX, R_SGR );
1.429 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.430 + load_reg( R_EAX, Rn );
1.431 + check_walign32( R_EAX );
1.432 + ADD_imm8s_r32( -4, R_EAX );
1.433 + MMU_TRANSLATE_WRITE( R_EAX );
1.434 + load_spreg( R_EDX, R_SGR );
1.435 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.436 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.437 sh4_x86.tstate = TSTATE_NONE;
1.438 }
1.439 break;
1.440 case 0x5:
1.441 { /* STS.L FPUL, @-Rn */
1.442 uint32_t Rn = ((ir>>8)&0xF);
1.443 - load_reg( R_ECX, Rn );
1.444 - check_walign32( R_ECX );
1.445 - ADD_imm8s_r32( -4, R_ECX );
1.446 - store_reg( R_ECX, Rn );
1.447 - load_spreg( R_EAX, R_FPUL );
1.448 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.449 + load_reg( R_EAX, Rn );
1.450 + check_walign32( R_EAX );
1.451 + ADD_imm8s_r32( -4, R_EAX );
1.452 + MMU_TRANSLATE_WRITE( R_EAX );
1.453 + load_spreg( R_EDX, R_FPUL );
1.454 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.455 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.456 sh4_x86.tstate = TSTATE_NONE;
1.457 }
1.458 break;
1.459 case 0x6:
1.460 { /* STS.L FPSCR, @-Rn */
1.461 uint32_t Rn = ((ir>>8)&0xF);
1.462 - load_reg( R_ECX, Rn );
1.463 - check_walign32( R_ECX );
1.464 - ADD_imm8s_r32( -4, R_ECX );
1.465 - store_reg( R_ECX, Rn );
1.466 - load_spreg( R_EAX, R_FPSCR );
1.467 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.468 + load_reg( R_EAX, Rn );
1.469 + check_walign32( R_EAX );
1.470 + ADD_imm8s_r32( -4, R_EAX );
1.471 + MMU_TRANSLATE_WRITE( R_EAX );
1.472 + load_spreg( R_EDX, R_FPSCR );
1.473 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.474 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.475 sh4_x86.tstate = TSTATE_NONE;
1.476 }
1.477 break;
1.478 @@ -1336,12 +1380,13 @@
1.479 { /* STC.L DBR, @-Rn */
1.480 uint32_t Rn = ((ir>>8)&0xF);
1.481 check_priv();
1.482 - load_reg( R_ECX, Rn );
1.483 - check_walign32( R_ECX );
1.484 - ADD_imm8s_r32( -4, R_ECX );
1.485 - store_reg( R_ECX, Rn );
1.486 - load_spreg( R_EAX, R_DBR );
1.487 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.488 + load_reg( R_EAX, Rn );
1.489 + check_walign32( R_EAX );
1.490 + ADD_imm8s_r32( -4, R_EAX );
1.491 + MMU_TRANSLATE_WRITE( R_EAX );
1.492 + load_spreg( R_EDX, R_DBR );
1.493 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.494 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.495 sh4_x86.tstate = TSTATE_NONE;
1.496 }
1.497 break;
1.498 @@ -1358,11 +1403,14 @@
1.499 { /* STC.L SR, @-Rn */
1.500 uint32_t Rn = ((ir>>8)&0xF);
1.501 check_priv();
1.502 + load_reg( R_EAX, Rn );
1.503 + check_walign32( R_EAX );
1.504 + ADD_imm8s_r32( -4, R_EAX );
1.505 + MMU_TRANSLATE_WRITE( R_EAX );
1.506 + PUSH_realigned_r32( R_EAX );
1.507 call_func0( sh4_read_sr );
1.508 - load_reg( R_ECX, Rn );
1.509 - check_walign32( R_ECX );
1.510 - ADD_imm8s_r32( -4, R_ECX );
1.511 - store_reg( R_ECX, Rn );
1.512 + POP_realigned_r32( R_ECX );
1.513 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.514 MEM_WRITE_LONG( R_ECX, R_EAX );
1.515 sh4_x86.tstate = TSTATE_NONE;
1.516 }
1.517 @@ -1370,12 +1418,13 @@
1.518 case 0x1:
1.519 { /* STC.L GBR, @-Rn */
1.520 uint32_t Rn = ((ir>>8)&0xF);
1.521 - load_reg( R_ECX, Rn );
1.522 - check_walign32( R_ECX );
1.523 - ADD_imm8s_r32( -4, R_ECX );
1.524 - store_reg( R_ECX, Rn );
1.525 - load_spreg( R_EAX, R_GBR );
1.526 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.527 + load_reg( R_EAX, Rn );
1.528 + check_walign32( R_EAX );
1.529 + ADD_imm8s_r32( -4, R_EAX );
1.530 + MMU_TRANSLATE_WRITE( R_EAX );
1.531 + load_spreg( R_EDX, R_GBR );
1.532 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.533 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.534 sh4_x86.tstate = TSTATE_NONE;
1.535 }
1.536 break;
1.537 @@ -1383,12 +1432,13 @@
1.538 { /* STC.L VBR, @-Rn */
1.539 uint32_t Rn = ((ir>>8)&0xF);
1.540 check_priv();
1.541 - load_reg( R_ECX, Rn );
1.542 - check_walign32( R_ECX );
1.543 - ADD_imm8s_r32( -4, R_ECX );
1.544 - store_reg( R_ECX, Rn );
1.545 - load_spreg( R_EAX, R_VBR );
1.546 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.547 + load_reg( R_EAX, Rn );
1.548 + check_walign32( R_EAX );
1.549 + ADD_imm8s_r32( -4, R_EAX );
1.550 + MMU_TRANSLATE_WRITE( R_EAX );
1.551 + load_spreg( R_EDX, R_VBR );
1.552 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.553 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.554 sh4_x86.tstate = TSTATE_NONE;
1.555 }
1.556 break;
1.557 @@ -1396,12 +1446,13 @@
1.558 { /* STC.L SSR, @-Rn */
1.559 uint32_t Rn = ((ir>>8)&0xF);
1.560 check_priv();
1.561 - load_reg( R_ECX, Rn );
1.562 - check_walign32( R_ECX );
1.563 - ADD_imm8s_r32( -4, R_ECX );
1.564 - store_reg( R_ECX, Rn );
1.565 - load_spreg( R_EAX, R_SSR );
1.566 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.567 + load_reg( R_EAX, Rn );
1.568 + check_walign32( R_EAX );
1.569 + ADD_imm8s_r32( -4, R_EAX );
1.570 + MMU_TRANSLATE_WRITE( R_EAX );
1.571 + load_spreg( R_EDX, R_SSR );
1.572 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.573 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.574 sh4_x86.tstate = TSTATE_NONE;
1.575 }
1.576 break;
1.577 @@ -1409,12 +1460,13 @@
1.578 { /* STC.L SPC, @-Rn */
1.579 uint32_t Rn = ((ir>>8)&0xF);
1.580 check_priv();
1.581 - load_reg( R_ECX, Rn );
1.582 - check_walign32( R_ECX );
1.583 - ADD_imm8s_r32( -4, R_ECX );
1.584 - store_reg( R_ECX, Rn );
1.585 - load_spreg( R_EAX, R_SPC );
1.586 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.587 + load_reg( R_EAX, Rn );
1.588 + check_walign32( R_EAX );
1.589 + ADD_imm8s_r32( -4, R_EAX );
1.590 + MMU_TRANSLATE_WRITE( R_EAX );
1.591 + load_spreg( R_EDX, R_SPC );
1.592 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.593 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.594 sh4_x86.tstate = TSTATE_NONE;
1.595 }
1.596 break;
1.597 @@ -1427,12 +1479,13 @@
1.598 { /* STC.L Rm_BANK, @-Rn */
1.599 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.600 check_priv();
1.601 - load_reg( R_ECX, Rn );
1.602 - check_walign32( R_ECX );
1.603 - ADD_imm8s_r32( -4, R_ECX );
1.604 - store_reg( R_ECX, Rn );
1.605 - load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1.606 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.607 + load_reg( R_EAX, Rn );
1.608 + check_walign32( R_EAX );
1.609 + ADD_imm8s_r32( -4, R_EAX );
1.610 + MMU_TRANSLATE_WRITE( R_EAX );
1.611 + load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1.612 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1.613 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.614 sh4_x86.tstate = TSTATE_NONE;
1.615 }
1.616 break;
1.617 @@ -1514,10 +1567,9 @@
1.618 uint32_t Rm = ((ir>>8)&0xF);
1.619 load_reg( R_EAX, Rm );
1.620 check_ralign32( R_EAX );
1.621 - MOV_r32_r32( R_EAX, R_ECX );
1.622 - ADD_imm8s_r32( 4, R_EAX );
1.623 - store_reg( R_EAX, Rm );
1.624 - MEM_READ_LONG( R_ECX, R_EAX );
1.625 + MMU_TRANSLATE_READ( R_EAX );
1.626 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.627 + MEM_READ_LONG( R_EAX, R_EAX );
1.628 store_spreg( R_EAX, R_MACH );
1.629 sh4_x86.tstate = TSTATE_NONE;
1.630 }
1.631 @@ -1527,10 +1579,9 @@
1.632 uint32_t Rm = ((ir>>8)&0xF);
1.633 load_reg( R_EAX, Rm );
1.634 check_ralign32( R_EAX );
1.635 - MOV_r32_r32( R_EAX, R_ECX );
1.636 - ADD_imm8s_r32( 4, R_EAX );
1.637 - store_reg( R_EAX, Rm );
1.638 - MEM_READ_LONG( R_ECX, R_EAX );
1.639 + MMU_TRANSLATE_READ( R_EAX );
1.640 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.641 + MEM_READ_LONG( R_EAX, R_EAX );
1.642 store_spreg( R_EAX, R_MACL );
1.643 sh4_x86.tstate = TSTATE_NONE;
1.644 }
1.645 @@ -1540,10 +1591,9 @@
1.646 uint32_t Rm = ((ir>>8)&0xF);
1.647 load_reg( R_EAX, Rm );
1.648 check_ralign32( R_EAX );
1.649 - MOV_r32_r32( R_EAX, R_ECX );
1.650 - ADD_imm8s_r32( 4, R_EAX );
1.651 - store_reg( R_EAX, Rm );
1.652 - MEM_READ_LONG( R_ECX, R_EAX );
1.653 + MMU_TRANSLATE_READ( R_EAX );
1.654 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.655 + MEM_READ_LONG( R_EAX, R_EAX );
1.656 store_spreg( R_EAX, R_PR );
1.657 sh4_x86.tstate = TSTATE_NONE;
1.658 }
1.659 @@ -1554,10 +1604,9 @@
1.660 check_priv();
1.661 load_reg( R_EAX, Rm );
1.662 check_ralign32( R_EAX );
1.663 - MOV_r32_r32( R_EAX, R_ECX );
1.664 - ADD_imm8s_r32( 4, R_EAX );
1.665 - store_reg( R_EAX, Rm );
1.666 - MEM_READ_LONG( R_ECX, R_EAX );
1.667 + MMU_TRANSLATE_READ( R_EAX );
1.668 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.669 + MEM_READ_LONG( R_EAX, R_EAX );
1.670 store_spreg( R_EAX, R_SGR );
1.671 sh4_x86.tstate = TSTATE_NONE;
1.672 }
1.673 @@ -1567,10 +1616,9 @@
1.674 uint32_t Rm = ((ir>>8)&0xF);
1.675 load_reg( R_EAX, Rm );
1.676 check_ralign32( R_EAX );
1.677 - MOV_r32_r32( R_EAX, R_ECX );
1.678 - ADD_imm8s_r32( 4, R_EAX );
1.679 - store_reg( R_EAX, Rm );
1.680 - MEM_READ_LONG( R_ECX, R_EAX );
1.681 + MMU_TRANSLATE_READ( R_EAX );
1.682 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.683 + MEM_READ_LONG( R_EAX, R_EAX );
1.684 store_spreg( R_EAX, R_FPUL );
1.685 sh4_x86.tstate = TSTATE_NONE;
1.686 }
1.687 @@ -1580,10 +1628,9 @@
1.688 uint32_t Rm = ((ir>>8)&0xF);
1.689 load_reg( R_EAX, Rm );
1.690 check_ralign32( R_EAX );
1.691 - MOV_r32_r32( R_EAX, R_ECX );
1.692 - ADD_imm8s_r32( 4, R_EAX );
1.693 - store_reg( R_EAX, Rm );
1.694 - MEM_READ_LONG( R_ECX, R_EAX );
1.695 + MMU_TRANSLATE_READ( R_EAX );
1.696 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.697 + MEM_READ_LONG( R_EAX, R_EAX );
1.698 store_spreg( R_EAX, R_FPSCR );
1.699 update_fr_bank( R_EAX );
1.700 sh4_x86.tstate = TSTATE_NONE;
1.701 @@ -1595,10 +1642,9 @@
1.702 check_priv();
1.703 load_reg( R_EAX, Rm );
1.704 check_ralign32( R_EAX );
1.705 - MOV_r32_r32( R_EAX, R_ECX );
1.706 - ADD_imm8s_r32( 4, R_EAX );
1.707 - store_reg( R_EAX, Rm );
1.708 - MEM_READ_LONG( R_ECX, R_EAX );
1.709 + MMU_TRANSLATE_READ( R_EAX );
1.710 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.711 + MEM_READ_LONG( R_EAX, R_EAX );
1.712 store_spreg( R_EAX, R_DBR );
1.713 sh4_x86.tstate = TSTATE_NONE;
1.714 }
1.715 @@ -1621,10 +1667,9 @@
1.716 check_priv();
1.717 load_reg( R_EAX, Rm );
1.718 check_ralign32( R_EAX );
1.719 - MOV_r32_r32( R_EAX, R_ECX );
1.720 - ADD_imm8s_r32( 4, R_EAX );
1.721 - store_reg( R_EAX, Rm );
1.722 - MEM_READ_LONG( R_ECX, R_EAX );
1.723 + MMU_TRANSLATE_READ( R_EAX );
1.724 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.725 + MEM_READ_LONG( R_EAX, R_EAX );
1.726 call_func1( sh4_write_sr, R_EAX );
1.727 sh4_x86.priv_checked = FALSE;
1.728 sh4_x86.fpuen_checked = FALSE;
1.729 @@ -1637,10 +1682,9 @@
1.730 uint32_t Rm = ((ir>>8)&0xF);
1.731 load_reg( R_EAX, Rm );
1.732 check_ralign32( R_EAX );
1.733 - MOV_r32_r32( R_EAX, R_ECX );
1.734 - ADD_imm8s_r32( 4, R_EAX );
1.735 - store_reg( R_EAX, Rm );
1.736 - MEM_READ_LONG( R_ECX, R_EAX );
1.737 + MMU_TRANSLATE_READ( R_EAX );
1.738 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.739 + MEM_READ_LONG( R_EAX, R_EAX );
1.740 store_spreg( R_EAX, R_GBR );
1.741 sh4_x86.tstate = TSTATE_NONE;
1.742 }
1.743 @@ -1651,10 +1695,9 @@
1.744 check_priv();
1.745 load_reg( R_EAX, Rm );
1.746 check_ralign32( R_EAX );
1.747 - MOV_r32_r32( R_EAX, R_ECX );
1.748 - ADD_imm8s_r32( 4, R_EAX );
1.749 - store_reg( R_EAX, Rm );
1.750 - MEM_READ_LONG( R_ECX, R_EAX );
1.751 + MMU_TRANSLATE_READ( R_EAX );
1.752 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.753 + MEM_READ_LONG( R_EAX, R_EAX );
1.754 store_spreg( R_EAX, R_VBR );
1.755 sh4_x86.tstate = TSTATE_NONE;
1.756 }
1.757 @@ -1665,10 +1708,9 @@
1.758 check_priv();
1.759 load_reg( R_EAX, Rm );
1.760 check_ralign32( R_EAX );
1.761 - MOV_r32_r32( R_EAX, R_ECX );
1.762 - ADD_imm8s_r32( 4, R_EAX );
1.763 - store_reg( R_EAX, Rm );
1.764 - MEM_READ_LONG( R_ECX, R_EAX );
1.765 + MMU_TRANSLATE_READ( R_EAX );
1.766 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.767 + MEM_READ_LONG( R_EAX, R_EAX );
1.768 store_spreg( R_EAX, R_SSR );
1.769 sh4_x86.tstate = TSTATE_NONE;
1.770 }
1.771 @@ -1679,10 +1721,9 @@
1.772 check_priv();
1.773 load_reg( R_EAX, Rm );
1.774 check_ralign32( R_EAX );
1.775 - MOV_r32_r32( R_EAX, R_ECX );
1.776 - ADD_imm8s_r32( 4, R_EAX );
1.777 - store_reg( R_EAX, Rm );
1.778 - MEM_READ_LONG( R_ECX, R_EAX );
1.779 + MMU_TRANSLATE_READ( R_EAX );
1.780 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.781 + MEM_READ_LONG( R_EAX, R_EAX );
1.782 store_spreg( R_EAX, R_SPC );
1.783 sh4_x86.tstate = TSTATE_NONE;
1.784 }
1.785 @@ -1698,10 +1739,9 @@
1.786 check_priv();
1.787 load_reg( R_EAX, Rm );
1.788 check_ralign32( R_EAX );
1.789 - MOV_r32_r32( R_EAX, R_ECX );
1.790 - ADD_imm8s_r32( 4, R_EAX );
1.791 - store_reg( R_EAX, Rm );
1.792 - MEM_READ_LONG( R_ECX, R_EAX );
1.793 + MMU_TRANSLATE_READ( R_EAX );
1.794 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.795 + MEM_READ_LONG( R_EAX, R_EAX );
1.796 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.797 sh4_x86.tstate = TSTATE_NONE;
1.798 }
1.799 @@ -1861,12 +1901,14 @@
1.800 case 0x1:
1.801 { /* TAS.B @Rn */
1.802 uint32_t Rn = ((ir>>8)&0xF);
1.803 - load_reg( R_ECX, Rn );
1.804 - MEM_READ_BYTE( R_ECX, R_EAX );
1.805 + load_reg( R_EAX, Rn );
1.806 + MMU_TRANSLATE_WRITE( R_EAX );
1.807 + PUSH_realigned_r32( R_EAX );
1.808 + MEM_READ_BYTE( R_EAX, R_EAX );
1.809 TEST_r8_r8( R_AL, R_AL );
1.810 SETE_t();
1.811 OR_imm8_r8( 0x80, R_AL );
1.812 - load_reg( R_ECX, Rn );
1.813 + POP_realigned_r32( R_ECX );
1.814 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.815 sh4_x86.tstate = TSTATE_NONE;
1.816 }
1.817 @@ -2019,15 +2061,31 @@
1.818 case 0xF:
1.819 { /* MAC.W @Rm+, @Rn+ */
1.820 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.821 - load_reg( R_ECX, Rm );
1.822 - check_ralign16( R_ECX );
1.823 - load_reg( R_ECX, Rn );
1.824 - check_ralign16( R_ECX );
1.825 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
1.826 - MEM_READ_WORD( R_ECX, R_EAX );
1.827 - PUSH_realigned_r32( R_EAX );
1.828 - load_reg( R_ECX, Rm );
1.829 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.830 + if( Rm == Rn ) {
1.831 + load_reg( R_EAX, Rm );
1.832 + check_ralign16( R_EAX );
1.833 + MMU_TRANSLATE_READ( R_EAX );
1.834 + PUSH_realigned_r32( R_EAX );
1.835 + load_reg( R_EAX, Rn );
1.836 + ADD_imm8s_r32( 2, R_EAX );
1.837 + MMU_TRANSLATE_READ( R_EAX );
1.838 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.839 + // Note translate twice in case of page boundaries. Maybe worth
1.840 + // adding a page-boundary check to skip the second translation
1.841 + } else {
1.842 + load_reg( R_EAX, Rm );
1.843 + check_ralign16( R_EAX );
1.844 + MMU_TRANSLATE_READ( R_EAX );
1.845 + PUSH_realigned_r32( R_EAX );
1.846 + load_reg( R_EAX, Rn );
1.847 + check_ralign16( R_EAX );
1.848 + MMU_TRANSLATE_READ( R_EAX );
1.849 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
1.850 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.851 + }
1.852 + MEM_READ_WORD( R_EAX, R_EAX );
1.853 + POP_r32( R_ECX );
1.854 + PUSH_r32( R_EAX );
1.855 MEM_READ_WORD( R_ECX, R_EAX );
1.856 POP_realigned_r32( R_ECX );
1.857 IMUL_r32( R_ECX );
1.858 @@ -2064,10 +2122,11 @@
1.859 case 0x5:
1.860 { /* MOV.L @(disp, Rm), Rn */
1.861 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1.862 - load_reg( R_ECX, Rm );
1.863 - ADD_imm8s_r32( disp, R_ECX );
1.864 - check_ralign32( R_ECX );
1.865 - MEM_READ_LONG( R_ECX, R_EAX );
1.866 + load_reg( R_EAX, Rm );
1.867 + ADD_imm8s_r32( disp, R_EAX );
1.868 + check_ralign32( R_EAX );
1.869 + MMU_TRANSLATE_READ( R_EAX );
1.870 + MEM_READ_LONG( R_EAX, R_EAX );
1.871 store_reg( R_EAX, Rn );
1.872 sh4_x86.tstate = TSTATE_NONE;
1.873 }
1.874 @@ -2077,8 +2136,9 @@
1.875 case 0x0:
1.876 { /* MOV.B @Rm, Rn */
1.877 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.878 - load_reg( R_ECX, Rm );
1.879 - MEM_READ_BYTE( R_ECX, R_EAX );
1.880 + load_reg( R_EAX, Rm );
1.881 + MMU_TRANSLATE_READ( R_EAX );
1.882 + MEM_READ_BYTE( R_EAX, R_EAX );
1.883 store_reg( R_EAX, Rn );
1.884 sh4_x86.tstate = TSTATE_NONE;
1.885 }
1.886 @@ -2086,9 +2146,10 @@
1.887 case 0x1:
1.888 { /* MOV.W @Rm, Rn */
1.889 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.890 - load_reg( R_ECX, Rm );
1.891 - check_ralign16( R_ECX );
1.892 - MEM_READ_WORD( R_ECX, R_EAX );
1.893 + load_reg( R_EAX, Rm );
1.894 + check_ralign16( R_EAX );
1.895 + MMU_TRANSLATE_READ( R_EAX );
1.896 + MEM_READ_WORD( R_EAX, R_EAX );
1.897 store_reg( R_EAX, Rn );
1.898 sh4_x86.tstate = TSTATE_NONE;
1.899 }
1.900 @@ -2096,9 +2157,10 @@
1.901 case 0x2:
1.902 { /* MOV.L @Rm, Rn */
1.903 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.904 - load_reg( R_ECX, Rm );
1.905 - check_ralign32( R_ECX );
1.906 - MEM_READ_LONG( R_ECX, R_EAX );
1.907 + load_reg( R_EAX, Rm );
1.908 + check_ralign32( R_EAX );
1.909 + MMU_TRANSLATE_READ( R_EAX );
1.910 + MEM_READ_LONG( R_EAX, R_EAX );
1.911 store_reg( R_EAX, Rn );
1.912 sh4_x86.tstate = TSTATE_NONE;
1.913 }
1.914 @@ -2113,11 +2175,10 @@
1.915 case 0x4:
1.916 { /* MOV.B @Rm+, Rn */
1.917 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.918 - load_reg( R_ECX, Rm );
1.919 - MOV_r32_r32( R_ECX, R_EAX );
1.920 - ADD_imm8s_r32( 1, R_EAX );
1.921 - store_reg( R_EAX, Rm );
1.922 - MEM_READ_BYTE( R_ECX, R_EAX );
1.923 + load_reg( R_EAX, Rm );
1.924 + MMU_TRANSLATE_READ( R_EAX );
1.925 + ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
1.926 + MEM_READ_BYTE( R_EAX, R_EAX );
1.927 store_reg( R_EAX, Rn );
1.928 sh4_x86.tstate = TSTATE_NONE;
1.929 }
1.930 @@ -2127,10 +2188,9 @@
1.931 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.932 load_reg( R_EAX, Rm );
1.933 check_ralign16( R_EAX );
1.934 - MOV_r32_r32( R_EAX, R_ECX );
1.935 - ADD_imm8s_r32( 2, R_EAX );
1.936 - store_reg( R_EAX, Rm );
1.937 - MEM_READ_WORD( R_ECX, R_EAX );
1.938 + MMU_TRANSLATE_READ( R_EAX );
1.939 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.940 + MEM_READ_WORD( R_EAX, R_EAX );
1.941 store_reg( R_EAX, Rn );
1.942 sh4_x86.tstate = TSTATE_NONE;
1.943 }
1.944 @@ -2140,10 +2200,9 @@
1.945 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.946 load_reg( R_EAX, Rm );
1.947 check_ralign32( R_EAX );
1.948 - MOV_r32_r32( R_EAX, R_ECX );
1.949 - ADD_imm8s_r32( 4, R_EAX );
1.950 - store_reg( R_EAX, Rm );
1.951 - MEM_READ_LONG( R_ECX, R_EAX );
1.952 + MMU_TRANSLATE_READ( R_EAX );
1.953 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.954 + MEM_READ_LONG( R_EAX, R_EAX );
1.955 store_reg( R_EAX, Rn );
1.956 sh4_x86.tstate = TSTATE_NONE;
1.957 }
1.958 @@ -2246,30 +2305,33 @@
1.959 case 0x0:
1.960 { /* MOV.B R0, @(disp, Rn) */
1.961 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1.962 - load_reg( R_EAX, 0 );
1.963 - load_reg( R_ECX, Rn );
1.964 - ADD_imm32_r32( disp, R_ECX );
1.965 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.966 + load_reg( R_EAX, Rn );
1.967 + ADD_imm32_r32( disp, R_EAX );
1.968 + MMU_TRANSLATE_WRITE( R_EAX );
1.969 + load_reg( R_EDX, 0 );
1.970 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.971 sh4_x86.tstate = TSTATE_NONE;
1.972 }
1.973 break;
1.974 case 0x1:
1.975 { /* MOV.W R0, @(disp, Rn) */
1.976 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1.977 - load_reg( R_ECX, Rn );
1.978 - load_reg( R_EAX, 0 );
1.979 - ADD_imm32_r32( disp, R_ECX );
1.980 - check_walign16( R_ECX );
1.981 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.982 + load_reg( R_EAX, Rn );
1.983 + ADD_imm32_r32( disp, R_EAX );
1.984 + check_walign16( R_EAX );
1.985 + MMU_TRANSLATE_WRITE( R_EAX );
1.986 + load_reg( R_EDX, 0 );
1.987 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.988 sh4_x86.tstate = TSTATE_NONE;
1.989 }
1.990 break;
1.991 case 0x4:
1.992 { /* MOV.B @(disp, Rm), R0 */
1.993 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1.994 - load_reg( R_ECX, Rm );
1.995 - ADD_imm32_r32( disp, R_ECX );
1.996 - MEM_READ_BYTE( R_ECX, R_EAX );
1.997 + load_reg( R_EAX, Rm );
1.998 + ADD_imm32_r32( disp, R_EAX );
1.999 + MMU_TRANSLATE_READ( R_EAX );
1.1000 + MEM_READ_BYTE( R_EAX, R_EAX );
1.1001 store_reg( R_EAX, 0 );
1.1002 sh4_x86.tstate = TSTATE_NONE;
1.1003 }
1.1004 @@ -2277,10 +2339,11 @@
1.1005 case 0x5:
1.1006 { /* MOV.W @(disp, Rm), R0 */
1.1007 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1.1008 - load_reg( R_ECX, Rm );
1.1009 - ADD_imm32_r32( disp, R_ECX );
1.1010 - check_ralign16( R_ECX );
1.1011 - MEM_READ_WORD( R_ECX, R_EAX );
1.1012 + load_reg( R_EAX, Rm );
1.1013 + ADD_imm32_r32( disp, R_EAX );
1.1014 + check_ralign16( R_EAX );
1.1015 + MMU_TRANSLATE_READ( R_EAX );
1.1016 + MEM_READ_WORD( R_EAX, R_EAX );
1.1017 store_reg( R_EAX, 0 );
1.1018 sh4_x86.tstate = TSTATE_NONE;
1.1019 }
1.1020 @@ -2300,8 +2363,9 @@
1.1021 if( sh4_x86.in_delay_slot ) {
1.1022 SLOTILLEGAL();
1.1023 } else {
1.1024 - JF_rel8( EXIT_BLOCK_SIZE, nottaken );
1.1025 - exit_block( disp + pc + 4, pc+2 );
1.1026 + sh4vma_t target = disp + pc + 4;
1.1027 + JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1.1028 + exit_block_rel(target, pc+2 );
1.1029 JMP_TARGET(nottaken);
1.1030 return 2;
1.1031 }
1.1032 @@ -2313,8 +2377,9 @@
1.1033 if( sh4_x86.in_delay_slot ) {
1.1034 SLOTILLEGAL();
1.1035 } else {
1.1036 - JT_rel8( EXIT_BLOCK_SIZE, nottaken );
1.1037 - exit_block( disp + pc + 4, pc+2 );
1.1038 + sh4vma_t target = disp + pc + 4;
1.1039 + JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1.1040 + exit_block_rel(target, pc+2 );
1.1041 JMP_TARGET(nottaken);
1.1042 return 2;
1.1043 }
1.1044 @@ -2333,7 +2398,7 @@
1.1045 }
1.1046 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
1.1047 sh4_translate_instruction(pc+2);
1.1048 - exit_block( disp + pc + 4, pc+4 );
1.1049 + exit_block_rel( disp + pc + 4, pc+4 );
1.1050 // not taken
1.1051 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.1052 sh4_translate_instruction(pc+2);
1.1053 @@ -2347,6 +2412,7 @@
1.1054 if( sh4_x86.in_delay_slot ) {
1.1055 SLOTILLEGAL();
1.1056 } else {
1.1057 + sh4vma_t target = disp + pc + 4;
1.1058 sh4_x86.in_delay_slot = TRUE;
1.1059 if( sh4_x86.tstate == TSTATE_NONE ) {
1.1060 CMP_imm8s_sh4r( 1, R_T );
1.1061 @@ -2354,7 +2420,7 @@
1.1062 }
1.1063 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
1.1064 sh4_translate_instruction(pc+2);
1.1065 - exit_block( disp + pc + 4, pc+4 );
1.1066 + exit_block_rel( target, pc+4 );
1.1067 // not taken
1.1068 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.1069 sh4_translate_instruction(pc+2);
1.1070 @@ -2380,9 +2446,10 @@
1.1071 MOV_moff32_EAX( ptr );
1.1072 MOVSX_r16_r32( R_EAX, R_EAX );
1.1073 } else {
1.1074 - load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1.1075 - ADD_sh4r_r32( R_PC, R_ECX );
1.1076 - MEM_READ_WORD( R_ECX, R_EAX );
1.1077 + load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1.1078 + ADD_sh4r_r32( R_PC, R_EAX );
1.1079 + MMU_TRANSLATE_READ( R_EAX );
1.1080 + MEM_READ_WORD( R_EAX, R_EAX );
1.1081 sh4_x86.tstate = TSTATE_NONE;
1.1082 }
1.1083 store_reg( R_EAX, Rn );
1.1084 @@ -2397,7 +2464,7 @@
1.1085 } else {
1.1086 sh4_x86.in_delay_slot = TRUE;
1.1087 sh4_translate_instruction( pc + 2 );
1.1088 - exit_block( disp + pc + 4, pc+4 );
1.1089 + exit_block_rel( disp + pc + 4, pc+4 );
1.1090 sh4_x86.branch_taken = TRUE;
1.1091 return 4;
1.1092 }
1.1093 @@ -2413,7 +2480,7 @@
1.1094 store_spreg( R_EAX, R_PR );
1.1095 sh4_x86.in_delay_slot = TRUE;
1.1096 sh4_translate_instruction( pc + 2 );
1.1097 - exit_block( disp + pc + 4, pc+4 );
1.1098 + exit_block_rel( disp + pc + 4, pc+4 );
1.1099 sh4_x86.branch_taken = TRUE;
1.1100 return 4;
1.1101 }
1.1102 @@ -2424,32 +2491,35 @@
1.1103 case 0x0:
1.1104 { /* MOV.B R0, @(disp, GBR) */
1.1105 uint32_t disp = (ir&0xFF);
1.1106 - load_reg( R_EAX, 0 );
1.1107 - load_spreg( R_ECX, R_GBR );
1.1108 - ADD_imm32_r32( disp, R_ECX );
1.1109 - MEM_WRITE_BYTE( R_ECX, R_EAX );
1.1110 + load_spreg( R_EAX, R_GBR );
1.1111 + ADD_imm32_r32( disp, R_EAX );
1.1112 + MMU_TRANSLATE_WRITE( R_EAX );
1.1113 + load_reg( R_EDX, 0 );
1.1114 + MEM_WRITE_BYTE( R_EAX, R_EDX );
1.1115 sh4_x86.tstate = TSTATE_NONE;
1.1116 }
1.1117 break;
1.1118 case 0x1:
1.1119 { /* MOV.W R0, @(disp, GBR) */
1.1120 uint32_t disp = (ir&0xFF)<<1;
1.1121 - load_spreg( R_ECX, R_GBR );
1.1122 - load_reg( R_EAX, 0 );
1.1123 - ADD_imm32_r32( disp, R_ECX );
1.1124 - check_walign16( R_ECX );
1.1125 - MEM_WRITE_WORD( R_ECX, R_EAX );
1.1126 + load_spreg( R_EAX, R_GBR );
1.1127 + ADD_imm32_r32( disp, R_EAX );
1.1128 + check_walign16( R_EAX );
1.1129 + MMU_TRANSLATE_WRITE( R_EAX );
1.1130 + load_reg( R_EDX, 0 );
1.1131 + MEM_WRITE_WORD( R_EAX, R_EDX );
1.1132 sh4_x86.tstate = TSTATE_NONE;
1.1133 }
1.1134 break;
1.1135 case 0x2:
1.1136 { /* MOV.L R0, @(disp, GBR) */
1.1137 uint32_t disp = (ir&0xFF)<<2;
1.1138 - load_spreg( R_ECX, R_GBR );
1.1139 - load_reg( R_EAX, 0 );
1.1140 - ADD_imm32_r32( disp, R_ECX );
1.1141 - check_walign32( R_ECX );
1.1142 - MEM_WRITE_LONG( R_ECX, R_EAX );
1.1143 + load_spreg( R_EAX, R_GBR );
1.1144 + ADD_imm32_r32( disp, R_EAX );
1.1145 + check_walign32( R_EAX );
1.1146 + MMU_TRANSLATE_WRITE( R_EAX );
1.1147 + load_reg( R_EDX, 0 );
1.1148 + MEM_WRITE_LONG( R_EAX, R_EDX );
1.1149 sh4_x86.tstate = TSTATE_NONE;
1.1150 }
1.1151 break;
1.1152 @@ -2473,9 +2543,10 @@
1.1153 case 0x4:
1.1154 { /* MOV.B @(disp, GBR), R0 */
1.1155 uint32_t disp = (ir&0xFF);
1.1156 - load_spreg( R_ECX, R_GBR );
1.1157 - ADD_imm32_r32( disp, R_ECX );
1.1158 - MEM_READ_BYTE( R_ECX, R_EAX );
1.1159 + load_spreg( R_EAX, R_GBR );
1.1160 + ADD_imm32_r32( disp, R_EAX );
1.1161 + MMU_TRANSLATE_READ( R_EAX );
1.1162 + MEM_READ_BYTE( R_EAX, R_EAX );
1.1163 store_reg( R_EAX, 0 );
1.1164 sh4_x86.tstate = TSTATE_NONE;
1.1165 }
1.1166 @@ -2483,10 +2554,11 @@
1.1167 case 0x5:
1.1168 { /* MOV.W @(disp, GBR), R0 */
1.1169 uint32_t disp = (ir&0xFF)<<1;
1.1170 - load_spreg( R_ECX, R_GBR );
1.1171 - ADD_imm32_r32( disp, R_ECX );
1.1172 - check_ralign16( R_ECX );
1.1173 - MEM_READ_WORD( R_ECX, R_EAX );
1.1174 + load_spreg( R_EAX, R_GBR );
1.1175 + ADD_imm32_r32( disp, R_EAX );
1.1176 + check_ralign16( R_EAX );
1.1177 + MMU_TRANSLATE_READ( R_EAX );
1.1178 + MEM_READ_WORD( R_EAX, R_EAX );
1.1179 store_reg( R_EAX, 0 );
1.1180 sh4_x86.tstate = TSTATE_NONE;
1.1181 }
1.1182 @@ -2494,10 +2566,11 @@
1.1183 case 0x6:
1.1184 { /* MOV.L @(disp, GBR), R0 */
1.1185 uint32_t disp = (ir&0xFF)<<2;
1.1186 - load_spreg( R_ECX, R_GBR );
1.1187 - ADD_imm32_r32( disp, R_ECX );
1.1188 - check_ralign32( R_ECX );
1.1189 - MEM_READ_LONG( R_ECX, R_EAX );
1.1190 + load_spreg( R_EAX, R_GBR );
1.1191 + ADD_imm32_r32( disp, R_EAX );
1.1192 + check_ralign32( R_EAX );
1.1193 + MMU_TRANSLATE_READ( R_EAX );
1.1194 + MEM_READ_LONG( R_EAX, R_EAX );
1.1195 store_reg( R_EAX, 0 );
1.1196 sh4_x86.tstate = TSTATE_NONE;
1.1197 }
1.1198 @@ -2511,6 +2584,7 @@
1.1199 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.1200 ADD_sh4r_r32( R_PC, R_ECX );
1.1201 store_reg( R_ECX, 0 );
1.1202 + sh4_x86.tstate = TSTATE_NONE;
1.1203 }
1.1204 }
1.1205 break;
1.1206 @@ -2555,8 +2629,9 @@
1.1207 uint32_t imm = (ir&0xFF);
1.1208 load_reg( R_EAX, 0);
1.1209 load_reg( R_ECX, R_GBR);
1.1210 - ADD_r32_r32( R_EAX, R_ECX );
1.1211 - MEM_READ_BYTE( R_ECX, R_EAX );
1.1212 + ADD_r32_r32( R_ECX, R_EAX );
1.1213 + MMU_TRANSLATE_READ( R_EAX );
1.1214 + MEM_READ_BYTE( R_EAX, R_EAX );
1.1215 TEST_imm8_r8( imm, R_AL );
1.1216 SETE_t();
1.1217 sh4_x86.tstate = TSTATE_E;
1.1218 @@ -2567,9 +2642,10 @@
1.1219 uint32_t imm = (ir&0xFF);
1.1220 load_reg( R_EAX, 0 );
1.1221 load_spreg( R_ECX, R_GBR );
1.1222 - ADD_r32_r32( R_EAX, R_ECX );
1.1223 - PUSH_realigned_r32(R_ECX);
1.1224 - MEM_READ_BYTE( R_ECX, R_EAX );
1.1225 + ADD_r32_r32( R_ECX, R_EAX );
1.1226 + MMU_TRANSLATE_WRITE( R_EAX );
1.1227 + PUSH_realigned_r32(R_EAX);
1.1228 + MEM_READ_BYTE( R_EAX, R_EAX );
1.1229 POP_realigned_r32(R_ECX);
1.1230 AND_imm32_r32(imm, R_EAX );
1.1231 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.1232 @@ -2581,9 +2657,10 @@
1.1233 uint32_t imm = (ir&0xFF);
1.1234 load_reg( R_EAX, 0 );
1.1235 load_spreg( R_ECX, R_GBR );
1.1236 - ADD_r32_r32( R_EAX, R_ECX );
1.1237 - PUSH_realigned_r32(R_ECX);
1.1238 - MEM_READ_BYTE(R_ECX, R_EAX);
1.1239 + ADD_r32_r32( R_ECX, R_EAX );
1.1240 + MMU_TRANSLATE_WRITE( R_EAX );
1.1241 + PUSH_realigned_r32(R_EAX);
1.1242 + MEM_READ_BYTE(R_EAX, R_EAX);
1.1243 POP_realigned_r32(R_ECX);
1.1244 XOR_imm32_r32( imm, R_EAX );
1.1245 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.1246 @@ -2595,9 +2672,10 @@
1.1247 uint32_t imm = (ir&0xFF);
1.1248 load_reg( R_EAX, 0 );
1.1249 load_spreg( R_ECX, R_GBR );
1.1250 - ADD_r32_r32( R_EAX, R_ECX );
1.1251 - PUSH_realigned_r32(R_ECX);
1.1252 - MEM_READ_BYTE( R_ECX, R_EAX );
1.1253 + ADD_r32_r32( R_ECX, R_EAX );
1.1254 + MMU_TRANSLATE_WRITE( R_EAX );
1.1255 + PUSH_realigned_r32(R_EAX);
1.1256 + MEM_READ_BYTE( R_EAX, R_EAX );
1.1257 POP_realigned_r32(R_ECX);
1.1258 OR_imm32_r32(imm, R_EAX );
1.1259 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.1260 @@ -2629,9 +2707,10 @@
1.1261 // Note: we use sh4r.pc for the calc as we could be running at a
1.1262 // different virtual address than the translation was done with,
1.1263 // but we can safely assume that the low bits are the same.
1.1264 - load_imm32( R_ECX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.1265 - ADD_sh4r_r32( R_PC, R_ECX );
1.1266 - MEM_READ_LONG( R_ECX, R_EAX );
1.1267 + load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.1268 + ADD_sh4r_r32( R_PC, R_EAX );
1.1269 + MMU_TRANSLATE_READ( R_EAX );
1.1270 + MEM_READ_LONG( R_EAX, R_EAX );
1.1271 sh4_x86.tstate = TSTATE_NONE;
1.1272 }
1.1273 store_reg( R_EAX, Rn );
1.1274 @@ -2781,31 +2860,32 @@
1.1275 { /* FMOV @(R0, Rm), FRn */
1.1276 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1277 check_fpuen();
1.1278 - load_reg( R_ECX, Rm );
1.1279 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.1280 - check_ralign32( R_ECX );
1.1281 + load_reg( R_EAX, Rm );
1.1282 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.1283 + check_ralign32( R_EAX );
1.1284 + MMU_TRANSLATE_READ( R_EAX );
1.1285 load_spreg( R_EDX, R_FPSCR );
1.1286 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1287 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1.1288 - MEM_READ_LONG( R_ECX, R_EAX );
1.1289 + MEM_READ_LONG( R_EAX, R_EAX );
1.1290 load_fr_bank( R_EDX );
1.1291 store_fr( R_EDX, R_EAX, FRn );
1.1292 if( FRn&1 ) {
1.1293 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1.1294 JMP_TARGET(doublesize);
1.1295 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1296 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1297 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1298 load_xf_bank( R_EDX );
1.1299 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1300 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1301 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1302 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1303 JMP_TARGET(end);
1.1304 } else {
1.1305 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1.1306 JMP_TARGET(doublesize);
1.1307 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1308 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1309 load_fr_bank( R_EDX );
1.1310 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1311 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1312 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1313 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1314 JMP_TARGET(end);
1.1315 }
1.1316 sh4_x86.tstate = TSTATE_NONE;
1.1317 @@ -2815,30 +2895,31 @@
1.1318 { /* FMOV FRm, @(R0, Rn) */
1.1319 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1320 check_fpuen();
1.1321 - load_reg( R_ECX, Rn );
1.1322 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.1323 - check_walign32( R_ECX );
1.1324 + load_reg( R_EAX, Rn );
1.1325 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.1326 + check_walign32( R_EAX );
1.1327 + MMU_TRANSLATE_WRITE( R_EAX );
1.1328 load_spreg( R_EDX, R_FPSCR );
1.1329 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1330 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1.1331 load_fr_bank( R_EDX );
1.1332 - load_fr( R_EDX, R_EAX, FRm );
1.1333 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1334 + load_fr( R_EDX, R_ECX, FRm );
1.1335 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1336 if( FRm&1 ) {
1.1337 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1.1338 JMP_TARGET(doublesize);
1.1339 load_xf_bank( R_EDX );
1.1340 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1341 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1342 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1343 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1344 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1345 JMP_TARGET(end);
1.1346 } else {
1.1347 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1.1348 JMP_TARGET(doublesize);
1.1349 load_fr_bank( R_EDX );
1.1350 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1351 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1352 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1353 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1354 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1355 JMP_TARGET(end);
1.1356 }
1.1357 sh4_x86.tstate = TSTATE_NONE;
1.1358 @@ -2848,30 +2929,31 @@
1.1359 { /* FMOV @Rm, FRn */
1.1360 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1361 check_fpuen();
1.1362 - load_reg( R_ECX, Rm );
1.1363 - check_ralign32( R_ECX );
1.1364 + load_reg( R_EAX, Rm );
1.1365 + check_ralign32( R_EAX );
1.1366 + MMU_TRANSLATE_READ( R_EAX );
1.1367 load_spreg( R_EDX, R_FPSCR );
1.1368 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1369 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1.1370 - MEM_READ_LONG( R_ECX, R_EAX );
1.1371 + MEM_READ_LONG( R_EAX, R_EAX );
1.1372 load_fr_bank( R_EDX );
1.1373 store_fr( R_EDX, R_EAX, FRn );
1.1374 if( FRn&1 ) {
1.1375 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1.1376 JMP_TARGET(doublesize);
1.1377 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1378 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1379 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1380 load_xf_bank( R_EDX );
1.1381 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1382 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1383 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1384 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1385 JMP_TARGET(end);
1.1386 } else {
1.1387 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1.1388 JMP_TARGET(doublesize);
1.1389 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1390 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1391 load_fr_bank( R_EDX );
1.1392 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1393 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1394 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1395 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1396 JMP_TARGET(end);
1.1397 }
1.1398 sh4_x86.tstate = TSTATE_NONE;
1.1399 @@ -2881,36 +2963,33 @@
1.1400 { /* FMOV @Rm+, FRn */
1.1401 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.1402 check_fpuen();
1.1403 - load_reg( R_ECX, Rm );
1.1404 - check_ralign32( R_ECX );
1.1405 - MOV_r32_r32( R_ECX, R_EAX );
1.1406 + load_reg( R_EAX, Rm );
1.1407 + check_ralign32( R_EAX );
1.1408 + MMU_TRANSLATE_READ( R_EAX );
1.1409 load_spreg( R_EDX, R_FPSCR );
1.1410 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1411 - JNE_rel8(14 + MEM_READ_SIZE, doublesize);
1.1412 - ADD_imm8s_r32( 4, R_EAX );
1.1413 - store_reg( R_EAX, Rm );
1.1414 - MEM_READ_LONG( R_ECX, R_EAX );
1.1415 + JNE_rel8(12 + MEM_READ_SIZE, doublesize);
1.1416 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.1417 + MEM_READ_LONG( R_EAX, R_EAX );
1.1418 load_fr_bank( R_EDX );
1.1419 store_fr( R_EDX, R_EAX, FRn );
1.1420 if( FRn&1 ) {
1.1421 - JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
1.1422 + JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
1.1423 JMP_TARGET(doublesize);
1.1424 - ADD_imm8s_r32( 8, R_EAX );
1.1425 - store_reg(R_EAX, Rm);
1.1426 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1427 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.1428 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1429 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.1430 load_xf_bank( R_EDX );
1.1431 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1432 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1433 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1434 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1435 JMP_TARGET(end);
1.1436 } else {
1.1437 - JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
1.1438 - ADD_imm8s_r32( 8, R_EAX );
1.1439 - store_reg(R_EAX, Rm);
1.1440 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.1441 + JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
1.1442 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.1443 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.1444 load_fr_bank( R_EDX );
1.1445 - store_fr( R_EDX, R_EAX, FRn&0x0E );
1.1446 - store_fr( R_EDX, R_ECX, FRn|0x01 );
1.1447 + store_fr( R_EDX, R_ECX, FRn&0x0E );
1.1448 + store_fr( R_EDX, R_EAX, FRn|0x01 );
1.1449 JMP_TARGET(end);
1.1450 }
1.1451 sh4_x86.tstate = TSTATE_NONE;
1.1452 @@ -2920,29 +2999,30 @@
1.1453 { /* FMOV FRm, @Rn */
1.1454 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1455 check_fpuen();
1.1456 - load_reg( R_ECX, Rn );
1.1457 - check_walign32( R_ECX );
1.1458 + load_reg( R_EAX, Rn );
1.1459 + check_walign32( R_EAX );
1.1460 + MMU_TRANSLATE_WRITE( R_EAX );
1.1461 load_spreg( R_EDX, R_FPSCR );
1.1462 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1463 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1.1464 load_fr_bank( R_EDX );
1.1465 - load_fr( R_EDX, R_EAX, FRm );
1.1466 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1467 + load_fr( R_EDX, R_ECX, FRm );
1.1468 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1469 if( FRm&1 ) {
1.1470 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1.1471 JMP_TARGET(doublesize);
1.1472 load_xf_bank( R_EDX );
1.1473 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1474 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1475 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1476 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1477 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1478 JMP_TARGET(end);
1.1479 } else {
1.1480 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1.1481 JMP_TARGET(doublesize);
1.1482 load_fr_bank( R_EDX );
1.1483 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1484 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1485 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1486 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1487 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1488 JMP_TARGET(end);
1.1489 }
1.1490 sh4_x86.tstate = TSTATE_NONE;
1.1491 @@ -2952,35 +3032,38 @@
1.1492 { /* FMOV FRm, @-Rn */
1.1493 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.1494 check_fpuen();
1.1495 - load_reg( R_ECX, Rn );
1.1496 - check_walign32( R_ECX );
1.1497 + load_reg( R_EAX, Rn );
1.1498 + check_walign32( R_EAX );
1.1499 load_spreg( R_EDX, R_FPSCR );
1.1500 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.1501 - JNE_rel8(14 + MEM_WRITE_SIZE, doublesize);
1.1502 + JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
1.1503 + ADD_imm8s_r32( -4, R_EAX );
1.1504 + MMU_TRANSLATE_WRITE( R_EAX );
1.1505 load_fr_bank( R_EDX );
1.1506 - load_fr( R_EDX, R_EAX, FRm );
1.1507 - ADD_imm8s_r32(-4,R_ECX);
1.1508 - store_reg( R_ECX, Rn );
1.1509 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.1510 + load_fr( R_EDX, R_ECX, FRm );
1.1511 + ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1.1512 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.1513 if( FRm&1 ) {
1.1514 - JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
1.1515 + JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1.1516 JMP_TARGET(doublesize);
1.1517 + ADD_imm8s_r32(-8,R_EAX);
1.1518 + MMU_TRANSLATE_WRITE( R_EAX );
1.1519 load_xf_bank( R_EDX );
1.1520 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1521 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1522 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1523 - ADD_imm8s_r32(-8,R_ECX);
1.1524 - store_reg( R_ECX, Rn );
1.1525 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1526 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.1527 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1528 JMP_TARGET(end);
1.1529 } else {
1.1530 - JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
1.1531 + JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1.1532 JMP_TARGET(doublesize);
1.1533 + ADD_imm8s_r32(-8,R_EAX);
1.1534 + MMU_TRANSLATE_WRITE( R_EAX );
1.1535 load_fr_bank( R_EDX );
1.1536 - load_fr( R_EDX, R_EAX, FRm&0x0E );
1.1537 + load_fr( R_EDX, R_ECX, FRm&0x0E );
1.1538 load_fr( R_EDX, R_EDX, FRm|0x01 );
1.1539 - ADD_imm8s_r32(-8,R_ECX);
1.1540 - store_reg( R_ECX, Rn );
1.1541 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.1542 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.1543 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.1544 JMP_TARGET(end);
1.1545 }
1.1546 sh4_x86.tstate = TSTATE_NONE;
.