1.1 --- a/src/sh4/sh4x86.c Fri Sep 28 07:27:20 2007 +0000
1.2 +++ b/src/sh4/sh4x86.c Mon Oct 01 11:51:25 2007 +0000
1.5 - * $Id: sh4x86.c,v 1.15 2007-09-28 07:27:20 nkeynes Exp $
1.6 + * $Id: sh4x86.c,v 1.16 2007-09-29 05:33:02 nkeynes Exp $
1.8 * SH4 => x86 translation. This version does no real optimization, it just
1.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
1.11 gboolean in_delay_slot;
1.12 gboolean priv_checked; /* true if we've already checked the cpu mode. */
1.13 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
1.14 + gboolean branch_taken; /* true if we branched unconditionally */
1.15 uint32_t block_start_pc;
1.17 /* Allocated memory for the (block-wide) back-patch list */
1.19 sh4_x86.in_delay_slot = FALSE;
1.20 sh4_x86.priv_checked = FALSE;
1.21 sh4_x86.fpuen_checked = FALSE;
1.22 + sh4_x86.branch_taken = FALSE;
1.23 sh4_x86.backpatch_posn = 0;
1.24 sh4_x86.block_start_pc = pc;
1.26 @@ -410,6 +412,10 @@
1.27 * Write the block trailer (exception handling block)
1.29 void sh4_translate_end_block( sh4addr_t pc ) {
1.30 + if( sh4_x86.branch_taken == FALSE ) {
1.31 + // Didn't exit unconditionally already, so write the termination here
1.32 + exit_block( pc, pc );
1.34 if( sh4_x86.backpatch_posn != 0 ) {
1.35 uint8_t *end_ptr = xlat_output;
1.36 // Exception termination. Jump block for various exception codes:
1.38 sh4_x86.in_delay_slot = TRUE;
1.39 sh4_x86_translate_instruction( pc + 2 );
1.40 exit_block_pcset(pc+2);
1.41 + sh4_x86.branch_taken = TRUE;
1.46 sh4_x86.in_delay_slot = TRUE;
1.47 sh4_x86_translate_instruction( pc + 2 );
1.48 exit_block_pcset(pc+2);
1.49 + sh4_x86.branch_taken = TRUE;
1.54 sh4_x86.in_delay_slot = TRUE;
1.55 sh4_x86_translate_instruction(pc+2);
1.56 exit_block_pcset(pc+2);
1.57 + sh4_x86.branch_taken = TRUE;
1.62 call_func0( sh4_sleep );
1.63 sh4_x86.in_delay_slot = FALSE;
1.65 - exit_block(pc+2, pc+2);
1.70 sh4_x86.fpuen_checked = FALSE;
1.71 sh4_x86_translate_instruction(pc+2);
1.72 exit_block_pcset(pc+2);
1.73 + sh4_x86.branch_taken = TRUE;
1.77 @@ -1854,6 +1863,7 @@
1.78 sh4_x86.in_delay_slot = TRUE;
1.79 sh4_x86_translate_instruction(pc+2);
1.80 exit_block_pcset(pc+2);
1.81 + sh4_x86.branch_taken = TRUE;
1.85 @@ -1881,6 +1891,7 @@
1.86 sh4_x86.in_delay_slot = TRUE;
1.87 sh4_x86_translate_instruction(pc+2);
1.88 exit_block_pcset(pc+2);
1.89 + sh4_x86.branch_taken = TRUE;
1.93 @@ -2277,7 +2288,6 @@
1.94 JE_rel8( 30, nottaken );
1.95 exit_block( disp + pc + 4, pc+2 );
1.96 JMP_TARGET(nottaken);
1.97 - exit_block( pc + 2, pc+2 );
1.101 @@ -2292,7 +2302,6 @@
1.102 JNE_rel8( 30, nottaken );
1.103 exit_block( disp + pc + 4, pc+2 );
1.104 JMP_TARGET(nottaken);
1.105 - exit_block( pc + 2, pc + 2 );
1.109 @@ -2311,7 +2320,6 @@
1.111 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.112 sh4_x86_translate_instruction(pc+2);
1.113 - exit_block( pc + 4, pc+4 );
1.117 @@ -2330,7 +2338,6 @@
1.119 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1.120 sh4_x86_translate_instruction(pc+2);
1.121 - exit_block( pc + 4, pc+4 );
1.125 @@ -2361,6 +2368,7 @@
1.126 sh4_x86.in_delay_slot = TRUE;
1.127 sh4_x86_translate_instruction( pc + 2 );
1.128 exit_block( disp + pc + 4, pc+4 );
1.129 + sh4_x86.branch_taken = TRUE;
1.133 @@ -2376,6 +2384,7 @@
1.134 sh4_x86.in_delay_slot = TRUE;
1.135 sh4_x86_translate_instruction( pc + 2 );
1.136 exit_block( disp + pc + 4, pc+4 );
1.137 + sh4_x86.branch_taken = TRUE;
1.141 @@ -2421,6 +2430,7 @@
1.142 call_func0( sh4_raise_trap );
1.143 ADD_imm8s_r32( 4, R_ESP );
1.144 exit_block_pcset(pc);
1.145 + sh4_x86.branch_taken = TRUE;