Search
lxdream.org :: lxdream :: r527:14c9489f647e
lxdream 0.9.1
released Jun 29
Download Now
changeset527:14c9489f647e
parent526:ba3da45b5754
child528:49cb007348aa
authornkeynes
dateSun Nov 18 11:12:44 2007 +0000 (12 years ago)
x86-64 translator work-in-progress
src/sh4/sh4core.h
src/sh4/sh4mem.c
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.c
src/sh4/sh4x86.in
src/sh4/x86op.h
src/sh4/xltcache.c
src/x86dasm/x86dasm.c
src/x86dasm/x86dasm.h
1.1 --- a/src/sh4/sh4core.h Sat Nov 17 06:04:19 2007 +0000
1.2 +++ b/src/sh4/sh4core.h Sun Nov 18 11:12:44 2007 +0000
1.3 @@ -114,14 +114,16 @@
1.4 #define BREAK_PERM 2
1.5
1.6 /* SH4 Memory */
1.7 -int32_t sh4_read_long( uint32_t addr );
1.8 -int32_t sh4_read_word( uint32_t addr );
1.9 -int32_t sh4_read_byte( uint32_t addr );
1.10 -void sh4_write_long( uint32_t addr, uint32_t val );
1.11 -void sh4_write_word( uint32_t addr, uint32_t val );
1.12 -void sh4_write_byte( uint32_t addr, uint32_t val );
1.13 -int32_t sh4_read_phys_word( uint32_t addr );
1.14 -void sh4_flush_store_queue( uint32_t addr );
1.15 +int64_t sh4_read_quad( sh4addr_t addr );
1.16 +int32_t sh4_read_long( sh4addr_t addr );
1.17 +int32_t sh4_read_word( sh4addr_t addr );
1.18 +int32_t sh4_read_byte( sh4addr_t addr );
1.19 +void sh4_write_quad( sh4addr_t addr, uint64_t val );
1.20 +void sh4_write_long( sh4addr_t addr, uint32_t val );
1.21 +void sh4_write_word( sh4addr_t addr, uint32_t val );
1.22 +void sh4_write_byte( sh4addr_t addr, uint32_t val );
1.23 +int32_t sh4_read_phys_word( sh4addr_t addr );
1.24 +void sh4_flush_store_queue( sh4addr_t addr );
1.25
1.26 /* SH4 Support methods */
1.27 uint32_t sh4_read_sr(void);
2.1 --- a/src/sh4/sh4mem.c Sat Nov 17 06:04:19 2007 +0000
2.2 +++ b/src/sh4/sh4mem.c Sun Nov 18 11:12:44 2007 +0000
2.3 @@ -69,7 +69,7 @@
2.4 extern struct mmio_region *P4_io[];
2.5 sh4ptr_t sh4_main_ram;
2.6
2.7 -int32_t sh4_read_p4( uint32_t addr )
2.8 +int32_t sh4_read_p4( sh4addr_t addr )
2.9 {
2.10 struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];
2.11 if( !io ) {
2.12 @@ -86,7 +86,7 @@
2.13 }
2.14 }
2.15
2.16 -void sh4_write_p4( uint32_t addr, int32_t val )
2.17 +void sh4_write_p4( sh4addr_t addr, int32_t val )
2.18 {
2.19 struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];
2.20 if( !io ) {
2.21 @@ -104,7 +104,7 @@
2.22 }
2.23 }
2.24
2.25 -int32_t sh4_read_phys_word( uint32_t addr )
2.26 +int32_t sh4_read_phys_word( sh4addr_t addr )
2.27 {
2.28 sh4ptr_t page;
2.29 if( addr >= 0xE0000000 ) /* P4 Area, handled specially */
2.30 @@ -127,7 +127,16 @@
2.31 }
2.32 }
2.33
2.34 -int32_t sh4_read_long( uint32_t addr )
2.35 +/**
2.36 + * Convenience function to read a quad-word (implemented as two long reads).
2.37 + */
2.38 +int64_t sh4_read_quad( sh4addr_t addr )
2.39 +{
2.40 + return ((int64_t)((uint32_t)sh4_read_long(addr))) |
2.41 + (((int64_t)((uint32_t)sh4_read_long(addr+4))) << 32);
2.42 +}
2.43 +
2.44 +int32_t sh4_read_long( sh4addr_t addr )
2.45 {
2.46 sh4ptr_t page;
2.47
2.48 @@ -159,7 +168,7 @@
2.49 }
2.50 }
2.51
2.52 -int32_t sh4_read_word( uint32_t addr )
2.53 +int32_t sh4_read_word( sh4addr_t addr )
2.54 {
2.55 sh4ptr_t page;
2.56
2.57 @@ -191,7 +200,7 @@
2.58 }
2.59 }
2.60
2.61 -int32_t sh4_read_byte( uint32_t addr )
2.62 +int32_t sh4_read_byte( sh4addr_t addr )
2.63 {
2.64 sh4ptr_t page;
2.65
2.66 @@ -224,7 +233,16 @@
2.67 }
2.68 }
2.69
2.70 -void sh4_write_long( uint32_t addr, uint32_t val )
2.71 +/**
2.72 + * Convenience function to write a quad-word (implemented as two long writes).
2.73 + */
2.74 +void sh4_write_quad( sh4addr_t addr, uint64_t val )
2.75 +{
2.76 + sh4_write_long( addr, (uint32_t)val );
2.77 + sh4_write_long( addr+4, (uint32_t)(val>>32) );
2.78 +}
2.79 +
2.80 +void sh4_write_long( sh4addr_t addr, uint32_t val )
2.81 {
2.82 sh4ptr_t page;
2.83
2.84 @@ -270,7 +288,7 @@
2.85 }
2.86 }
2.87
2.88 -void sh4_write_word( uint32_t addr, uint32_t val )
2.89 +void sh4_write_word( sh4addr_t addr, uint32_t val )
2.90 {
2.91 sh4ptr_t page;
2.92
2.93 @@ -310,7 +328,7 @@
2.94 }
2.95 }
2.96
2.97 -void sh4_write_byte( uint32_t addr, uint32_t val )
2.98 +void sh4_write_byte( sh4addr_t addr, uint32_t val )
2.99 {
2.100 sh4ptr_t page;
2.101
2.102 @@ -355,7 +373,7 @@
2.103 /* FIXME: Handle all the many special cases when the range doesn't fall cleanly
2.104 * into the same memory block
2.105 */
2.106 -void mem_copy_from_sh4( sh4ptr_t dest, uint32_t srcaddr, size_t count ) {
2.107 +void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t srcaddr, size_t count ) {
2.108 if( srcaddr >= 0x04000000 && srcaddr < 0x05000000 ) {
2.109 pvr2_vram64_read( dest, srcaddr, count );
2.110 } else {
2.111 @@ -368,7 +386,7 @@
2.112 }
2.113 }
2.114
2.115 -void mem_copy_to_sh4( uint32_t destaddr, sh4ptr_t src, size_t count ) {
2.116 +void mem_copy_to_sh4( sh4addr_t destaddr, sh4ptr_t src, size_t count ) {
2.117 if( destaddr >= 0x10000000 && destaddr < 0x14000000 ) {
2.118 pvr2_dma_write( destaddr, src, count );
2.119 return;
2.120 @@ -387,7 +405,7 @@
2.121 }
2.122 }
2.123
2.124 -void sh4_flush_store_queue( uint32_t addr )
2.125 +void sh4_flush_store_queue( sh4addr_t addr )
2.126 {
2.127 /* Store queue operation */
2.128 int queue = (addr&0x20)>>2;
3.1 --- a/src/sh4/sh4trans.c Sat Nov 17 06:04:19 2007 +0000
3.2 +++ b/src/sh4/sh4trans.c Sun Nov 18 11:12:44 2007 +0000
3.3 @@ -99,7 +99,7 @@
3.4 xlat_output = block->code + (xlat_output - oldstart);
3.5 eob = block->code + block->size;
3.6 }
3.7 - done = sh4_x86_translate_instruction( pc );
3.8 + done = sh4_translate_instruction( pc );
3.9 assert( xlat_output <= eob );
3.10 pc += 2;
3.11 if ( pc >= lastpc ) {
3.12 @@ -132,7 +132,7 @@
3.13
3.14 sh4_translate_begin_block(pc);
3.15
3.16 - while( (done = sh4_x86_translate_instruction( pc )) == 0 ) {
3.17 + while( (done = sh4_translate_instruction( pc )) == 0 ) {
3.18 assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );
3.19 pc += 2;
3.20 }
4.1 --- a/src/sh4/sh4trans.h Sat Nov 17 06:04:19 2007 +0000
4.2 +++ b/src/sh4/sh4trans.h Sun Nov 18 11:12:44 2007 +0000
4.3 @@ -45,6 +45,9 @@
4.4 * actual code gen (eg sh4x86.c)
4.5 ******************************************************************************/
4.6
4.7 +#define TARGET_X86 1
4.8 +#define TARGET_X86_64 2
4.9 +
4.10 void sh4_translate_begin_block( sh4addr_t pc );
4.11 uint32_t sh4_translate_instruction( sh4addr_t pc );
4.12 void sh4_translate_end_block( sh4addr_t pc );
5.1 --- a/src/sh4/sh4x86.c Sat Nov 17 06:04:19 2007 +0000
5.2 +++ b/src/sh4/sh4x86.c Sun Nov 18 11:12:44 2007 +0000
5.3 @@ -152,6 +152,17 @@
5.4 }
5.5
5.6 /**
5.7 + * Load an immediate 64-bit quantity (note: x86-64 only)
5.8 + */
5.9 +static inline void load_imm64( int x86reg, uint32_t value ) {
5.10 + /* mov #value, reg */
5.11 + REXW();
5.12 + OP(0xB8 + x86reg);
5.13 + OP64(value);
5.14 +}
5.15 +
5.16 +
5.17 +/**
5.18 * Emit an instruction to store an SH4 reg (RN)
5.19 */
5.20 void static inline store_reg( int x86reg, int sh4reg ) {
5.21 @@ -253,16 +264,161 @@
5.22 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
5.23 }
5.24
5.25 +#if SH4_TRANSLATOR == TARGET_X86_64
5.26 +/* X86-64 has different calling conventions... */
5.27 +/**
5.28 + * Note: clobbers EAX to make the indirect call - this isn't usually
5.29 + * a problem since the callee will usually clobber it anyway.
5.30 + * Size: 12 bytes
5.31 + */
5.32 +#define CALL_FUNC0_SIZE 12
5.33 +static inline void call_func0( void *ptr )
5.34 +{
5.35 + load_imm64(R_EAX, (uint64_t)ptr);
5.36 + CALL_r32(R_EAX);
5.37 +}
5.38 +
5.39 +#define CALL_FUNC1_SIZE 14
5.40 +static inline void call_func1( void *ptr, int arg1 )
5.41 +{
5.42 + MOV_r32_r32(arg1, R_EDI);
5.43 + call_func0(ptr);
5.44 +}
5.45 +
5.46 +#define CALL_FUNC2_SIZE 16
5.47 +static inline void call_func2( void *ptr, int arg1, int arg2 )
5.48 +{
5.49 + MOV_r32_r32(arg1, R_EDI);
5.50 + MOV_r32_r32(arg2, R_ESI);
5.51 + call_func0(ptr);
5.52 +}
5.53 +
5.54 +#define MEM_WRITE_DOUBLE_SIZE 39
5.55 +/**
5.56 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
5.57 + * the second in arg2b
5.58 + */
5.59 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
5.60 +{
5.61 +/*
5.62 + MOV_r32_r32( addr, R_EDI );
5.63 + MOV_r32_r32( arg2b, R_ESI );
5.64 + REXW(); SHL_imm8_r32( 32, R_ESI );
5.65 + REXW(); MOVZX_r16_r32( arg2a, arg2a );
5.66 + REXW(); OR_r32_r32( arg2a, R_ESI );
5.67 + call_func0(sh4_write_quad);
5.68 +*/
5.69 + PUSH_r32(arg2b);
5.70 + PUSH_r32(addr);
5.71 + call_func2(sh4_write_long, addr, arg2a);
5.72 + POP_r32(addr);
5.73 + POP_r32(arg2b);
5.74 + ADD_imm8s_r32(4, addr);
5.75 + call_func2(sh4_write_long, addr, arg2b);
5.76 +}
5.77 +
5.78 +#define MEM_READ_DOUBLE_SIZE 35
5.79 +/**
5.80 + * Read a double (64-bit) value from memory, writing the first word into arg2a
5.81 + * and the second into arg2b. The addr must not be in EAX
5.82 + */
5.83 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
5.84 +{
5.85 +/*
5.86 + MOV_r32_r32( addr, R_EDI );
5.87 + call_func0(sh4_read_quad);
5.88 + REXW(); MOV_r32_r32( R_EAX, arg2a );
5.89 + REXW(); MOV_r32_r32( R_EAX, arg2b );
5.90 + REXW(); SHR_imm8_r32( 32, arg2b );
5.91 +*/
5.92 + PUSH_r32(addr);
5.93 + call_func1(sh4_read_long, addr);
5.94 + POP_r32(R_EDI);
5.95 + PUSH_r32(R_EAX);
5.96 + ADD_imm8s_r32(4, R_EDI);
5.97 + call_func0(sh4_read_long);
5.98 + MOV_r32_r32(R_EAX, arg2b);
5.99 + POP_r32(arg2a);
5.100 +}
5.101 +
5.102 +#define EXIT_BLOCK_SIZE 35
5.103 +/**
5.104 + * Exit the block to an absolute PC
5.105 + */
5.106 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
5.107 +{
5.108 + load_imm32( R_ECX, pc ); // 5
5.109 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
5.110 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
5.111 + REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
5.112 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
5.113 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
5.114 + POP_r32(R_EBP);
5.115 + RET();
5.116 +}
5.117 +
5.118 +
5.119 +/**
5.120 + * Write the block trailer (exception handling block)
5.121 + */
5.122 +void sh4_translate_end_block( sh4addr_t pc ) {
5.123 + if( sh4_x86.branch_taken == FALSE ) {
5.124 + // Didn't exit unconditionally already, so write the termination here
5.125 + exit_block( pc, pc );
5.126 + }
5.127 + if( sh4_x86.backpatch_posn != 0 ) {
5.128 + uint8_t *end_ptr = xlat_output;
5.129 + // Exception termination. Jump block for various exception codes:
5.130 + load_imm32( R_EDI, EXC_DATA_ADDR_READ );
5.131 + JMP_rel8( 33, target1 );
5.132 + load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
5.133 + JMP_rel8( 26, target2 );
5.134 + load_imm32( R_EDI, EXC_ILLEGAL );
5.135 + JMP_rel8( 19, target3 );
5.136 + load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
5.137 + JMP_rel8( 12, target4 );
5.138 + load_imm32( R_EDI, EXC_FPU_DISABLED );
5.139 + JMP_rel8( 5, target5 );
5.140 + load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
5.141 + // target
5.142 + JMP_TARGET(target1);
5.143 + JMP_TARGET(target2);
5.144 + JMP_TARGET(target3);
5.145 + JMP_TARGET(target4);
5.146 + JMP_TARGET(target5);
5.147 + // Raise exception
5.148 + load_spreg( R_ECX, REG_OFFSET(pc) );
5.149 + ADD_r32_r32( R_EDX, R_ECX );
5.150 + ADD_r32_r32( R_EDX, R_ECX );
5.151 + store_spreg( R_ECX, REG_OFFSET(pc) );
5.152 + MOV_moff32_EAX( &sh4_cpu_period );
5.153 + MUL_r32( R_EDX );
5.154 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
5.155 +
5.156 + call_func0( sh4_raise_exception );
5.157 + load_spreg( R_EAX, REG_OFFSET(pc) );
5.158 + call_func1(xlat_get_code,R_EAX);
5.159 + POP_r32(R_EBP);
5.160 + RET();
5.161 +
5.162 + sh4_x86_do_backpatch( end_ptr );
5.163 + }
5.164 +}
5.165 +
5.166 +#else /* SH4_TRANSLATOR == TARGET_X86 */
5.167 +
5.168 /**
5.169 * Note: clobbers EAX to make the indirect call - this isn't usually
5.170 * a problem since the callee will usually clobber it anyway.
5.171 */
5.172 +#define CALL_FUNC0_SIZE 7
5.173 static inline void call_func0( void *ptr )
5.174 {
5.175 load_imm32(R_EAX, (uint32_t)ptr);
5.176 CALL_r32(R_EAX);
5.177 }
5.178
5.179 +#define CALL_FUNC1_SIZE 11
5.180 static inline void call_func1( void *ptr, int arg1 )
5.181 {
5.182 PUSH_r32(arg1);
5.183 @@ -270,6 +426,7 @@
5.184 ADD_imm8s_r32( 4, R_ESP );
5.185 }
5.186
5.187 +#define CALL_FUNC2_SIZE 12
5.188 static inline void call_func2( void *ptr, int arg1, int arg2 )
5.189 {
5.190 PUSH_r32(arg2);
5.191 @@ -283,6 +440,7 @@
5.192 * the second in arg2b
5.193 * NB: 30 bytes
5.194 */
5.195 +#define MEM_WRITE_DOUBLE_SIZE 30
5.196 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
5.197 {
5.198 ADD_imm8s_r32( 4, addr );
5.199 @@ -302,6 +460,7 @@
5.200 * and the second into arg2b. The addr must not be in EAX
5.201 * NB: 27 bytes
5.202 */
5.203 +#define MEM_READ_DOUBLE_SIZE 27
5.204 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
5.205 {
5.206 PUSH_r32(addr);
5.207 @@ -316,6 +475,71 @@
5.208 POP_r32(arg2a);
5.209 }
5.210
5.211 +#define EXIT_BLOCK_SIZE 29
5.212 +/**
5.213 + * Exit the block to an absolute PC
5.214 + */
5.215 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
5.216 +{
5.217 + load_imm32( R_ECX, pc ); // 5
5.218 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
5.219 + MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
5.220 + AND_imm8s_r32( 0xFC, R_EAX ); // 3
5.221 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
5.222 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
5.223 + POP_r32(R_EBP);
5.224 + RET();
5.225 +}
5.226 +
5.227 +/**
5.228 + * Write the block trailer (exception handling block)
5.229 + */
5.230 +void sh4_translate_end_block( sh4addr_t pc ) {
5.231 + if( sh4_x86.branch_taken == FALSE ) {
5.232 + // Didn't exit unconditionally already, so write the termination here
5.233 + exit_block( pc, pc );
5.234 + }
5.235 + if( sh4_x86.backpatch_posn != 0 ) {
5.236 + uint8_t *end_ptr = xlat_output;
5.237 + // Exception termination. Jump block for various exception codes:
5.238 + PUSH_imm32( EXC_DATA_ADDR_READ );
5.239 + JMP_rel8( 33, target1 );
5.240 + PUSH_imm32( EXC_DATA_ADDR_WRITE );
5.241 + JMP_rel8( 26, target2 );
5.242 + PUSH_imm32( EXC_ILLEGAL );
5.243 + JMP_rel8( 19, target3 );
5.244 + PUSH_imm32( EXC_SLOT_ILLEGAL );
5.245 + JMP_rel8( 12, target4 );
5.246 + PUSH_imm32( EXC_FPU_DISABLED );
5.247 + JMP_rel8( 5, target5 );
5.248 + PUSH_imm32( EXC_SLOT_FPU_DISABLED );
5.249 + // target
5.250 + JMP_TARGET(target1);
5.251 + JMP_TARGET(target2);
5.252 + JMP_TARGET(target3);
5.253 + JMP_TARGET(target4);
5.254 + JMP_TARGET(target5);
5.255 + // Raise exception
5.256 + load_spreg( R_ECX, REG_OFFSET(pc) );
5.257 + ADD_r32_r32( R_EDX, R_ECX );
5.258 + ADD_r32_r32( R_EDX, R_ECX );
5.259 + store_spreg( R_ECX, REG_OFFSET(pc) );
5.260 + MOV_moff32_EAX( &sh4_cpu_period );
5.261 + MUL_r32( R_EDX );
5.262 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
5.263 +
5.264 + call_func0( sh4_raise_exception );
5.265 + ADD_imm8s_r32( 4, R_ESP );
5.266 + load_spreg( R_EAX, REG_OFFSET(pc) );
5.267 + call_func1(xlat_get_code,R_EAX);
5.268 + POP_r32(R_EBP);
5.269 + RET();
5.270 +
5.271 + sh4_x86_do_backpatch( end_ptr );
5.272 + }
5.273 +}
5.274 +#endif
5.275 +
5.276 /* Exception checks - Note that all exception checks will clobber EAX */
5.277 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
5.278
5.279 @@ -431,22 +655,6 @@
5.280 }
5.281
5.282 /**
5.283 - * Exit the block to an absolute PC
5.284 - * Bytes: 29
5.285 - */
5.286 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
5.287 -{
5.288 - load_imm32( R_ECX, pc ); // 5
5.289 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
5.290 - MOV_moff32_EAX( (uint32_t)xlat_get_lut_entry(pc) ); // 5
5.291 - AND_imm8s_r32( 0xFC, R_EAX ); // 3
5.292 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
5.293 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
5.294 - POP_r32(R_EBP);
5.295 - RET();
5.296 -}
5.297 -
5.298 -/**
5.299 * Exit the block with sh4r.pc already written
5.300 * Bytes: 15
5.301 */
5.302 @@ -460,57 +668,6 @@
5.303 RET();
5.304 }
5.305
5.306 -/**
5.307 - * Write the block trailer (exception handling block)
5.308 - */
5.309 -void sh4_translate_end_block( sh4addr_t pc ) {
5.310 - if( sh4_x86.branch_taken == FALSE ) {
5.311 - // Didn't exit unconditionally already, so write the termination here
5.312 - exit_block( pc, pc );
5.313 - }
5.314 - if( sh4_x86.backpatch_posn != 0 ) {
5.315 - uint8_t *end_ptr = xlat_output;
5.316 - // Exception termination. Jump block for various exception codes:
5.317 - PUSH_imm32( EXC_DATA_ADDR_READ );
5.318 - JMP_rel8( 33, target1 );
5.319 - PUSH_imm32( EXC_DATA_ADDR_WRITE );
5.320 - JMP_rel8( 26, target2 );
5.321 - PUSH_imm32( EXC_ILLEGAL );
5.322 - JMP_rel8( 19, target3 );
5.323 - PUSH_imm32( EXC_SLOT_ILLEGAL );
5.324 - JMP_rel8( 12, target4 );
5.325 - PUSH_imm32( EXC_FPU_DISABLED );
5.326 - JMP_rel8( 5, target5 );
5.327 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );
5.328 - // target
5.329 - JMP_TARGET(target1);
5.330 - JMP_TARGET(target2);
5.331 - JMP_TARGET(target3);
5.332 - JMP_TARGET(target4);
5.333 - JMP_TARGET(target5);
5.334 - // Raise exception
5.335 - load_spreg( R_ECX, REG_OFFSET(pc) );
5.336 - ADD_r32_r32( R_EDX, R_ECX );
5.337 - ADD_r32_r32( R_EDX, R_ECX );
5.338 - store_spreg( R_ECX, REG_OFFSET(pc) );
5.339 - MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
5.340 - MUL_r32( R_EDX );
5.341 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
5.342 -
5.343 - load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
5.344 - CALL_r32( R_EAX ); // 2
5.345 - ADD_imm8s_r32( 4, R_ESP );
5.346 - load_spreg( R_EAX, REG_OFFSET(pc) );
5.347 - call_func1(xlat_get_code,R_EAX);
5.348 - POP_r32(R_EBP);
5.349 - RET();
5.350 -
5.351 - sh4_x86_do_backpatch( end_ptr );
5.352 - }
5.353 -
5.354 -}
5.355 -
5.356 -
5.357 extern uint16_t *sh4_icache;
5.358 extern uint32_t sh4_icache_addr;
5.359
5.360 @@ -531,7 +688,7 @@
5.361 ir = sh4_icache[(pc&0xFFF)>>1];
5.362 } else {
5.363 sh4_icache = (uint16_t *)mem_get_page(pc);
5.364 - if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
5.365 + if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
5.366 /* If someone's actually been so daft as to try to execute out of an IO
5.367 * region, fallback on the full-blown memory read
5.368 */
5.369 @@ -655,7 +812,7 @@
5.370 PUSH_r32( R_EAX );
5.371 AND_imm32_r32( 0xFC000000, R_EAX );
5.372 CMP_imm32_r32( 0xE0000000, R_EAX );
5.373 - JNE_rel8(7, end);
5.374 + JNE_rel8(CALL_FUNC0_SIZE, end);
5.375 call_func0( sh4_flush_store_queue );
5.376 JMP_TARGET(end);
5.377 ADD_imm8s_r32( 4, R_ESP );
5.378 @@ -985,7 +1142,7 @@
5.379
5.380 load_spreg( R_ECX, R_S );
5.381 TEST_r32_r32(R_ECX, R_ECX);
5.382 - JE_rel8( 7, nosat );
5.383 + JE_rel8( CALL_FUNC0_SIZE, nosat );
5.384 call_func0( signsat48 );
5.385 JMP_TARGET( nosat );
5.386 sh4_x86.tstate = TSTATE_NONE;
5.387 @@ -2519,7 +2676,7 @@
5.388 if( sh4_x86.in_delay_slot ) {
5.389 SLOTILLEGAL();
5.390 } else {
5.391 - JF_rel8( 29, nottaken );
5.392 + JF_rel8( EXIT_BLOCK_SIZE, nottaken );
5.393 exit_block( disp + pc + 4, pc+2 );
5.394 JMP_TARGET(nottaken);
5.395 return 2;
5.396 @@ -2532,7 +2689,7 @@
5.397 if( sh4_x86.in_delay_slot ) {
5.398 SLOTILLEGAL();
5.399 } else {
5.400 - JT_rel8( 29, nottaken );
5.401 + JT_rel8( EXIT_BLOCK_SIZE, nottaken );
5.402 exit_block( disp + pc + 4, pc+2 );
5.403 JMP_TARGET(nottaken);
5.404 return 2;
5.405 @@ -2671,8 +2828,8 @@
5.406 if( sh4_x86.in_delay_slot ) {
5.407 SLOTILLEGAL();
5.408 } else {
5.409 - PUSH_imm32( imm );
5.410 - call_func0( sh4_raise_trap );
5.411 + load_imm32( R_EAX, imm );
5.412 + call_func1( sh4_raise_trap, R_EAX );
5.413 ADD_imm8s_r32( 4, R_ESP );
5.414 sh4_x86.tstate = TSTATE_NONE;
5.415 exit_block_pcset(pc);
5.416 @@ -2781,7 +2938,7 @@
5.417 load_spreg( R_ECX, R_GBR );
5.418 ADD_r32_r32( R_EAX, R_ECX );
5.419 PUSH_r32(R_ECX);
5.420 - call_func0(sh4_read_byte);
5.421 + MEM_READ_BYTE( R_ECX, R_EAX );
5.422 POP_r32(R_ECX);
5.423 AND_imm32_r32(imm, R_EAX );
5.424 MEM_WRITE_BYTE( R_ECX, R_EAX );
5.425 @@ -2795,7 +2952,7 @@
5.426 load_spreg( R_ECX, R_GBR );
5.427 ADD_r32_r32( R_EAX, R_ECX );
5.428 PUSH_r32(R_ECX);
5.429 - call_func0(sh4_read_byte);
5.430 + MEM_READ_BYTE(R_ECX, R_EAX);
5.431 POP_r32(R_ECX);
5.432 XOR_imm32_r32( imm, R_EAX );
5.433 MEM_WRITE_BYTE( R_ECX, R_EAX );
5.434 @@ -2809,7 +2966,7 @@
5.435 load_spreg( R_ECX, R_GBR );
5.436 ADD_r32_r32( R_EAX, R_ECX );
5.437 PUSH_r32(R_ECX);
5.438 - call_func0(sh4_read_byte);
5.439 + MEM_READ_BYTE( R_ECX, R_EAX );
5.440 POP_r32(R_ECX);
5.441 OR_imm32_r32(imm, R_EAX );
5.442 MEM_WRITE_BYTE( R_ECX, R_EAX );
5.443 @@ -2827,7 +2984,7 @@
5.444 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
5.445 sh4ptr_t ptr = mem_get_region(target);
5.446 if( ptr != NULL ) {
5.447 - MOV_moff32_EAX( (uint32_t)ptr );
5.448 + MOV_moff32_EAX( ptr );
5.449 } else {
5.450 load_imm32( R_ECX, target );
5.451 MEM_READ_LONG( R_ECX, R_EAX );
5.452 @@ -2986,12 +3143,12 @@
5.453 check_ralign32( R_ECX );
5.454 load_spreg( R_EDX, R_FPSCR );
5.455 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.456 - JNE_rel8(19, doublesize);
5.457 + JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
5.458 MEM_READ_LONG( R_ECX, R_EAX );
5.459 load_fr_bank( R_EDX );
5.460 store_fr( R_EDX, R_EAX, FRn );
5.461 if( FRn&1 ) {
5.462 - JMP_rel8(48, end);
5.463 + JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
5.464 JMP_TARGET(doublesize);
5.465 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
5.466 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
5.467 @@ -3000,7 +3157,7 @@
5.468 store_fr( R_EDX, R_ECX, FRn|0x01 );
5.469 JMP_TARGET(end);
5.470 } else {
5.471 - JMP_rel8(36, end);
5.472 + JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
5.473 JMP_TARGET(doublesize);
5.474 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
5.475 load_fr_bank( R_EDX );
5.476 @@ -3021,12 +3178,12 @@
5.477 check_walign32( R_ECX );
5.478 load_spreg( R_EDX, R_FPSCR );
5.479 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.480 - JNE_rel8(20, doublesize);
5.481 + JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
5.482 load_fr_bank( R_EDX );
5.483 load_fr( R_EDX, R_EAX, FRm );
5.484 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
5.485 if( FRm&1 ) {
5.486 - JMP_rel8( 48, end );
5.487 + JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
5.488 JMP_TARGET(doublesize);
5.489 load_xf_bank( R_EDX );
5.490 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.491 @@ -3034,7 +3191,7 @@
5.492 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
5.493 JMP_TARGET(end);
5.494 } else {
5.495 - JMP_rel8( 39, end );
5.496 + JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
5.497 JMP_TARGET(doublesize);
5.498 load_fr_bank( R_EDX );
5.499 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.500 @@ -3054,12 +3211,12 @@
5.501 check_ralign32( R_ECX );
5.502 load_spreg( R_EDX, R_FPSCR );
5.503 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.504 - JNE_rel8(19, doublesize);
5.505 + JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
5.506 MEM_READ_LONG( R_ECX, R_EAX );
5.507 load_fr_bank( R_EDX );
5.508 store_fr( R_EDX, R_EAX, FRn );
5.509 if( FRn&1 ) {
5.510 - JMP_rel8(48, end);
5.511 + JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
5.512 JMP_TARGET(doublesize);
5.513 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
5.514 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
5.515 @@ -3068,7 +3225,7 @@
5.516 store_fr( R_EDX, R_ECX, FRn|0x01 );
5.517 JMP_TARGET(end);
5.518 } else {
5.519 - JMP_rel8(36, end);
5.520 + JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
5.521 JMP_TARGET(doublesize);
5.522 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
5.523 load_fr_bank( R_EDX );
5.524 @@ -3089,14 +3246,14 @@
5.525 MOV_r32_r32( R_ECX, R_EAX );
5.526 load_spreg( R_EDX, R_FPSCR );
5.527 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.528 - JNE_rel8(25, doublesize);
5.529 + JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);
5.530 ADD_imm8s_r32( 4, R_EAX );
5.531 store_reg( R_EAX, Rm );
5.532 MEM_READ_LONG( R_ECX, R_EAX );
5.533 load_fr_bank( R_EDX );
5.534 store_fr( R_EDX, R_EAX, FRn );
5.535 if( FRn&1 ) {
5.536 - JMP_rel8(54, end);
5.537 + JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
5.538 JMP_TARGET(doublesize);
5.539 ADD_imm8s_r32( 8, R_EAX );
5.540 store_reg(R_EAX, Rm);
5.541 @@ -3107,7 +3264,7 @@
5.542 store_fr( R_EDX, R_ECX, FRn|0x01 );
5.543 JMP_TARGET(end);
5.544 } else {
5.545 - JMP_rel8(42, end);
5.546 + JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
5.547 ADD_imm8s_r32( 8, R_EAX );
5.548 store_reg(R_EAX, Rm);
5.549 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
5.550 @@ -3128,12 +3285,12 @@
5.551 check_walign32( R_ECX );
5.552 load_spreg( R_EDX, R_FPSCR );
5.553 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.554 - JNE_rel8(20, doublesize);
5.555 + JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
5.556 load_fr_bank( R_EDX );
5.557 load_fr( R_EDX, R_EAX, FRm );
5.558 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
5.559 if( FRm&1 ) {
5.560 - JMP_rel8( 48, end );
5.561 + JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
5.562 JMP_TARGET(doublesize);
5.563 load_xf_bank( R_EDX );
5.564 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.565 @@ -3141,7 +3298,7 @@
5.566 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
5.567 JMP_TARGET(end);
5.568 } else {
5.569 - JMP_rel8( 39, end );
5.570 + JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
5.571 JMP_TARGET(doublesize);
5.572 load_fr_bank( R_EDX );
5.573 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.574 @@ -3161,14 +3318,14 @@
5.575 check_walign32( R_ECX );
5.576 load_spreg( R_EDX, R_FPSCR );
5.577 TEST_imm32_r32( FPSCR_SZ, R_EDX );
5.578 - JNE_rel8(26, doublesize);
5.579 + JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);
5.580 load_fr_bank( R_EDX );
5.581 load_fr( R_EDX, R_EAX, FRm );
5.582 ADD_imm8s_r32(-4,R_ECX);
5.583 store_reg( R_ECX, Rn );
5.584 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
5.585 if( FRm&1 ) {
5.586 - JMP_rel8( 54, end );
5.587 + JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
5.588 JMP_TARGET(doublesize);
5.589 load_xf_bank( R_EDX );
5.590 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.591 @@ -3178,7 +3335,7 @@
5.592 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
5.593 JMP_TARGET(end);
5.594 } else {
5.595 - JMP_rel8( 45, end );
5.596 + JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
5.597 JMP_TARGET(doublesize);
5.598 load_fr_bank( R_EDX );
5.599 load_fr( R_EDX, R_EAX, FRm&0x0E );
5.600 @@ -3493,7 +3650,7 @@
5.601 check_fpuen();
5.602 load_spreg( R_ECX, R_FPSCR );
5.603 TEST_imm32_r32( FPSCR_PR, R_ECX );
5.604 - JNE_rel8( 21, doubleprec );
5.605 + JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
5.606 load_fr_bank( R_ECX );
5.607 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
5.608 load_spreg( R_EDX, R_FPUL );
5.609 @@ -3510,7 +3667,7 @@
5.610 check_fpuen();
5.611 load_spreg( R_ECX, R_FPSCR );
5.612 TEST_imm32_r32( FPSCR_PR, R_ECX );
5.613 - JNE_rel8( 30, doubleprec );
5.614 + JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
5.615 load_fr_bank( R_EDX ); // 3
5.616 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
5.617 load_xf_bank( R_ECX ); // 12
6.1 --- a/src/sh4/sh4x86.in Sat Nov 17 06:04:19 2007 +0000
6.2 +++ b/src/sh4/sh4x86.in Sun Nov 18 11:12:44 2007 +0000
6.3 @@ -152,6 +152,17 @@
6.4 }
6.5
6.6 /**
6.7 + * Load an immediate 64-bit quantity (note: x86-64 only)
6.8 + */
6.9 +static inline void load_imm64( int x86reg, uint32_t value ) {
6.10 + /* mov #value, reg */
6.11 + REXW();
6.12 + OP(0xB8 + x86reg);
6.13 + OP64(value);
6.14 +}
6.15 +
6.16 +
6.17 +/**
6.18 * Emit an instruction to store an SH4 reg (RN)
6.19 */
6.20 void static inline store_reg( int x86reg, int sh4reg ) {
6.21 @@ -253,16 +264,161 @@
6.22 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
6.23 }
6.24
6.25 +#if SH4_TRANSLATOR == TARGET_X86_64
6.26 +/* X86-64 has different calling conventions... */
6.27 +/**
6.28 + * Note: clobbers EAX to make the indirect call - this isn't usually
6.29 + * a problem since the callee will usually clobber it anyway.
6.30 + * Size: 12 bytes
6.31 + */
6.32 +#define CALL_FUNC0_SIZE 12
6.33 +static inline void call_func0( void *ptr )
6.34 +{
6.35 + load_imm64(R_EAX, (uint64_t)ptr);
6.36 + CALL_r32(R_EAX);
6.37 +}
6.38 +
6.39 +#define CALL_FUNC1_SIZE 14
6.40 +static inline void call_func1( void *ptr, int arg1 )
6.41 +{
6.42 + MOV_r32_r32(arg1, R_EDI);
6.43 + call_func0(ptr);
6.44 +}
6.45 +
6.46 +#define CALL_FUNC2_SIZE 16
6.47 +static inline void call_func2( void *ptr, int arg1, int arg2 )
6.48 +{
6.49 + MOV_r32_r32(arg1, R_EDI);
6.50 + MOV_r32_r32(arg2, R_ESI);
6.51 + call_func0(ptr);
6.52 +}
6.53 +
6.54 +#define MEM_WRITE_DOUBLE_SIZE 39
6.55 +/**
6.56 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
6.57 + * the second in arg2b
6.58 + */
6.59 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
6.60 +{
6.61 +/*
6.62 + MOV_r32_r32( addr, R_EDI );
6.63 + MOV_r32_r32( arg2b, R_ESI );
6.64 + REXW(); SHL_imm8_r32( 32, R_ESI );
6.65 + REXW(); MOVZX_r16_r32( arg2a, arg2a );
6.66 + REXW(); OR_r32_r32( arg2a, R_ESI );
6.67 + call_func0(sh4_write_quad);
6.68 +*/
6.69 + PUSH_r32(arg2b);
6.70 + PUSH_r32(addr);
6.71 + call_func2(sh4_write_long, addr, arg2a);
6.72 + POP_r32(addr);
6.73 + POP_r32(arg2b);
6.74 + ADD_imm8s_r32(4, addr);
6.75 + call_func2(sh4_write_long, addr, arg2b);
6.76 +}
6.77 +
6.78 +#define MEM_READ_DOUBLE_SIZE 35
6.79 +/**
6.80 + * Read a double (64-bit) value from memory, writing the first word into arg2a
6.81 + * and the second into arg2b. The addr must not be in EAX
6.82 + */
6.83 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
6.84 +{
6.85 +/*
6.86 + MOV_r32_r32( addr, R_EDI );
6.87 + call_func0(sh4_read_quad);
6.88 + REXW(); MOV_r32_r32( R_EAX, arg2a );
6.89 + REXW(); MOV_r32_r32( R_EAX, arg2b );
6.90 + REXW(); SHR_imm8_r32( 32, arg2b );
6.91 +*/
6.92 + PUSH_r32(addr);
6.93 + call_func1(sh4_read_long, addr);
6.94 + POP_r32(R_EDI);
6.95 + PUSH_r32(R_EAX);
6.96 + ADD_imm8s_r32(4, R_EDI);
6.97 + call_func0(sh4_read_long);
6.98 + MOV_r32_r32(R_EAX, arg2b);
6.99 + POP_r32(arg2a);
6.100 +}
6.101 +
6.102 +#define EXIT_BLOCK_SIZE 35
6.103 +/**
6.104 + * Exit the block to an absolute PC
6.105 + */
6.106 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
6.107 +{
6.108 + load_imm32( R_ECX, pc ); // 5
6.109 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
6.110 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
6.111 + REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
6.112 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
6.113 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
6.114 + POP_r32(R_EBP);
6.115 + RET();
6.116 +}
6.117 +
6.118 +
6.119 +/**
6.120 + * Write the block trailer (exception handling block)
6.121 + */
6.122 +void sh4_translate_end_block( sh4addr_t pc ) {
6.123 + if( sh4_x86.branch_taken == FALSE ) {
6.124 + // Didn't exit unconditionally already, so write the termination here
6.125 + exit_block( pc, pc );
6.126 + }
6.127 + if( sh4_x86.backpatch_posn != 0 ) {
6.128 + uint8_t *end_ptr = xlat_output;
6.129 + // Exception termination. Jump block for various exception codes:
6.130 + load_imm32( R_EDI, EXC_DATA_ADDR_READ );
6.131 + JMP_rel8( 33, target1 );
6.132 + load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
6.133 + JMP_rel8( 26, target2 );
6.134 + load_imm32( R_EDI, EXC_ILLEGAL );
6.135 + JMP_rel8( 19, target3 );
6.136 + load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
6.137 + JMP_rel8( 12, target4 );
6.138 + load_imm32( R_EDI, EXC_FPU_DISABLED );
6.139 + JMP_rel8( 5, target5 );
6.140 + load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
6.141 + // target
6.142 + JMP_TARGET(target1);
6.143 + JMP_TARGET(target2);
6.144 + JMP_TARGET(target3);
6.145 + JMP_TARGET(target4);
6.146 + JMP_TARGET(target5);
6.147 + // Raise exception
6.148 + load_spreg( R_ECX, REG_OFFSET(pc) );
6.149 + ADD_r32_r32( R_EDX, R_ECX );
6.150 + ADD_r32_r32( R_EDX, R_ECX );
6.151 + store_spreg( R_ECX, REG_OFFSET(pc) );
6.152 + MOV_moff32_EAX( &sh4_cpu_period );
6.153 + MUL_r32( R_EDX );
6.154 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
6.155 +
6.156 + call_func0( sh4_raise_exception );
6.157 + load_spreg( R_EAX, REG_OFFSET(pc) );
6.158 + call_func1(xlat_get_code,R_EAX);
6.159 + POP_r32(R_EBP);
6.160 + RET();
6.161 +
6.162 + sh4_x86_do_backpatch( end_ptr );
6.163 + }
6.164 +}
6.165 +
6.166 +#else /* SH4_TRANSLATOR == TARGET_X86 */
6.167 +
6.168 /**
6.169 * Note: clobbers EAX to make the indirect call - this isn't usually
6.170 * a problem since the callee will usually clobber it anyway.
6.171 */
6.172 +#define CALL_FUNC0_SIZE 7
6.173 static inline void call_func0( void *ptr )
6.174 {
6.175 load_imm32(R_EAX, (uint32_t)ptr);
6.176 CALL_r32(R_EAX);
6.177 }
6.178
6.179 +#define CALL_FUNC1_SIZE 11
6.180 static inline void call_func1( void *ptr, int arg1 )
6.181 {
6.182 PUSH_r32(arg1);
6.183 @@ -270,6 +426,7 @@
6.184 ADD_imm8s_r32( 4, R_ESP );
6.185 }
6.186
6.187 +#define CALL_FUNC2_SIZE 12
6.188 static inline void call_func2( void *ptr, int arg1, int arg2 )
6.189 {
6.190 PUSH_r32(arg2);
6.191 @@ -283,6 +440,7 @@
6.192 * the second in arg2b
6.193 * NB: 30 bytes
6.194 */
6.195 +#define MEM_WRITE_DOUBLE_SIZE 30
6.196 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
6.197 {
6.198 ADD_imm8s_r32( 4, addr );
6.199 @@ -302,6 +460,7 @@
6.200 * and the second into arg2b. The addr must not be in EAX
6.201 * NB: 27 bytes
6.202 */
6.203 +#define MEM_READ_DOUBLE_SIZE 27
6.204 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
6.205 {
6.206 PUSH_r32(addr);
6.207 @@ -316,6 +475,71 @@
6.208 POP_r32(arg2a);
6.209 }
6.210
6.211 +#define EXIT_BLOCK_SIZE 29
6.212 +/**
6.213 + * Exit the block to an absolute PC
6.214 + */
6.215 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
6.216 +{
6.217 + load_imm32( R_ECX, pc ); // 5
6.218 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
6.219 + MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
6.220 + AND_imm8s_r32( 0xFC, R_EAX ); // 3
6.221 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
6.222 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
6.223 + POP_r32(R_EBP);
6.224 + RET();
6.225 +}
6.226 +
6.227 +/**
6.228 + * Write the block trailer (exception handling block)
6.229 + */
6.230 +void sh4_translate_end_block( sh4addr_t pc ) {
6.231 + if( sh4_x86.branch_taken == FALSE ) {
6.232 + // Didn't exit unconditionally already, so write the termination here
6.233 + exit_block( pc, pc );
6.234 + }
6.235 + if( sh4_x86.backpatch_posn != 0 ) {
6.236 + uint8_t *end_ptr = xlat_output;
6.237 + // Exception termination. Jump block for various exception codes:
6.238 + PUSH_imm32( EXC_DATA_ADDR_READ );
6.239 + JMP_rel8( 33, target1 );
6.240 + PUSH_imm32( EXC_DATA_ADDR_WRITE );
6.241 + JMP_rel8( 26, target2 );
6.242 + PUSH_imm32( EXC_ILLEGAL );
6.243 + JMP_rel8( 19, target3 );
6.244 + PUSH_imm32( EXC_SLOT_ILLEGAL );
6.245 + JMP_rel8( 12, target4 );
6.246 + PUSH_imm32( EXC_FPU_DISABLED );
6.247 + JMP_rel8( 5, target5 );
6.248 + PUSH_imm32( EXC_SLOT_FPU_DISABLED );
6.249 + // target
6.250 + JMP_TARGET(target1);
6.251 + JMP_TARGET(target2);
6.252 + JMP_TARGET(target3);
6.253 + JMP_TARGET(target4);
6.254 + JMP_TARGET(target5);
6.255 + // Raise exception
6.256 + load_spreg( R_ECX, REG_OFFSET(pc) );
6.257 + ADD_r32_r32( R_EDX, R_ECX );
6.258 + ADD_r32_r32( R_EDX, R_ECX );
6.259 + store_spreg( R_ECX, REG_OFFSET(pc) );
6.260 + MOV_moff32_EAX( &sh4_cpu_period );
6.261 + MUL_r32( R_EDX );
6.262 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
6.263 +
6.264 + call_func0( sh4_raise_exception );
6.265 + ADD_imm8s_r32( 4, R_ESP );
6.266 + load_spreg( R_EAX, REG_OFFSET(pc) );
6.267 + call_func1(xlat_get_code,R_EAX);
6.268 + POP_r32(R_EBP);
6.269 + RET();
6.270 +
6.271 + sh4_x86_do_backpatch( end_ptr );
6.272 + }
6.273 +}
6.274 +#endif
6.275 +
6.276 /* Exception checks - Note that all exception checks will clobber EAX */
6.277 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
6.278
6.279 @@ -431,22 +655,6 @@
6.280 }
6.281
6.282 /**
6.283 - * Exit the block to an absolute PC
6.284 - * Bytes: 29
6.285 - */
6.286 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
6.287 -{
6.288 - load_imm32( R_ECX, pc ); // 5
6.289 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
6.290 - MOV_moff32_EAX( (uint32_t)xlat_get_lut_entry(pc) ); // 5
6.291 - AND_imm8s_r32( 0xFC, R_EAX ); // 3
6.292 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
6.293 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
6.294 - POP_r32(R_EBP);
6.295 - RET();
6.296 -}
6.297 -
6.298 -/**
6.299 * Exit the block with sh4r.pc already written
6.300 * Bytes: 15
6.301 */
6.302 @@ -460,57 +668,6 @@
6.303 RET();
6.304 }
6.305
6.306 -/**
6.307 - * Write the block trailer (exception handling block)
6.308 - */
6.309 -void sh4_translate_end_block( sh4addr_t pc ) {
6.310 - if( sh4_x86.branch_taken == FALSE ) {
6.311 - // Didn't exit unconditionally already, so write the termination here
6.312 - exit_block( pc, pc );
6.313 - }
6.314 - if( sh4_x86.backpatch_posn != 0 ) {
6.315 - uint8_t *end_ptr = xlat_output;
6.316 - // Exception termination. Jump block for various exception codes:
6.317 - PUSH_imm32( EXC_DATA_ADDR_READ );
6.318 - JMP_rel8( 33, target1 );
6.319 - PUSH_imm32( EXC_DATA_ADDR_WRITE );
6.320 - JMP_rel8( 26, target2 );
6.321 - PUSH_imm32( EXC_ILLEGAL );
6.322 - JMP_rel8( 19, target3 );
6.323 - PUSH_imm32( EXC_SLOT_ILLEGAL );
6.324 - JMP_rel8( 12, target4 );
6.325 - PUSH_imm32( EXC_FPU_DISABLED );
6.326 - JMP_rel8( 5, target5 );
6.327 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );
6.328 - // target
6.329 - JMP_TARGET(target1);
6.330 - JMP_TARGET(target2);
6.331 - JMP_TARGET(target3);
6.332 - JMP_TARGET(target4);
6.333 - JMP_TARGET(target5);
6.334 - // Raise exception
6.335 - load_spreg( R_ECX, REG_OFFSET(pc) );
6.336 - ADD_r32_r32( R_EDX, R_ECX );
6.337 - ADD_r32_r32( R_EDX, R_ECX );
6.338 - store_spreg( R_ECX, REG_OFFSET(pc) );
6.339 - MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
6.340 - MUL_r32( R_EDX );
6.341 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
6.342 -
6.343 - load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
6.344 - CALL_r32( R_EAX ); // 2
6.345 - ADD_imm8s_r32( 4, R_ESP );
6.346 - load_spreg( R_EAX, REG_OFFSET(pc) );
6.347 - call_func1(xlat_get_code,R_EAX);
6.348 - POP_r32(R_EBP);
6.349 - RET();
6.350 -
6.351 - sh4_x86_do_backpatch( end_ptr );
6.352 - }
6.353 -
6.354 -}
6.355 -
6.356 -
6.357 extern uint16_t *sh4_icache;
6.358 extern uint32_t sh4_icache_addr;
6.359
6.360 @@ -531,7 +688,7 @@
6.361 ir = sh4_icache[(pc&0xFFF)>>1];
6.362 } else {
6.363 sh4_icache = (uint16_t *)mem_get_page(pc);
6.364 - if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
6.365 + if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
6.366 /* If someone's actually been so daft as to try to execute out of an IO
6.367 * region, fallback on the full-blown memory read
6.368 */
6.369 @@ -595,7 +752,7 @@
6.370 load_spreg( R_ECX, R_GBR );
6.371 ADD_r32_r32( R_EAX, R_ECX );
6.372 PUSH_r32(R_ECX);
6.373 - call_func0(sh4_read_byte);
6.374 + MEM_READ_BYTE( R_ECX, R_EAX );
6.375 POP_r32(R_ECX);
6.376 AND_imm32_r32(imm, R_EAX );
6.377 MEM_WRITE_BYTE( R_ECX, R_EAX );
6.378 @@ -777,7 +934,7 @@
6.379
6.380 load_spreg( R_ECX, R_S );
6.381 TEST_r32_r32(R_ECX, R_ECX);
6.382 - JE_rel8( 7, nosat );
6.383 + JE_rel8( CALL_FUNC0_SIZE, nosat );
6.384 call_func0( signsat48 );
6.385 JMP_TARGET( nosat );
6.386 sh4_x86.tstate = TSTATE_NONE;
6.387 @@ -887,7 +1044,7 @@
6.388 load_spreg( R_ECX, R_GBR );
6.389 ADD_r32_r32( R_EAX, R_ECX );
6.390 PUSH_r32(R_ECX);
6.391 - call_func0(sh4_read_byte);
6.392 + MEM_READ_BYTE( R_ECX, R_EAX );
6.393 POP_r32(R_ECX);
6.394 OR_imm32_r32(imm, R_EAX );
6.395 MEM_WRITE_BYTE( R_ECX, R_EAX );
6.396 @@ -1130,7 +1287,7 @@
6.397 load_spreg( R_ECX, R_GBR );
6.398 ADD_r32_r32( R_EAX, R_ECX );
6.399 PUSH_r32(R_ECX);
6.400 - call_func0(sh4_read_byte);
6.401 + MEM_READ_BYTE(R_ECX, R_EAX);
6.402 POP_r32(R_ECX);
6.403 XOR_imm32_r32( imm, R_EAX );
6.404 MEM_WRITE_BYTE( R_ECX, R_EAX );
6.405 @@ -1319,7 +1476,7 @@
6.406 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
6.407 sh4ptr_t ptr = mem_get_region(target);
6.408 if( ptr != NULL ) {
6.409 - MOV_moff32_EAX( (uint32_t)ptr );
6.410 + MOV_moff32_EAX( ptr );
6.411 } else {
6.412 load_imm32( R_ECX, target );
6.413 MEM_READ_LONG( R_ECX, R_EAX );
6.414 @@ -1462,7 +1619,7 @@
6.415 if( sh4_x86.in_delay_slot ) {
6.416 SLOTILLEGAL();
6.417 } else {
6.418 - JT_rel8( 29, nottaken );
6.419 + JT_rel8( EXIT_BLOCK_SIZE, nottaken );
6.420 exit_block( disp + pc + 4, pc+2 );
6.421 JMP_TARGET(nottaken);
6.422 return 2;
6.423 @@ -1545,7 +1702,7 @@
6.424 if( sh4_x86.in_delay_slot ) {
6.425 SLOTILLEGAL();
6.426 } else {
6.427 - JF_rel8( 29, nottaken );
6.428 + JF_rel8( EXIT_BLOCK_SIZE, nottaken );
6.429 exit_block( disp + pc + 4, pc+2 );
6.430 JMP_TARGET(nottaken);
6.431 return 2;
6.432 @@ -1633,8 +1790,8 @@
6.433 if( sh4_x86.in_delay_slot ) {
6.434 SLOTILLEGAL();
6.435 } else {
6.436 - PUSH_imm32( imm );
6.437 - call_func0( sh4_raise_trap );
6.438 + load_imm32( R_EAX, imm );
6.439 + call_func1( sh4_raise_trap, R_EAX );
6.440 ADD_imm8s_r32( 4, R_ESP );
6.441 sh4_x86.tstate = TSTATE_NONE;
6.442 exit_block_pcset(pc);
6.443 @@ -1737,12 +1894,12 @@
6.444 check_walign32( R_ECX );
6.445 load_spreg( R_EDX, R_FPSCR );
6.446 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.447 - JNE_rel8(20, doublesize);
6.448 + JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
6.449 load_fr_bank( R_EDX );
6.450 load_fr( R_EDX, R_EAX, FRm );
6.451 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
6.452 if( FRm&1 ) {
6.453 - JMP_rel8( 48, end );
6.454 + JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
6.455 JMP_TARGET(doublesize);
6.456 load_xf_bank( R_EDX );
6.457 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.458 @@ -1750,7 +1907,7 @@
6.459 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
6.460 JMP_TARGET(end);
6.461 } else {
6.462 - JMP_rel8( 39, end );
6.463 + JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
6.464 JMP_TARGET(doublesize);
6.465 load_fr_bank( R_EDX );
6.466 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.467 @@ -1767,12 +1924,12 @@
6.468 check_ralign32( R_ECX );
6.469 load_spreg( R_EDX, R_FPSCR );
6.470 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.471 - JNE_rel8(19, doublesize);
6.472 + JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
6.473 MEM_READ_LONG( R_ECX, R_EAX );
6.474 load_fr_bank( R_EDX );
6.475 store_fr( R_EDX, R_EAX, FRn );
6.476 if( FRn&1 ) {
6.477 - JMP_rel8(48, end);
6.478 + JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
6.479 JMP_TARGET(doublesize);
6.480 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
6.481 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
6.482 @@ -1781,7 +1938,7 @@
6.483 store_fr( R_EDX, R_ECX, FRn|0x01 );
6.484 JMP_TARGET(end);
6.485 } else {
6.486 - JMP_rel8(36, end);
6.487 + JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
6.488 JMP_TARGET(doublesize);
6.489 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
6.490 load_fr_bank( R_EDX );
6.491 @@ -1798,14 +1955,14 @@
6.492 check_walign32( R_ECX );
6.493 load_spreg( R_EDX, R_FPSCR );
6.494 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.495 - JNE_rel8(26, doublesize);
6.496 + JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);
6.497 load_fr_bank( R_EDX );
6.498 load_fr( R_EDX, R_EAX, FRm );
6.499 ADD_imm8s_r32(-4,R_ECX);
6.500 store_reg( R_ECX, Rn );
6.501 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
6.502 if( FRm&1 ) {
6.503 - JMP_rel8( 54, end );
6.504 + JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
6.505 JMP_TARGET(doublesize);
6.506 load_xf_bank( R_EDX );
6.507 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.508 @@ -1815,7 +1972,7 @@
6.509 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
6.510 JMP_TARGET(end);
6.511 } else {
6.512 - JMP_rel8( 45, end );
6.513 + JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
6.514 JMP_TARGET(doublesize);
6.515 load_fr_bank( R_EDX );
6.516 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.517 @@ -1835,14 +1992,14 @@
6.518 MOV_r32_r32( R_ECX, R_EAX );
6.519 load_spreg( R_EDX, R_FPSCR );
6.520 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.521 - JNE_rel8(25, doublesize);
6.522 + JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);
6.523 ADD_imm8s_r32( 4, R_EAX );
6.524 store_reg( R_EAX, Rm );
6.525 MEM_READ_LONG( R_ECX, R_EAX );
6.526 load_fr_bank( R_EDX );
6.527 store_fr( R_EDX, R_EAX, FRn );
6.528 if( FRn&1 ) {
6.529 - JMP_rel8(54, end);
6.530 + JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
6.531 JMP_TARGET(doublesize);
6.532 ADD_imm8s_r32( 8, R_EAX );
6.533 store_reg(R_EAX, Rm);
6.534 @@ -1853,7 +2010,7 @@
6.535 store_fr( R_EDX, R_ECX, FRn|0x01 );
6.536 JMP_TARGET(end);
6.537 } else {
6.538 - JMP_rel8(42, end);
6.539 + JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
6.540 ADD_imm8s_r32( 8, R_EAX );
6.541 store_reg(R_EAX, Rm);
6.542 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
6.543 @@ -1872,12 +2029,12 @@
6.544 check_walign32( R_ECX );
6.545 load_spreg( R_EDX, R_FPSCR );
6.546 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.547 - JNE_rel8(20, doublesize);
6.548 + JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
6.549 load_fr_bank( R_EDX );
6.550 load_fr( R_EDX, R_EAX, FRm );
6.551 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
6.552 if( FRm&1 ) {
6.553 - JMP_rel8( 48, end );
6.554 + JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
6.555 JMP_TARGET(doublesize);
6.556 load_xf_bank( R_EDX );
6.557 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.558 @@ -1885,7 +2042,7 @@
6.559 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
6.560 JMP_TARGET(end);
6.561 } else {
6.562 - JMP_rel8( 39, end );
6.563 + JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
6.564 JMP_TARGET(doublesize);
6.565 load_fr_bank( R_EDX );
6.566 load_fr( R_EDX, R_EAX, FRm&0x0E );
6.567 @@ -1903,12 +2060,12 @@
6.568 check_ralign32( R_ECX );
6.569 load_spreg( R_EDX, R_FPSCR );
6.570 TEST_imm32_r32( FPSCR_SZ, R_EDX );
6.571 - JNE_rel8(19, doublesize);
6.572 + JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
6.573 MEM_READ_LONG( R_ECX, R_EAX );
6.574 load_fr_bank( R_EDX );
6.575 store_fr( R_EDX, R_EAX, FRn );
6.576 if( FRn&1 ) {
6.577 - JMP_rel8(48, end);
6.578 + JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
6.579 JMP_TARGET(doublesize);
6.580 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
6.581 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
6.582 @@ -1917,7 +2074,7 @@
6.583 store_fr( R_EDX, R_ECX, FRn|0x01 );
6.584 JMP_TARGET(end);
6.585 } else {
6.586 - JMP_rel8(36, end);
6.587 + JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
6.588 JMP_TARGET(doublesize);
6.589 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
6.590 load_fr_bank( R_EDX );
6.591 @@ -2244,7 +2401,7 @@
6.592 check_fpuen();
6.593 load_spreg( R_ECX, R_FPSCR );
6.594 TEST_imm32_r32( FPSCR_PR, R_ECX );
6.595 - JNE_rel8( 21, doubleprec );
6.596 + JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
6.597 load_fr_bank( R_ECX );
6.598 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
6.599 load_spreg( R_EDX, R_FPUL );
6.600 @@ -2282,7 +2439,7 @@
6.601 check_fpuen();
6.602 load_spreg( R_ECX, R_FPSCR );
6.603 TEST_imm32_r32( FPSCR_PR, R_ECX );
6.604 - JNE_rel8( 30, doubleprec );
6.605 + JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
6.606 load_fr_bank( R_EDX ); // 3
6.607 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
6.608 load_xf_bank( R_ECX ); // 12
6.609 @@ -2548,7 +2705,7 @@
6.610 PUSH_r32( R_EAX );
6.611 AND_imm32_r32( 0xFC000000, R_EAX );
6.612 CMP_imm32_r32( 0xE0000000, R_EAX );
6.613 - JNE_rel8(7, end);
6.614 + JNE_rel8(CALL_FUNC0_SIZE, end);
6.615 call_func0( sh4_flush_store_queue );
6.616 JMP_TARGET(end);
6.617 ADD_imm8s_r32( 4, R_ESP );
7.1 --- a/src/sh4/x86op.h Sat Nov 17 06:04:19 2007 +0000
7.2 +++ b/src/sh4/x86op.h Sun Nov 18 11:12:44 2007 +0000
7.3 @@ -52,6 +52,12 @@
7.4
7.5 #define OP(x) *xlat_output++ = (x)
7.6 #define OP32(x) *((uint32_t *)xlat_output) = (x); xlat_output+=4
7.7 +#define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=8
7.8 +#if SH4_TRANSLATOR == TARGET_X86_64
7.9 +#define OPPTR(x) OP64((uint64_t)(x))
7.10 +#else
7.11 +#define OPPTR(x) OP32((uint32_t)(x))
7.12 +#endif
7.13
7.14 /* Offset of a reg relative to the sh4r structure */
7.15 #define REG_OFFSET(reg) (((char *)&sh4r.reg) - ((char *)&sh4r))
7.16 @@ -90,6 +96,8 @@
7.17
7.18 #define MODRM_r32_sh4r(r1,disp) if(disp>127){ MODRM_r32_ebp32(r1,disp);}else{ MODRM_r32_ebp8(r1,(unsigned char)disp); }
7.19
7.20 +#define REXW() OP(0x48)
7.21 +
7.22 /* Major opcodes */
7.23 #define ADD_sh4r_r32(disp,r1) OP(0x03); MODRM_r32_sh4r(r1,disp)
7.24 #define ADD_r32_sh4r(r1,disp) OP(0x01); MODRM_r32_sh4r(r1,disp)
7.25 @@ -118,7 +126,7 @@
7.26 #define JMP_rel8(rel, label) OP(0xEB); OP(rel); MARK_JMP(rel,label)
7.27 #define MOV_r32_r32(r1,r2) OP(0x89); MODRM_r32_rm32(r1,r2)
7.28 #define MOV_r32_sh4r(r1,disp) OP(0x89); MODRM_r32_sh4r(r1,disp)
7.29 -#define MOV_moff32_EAX(off) OP(0xA1); OP32(off)
7.30 +#define MOV_moff32_EAX(off) OP(0xA1); OPPTR(off)
7.31 #define MOV_sh4r_r32(disp, r1) OP(0x8B); MODRM_r32_sh4r(r1,disp)
7.32 #define MOV_r32ind_r32(r1,r2) OP(0x8B); OP(0 + (r2<<3) + r1 )
7.33 #define MOVSX_r8_r32(r1,r2) OP(0x0F); OP(0xBE); MODRM_rm32_r32(r1,r2)
8.1 --- a/src/sh4/xltcache.c Sat Nov 17 06:04:19 2007 +0000
8.2 +++ b/src/sh4/xltcache.c Sun Nov 18 11:12:44 2007 +0000
8.3 @@ -202,7 +202,7 @@
8.4 void *result = NULL;
8.5 void **page = xlat_lut[XLAT_LUT_PAGE(address)];
8.6 if( page != NULL ) {
8.7 - result = (void *)(((uint32_t)(page[XLAT_LUT_ENTRY(address)])) & 0xFFFFFFFC);
8.8 + result = (void *)(((uintptr_t)(page[XLAT_LUT_ENTRY(address)])) & (~((uintptr_t)0x03)));
8.9 }
8.10 return result;
8.11 }
9.1 --- a/src/x86dasm/x86dasm.c Sat Nov 17 06:04:19 2007 +0000
9.2 +++ b/src/x86dasm/x86dasm.c Sun Nov 18 11:12:44 2007 +0000
9.3 @@ -23,6 +23,7 @@
9.4 #include "bfd.h"
9.5 #include "dis-asm.h"
9.6 #include "sh4/sh4core.h"
9.7 +#include "sh4/sh4trans.h"
9.8
9.9 extern const struct reg_desc_struct sh4_reg_map[];
9.10 const struct cpu_desc_struct x86_cpu_desc =
9.11 @@ -49,7 +50,7 @@
9.12
9.13 void x86_disasm_block(FILE *out, void *start, uint32_t len)
9.14 {
9.15 - uint32_t start_addr = (uint32_t)start;
9.16 + uintptr_t start_addr = (uintptr_t)start;
9.17 uint32_t pc;
9.18 x86_disasm_init( start, start_addr, len );
9.19 for( pc = start_addr; pc < start_addr + len; ) {
9.20 @@ -61,11 +62,15 @@
9.21 }
9.22 }
9.23
9.24 -void x86_disasm_init(unsigned char *buf, uint32_t vma, int buflen)
9.25 +void x86_disasm_init(unsigned char *buf, uintptr_t vma, int buflen)
9.26 {
9.27 init_disassemble_info( &x86_disasm_info, NULL, x86_disasm_output );
9.28 x86_disasm_info.arch = bfd_arch_i386;
9.29 +#if SH4_TRANSLATOR == TARGET_X86_64
9.30 + x86_disasm_info.mach = bfd_mach_x86_64_intel_syntax;
9.31 +#else
9.32 x86_disasm_info.mach = bfd_mach_i386_i386_intel_syntax;
9.33 +#endif
9.34 x86_disasm_info.endian = BFD_ENDIAN_LITTLE;
9.35 x86_disasm_info.buffer = buf;
9.36 x86_disasm_info.buffer_vma = vma;
9.37 @@ -83,7 +88,7 @@
9.38 {
9.39 int i;
9.40 for( i=0; i<x86_num_symbols; i++ ) {
9.41 - if( x86_symtab[i].ptr == (void *)(uint32_t)memaddr ) {
9.42 + if( x86_symtab[i].ptr == (void *)(uintptr_t)memaddr ) {
9.43 return x86_symtab[i].name;
9.44 }
9.45 }
9.46 @@ -99,7 +104,7 @@
9.47 }
9.48 }
9.49
9.50 -uint32_t x86_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
9.51 +uint32_t x86_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode )
9.52 {
9.53 int count, i;
9.54
10.1 --- a/src/x86dasm/x86dasm.h Sat Nov 17 06:04:19 2007 +0000
10.2 +++ b/src/x86dasm/x86dasm.h Sun Nov 18 11:12:44 2007 +0000
10.3 @@ -29,5 +29,5 @@
10.4
10.5 void x86_disasm_block( FILE *out, void *block, uint32_t len );
10.6 void x86_set_symtab( x86_symbol *symtab, int num_symbols );
10.7 -void x86_disasm_init(unsigned char *buf, uint32_t vma, int buflen);
10.8 -uint32_t x86_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode );
10.9 +void x86_disasm_init(unsigned char *buf, uintptr_t vma, int buflen);
10.10 +uint32_t x86_disasm_instruction( uintptr_t pc, char *buf, int len, char *opcode );
.