Search
lxdream.org :: lxdream :: r409:549e00835448
lxdream 0.9.1
released Jun 29
Download Now
changeset409:549e00835448
parent408:af496b734734
child410:5f8413358e7f
authornkeynes
dateSat Sep 29 05:33:02 2007 +0000 (16 years ago)
Modify termination again to allow early exit (eg on end-of-page), as well
as allowing follow through on conditional branches if desired.
src/sh4/sh4x86.c
src/sh4/sh4x86.in
1.1 --- a/src/sh4/sh4x86.c Fri Sep 28 07:27:20 2007 +0000
1.2 +++ b/src/sh4/sh4x86.c Sat Sep 29 05:33:02 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
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.7 *
1.8 * SH4 => x86 translation. This version does no real optimization, it just
1.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
1.10 @@ -42,6 +42,7 @@
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.16
1.17 /* Allocated memory for the (block-wide) back-patch list */
1.18 @@ -371,6 +372,7 @@
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.25 }
1.26 @@ -410,6 +412,10 @@
1.27 * Write the block trailer (exception handling block)
1.28 */
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.33 + }
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.37 @@ -562,6 +568,7 @@
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.42 return 4;
1.43 }
1.44 }
1.45 @@ -578,6 +585,7 @@
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.50 return 4;
1.51 }
1.52 }
1.53 @@ -804,6 +812,7 @@
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.58 return 4;
1.59 }
1.60 }
1.61 @@ -814,7 +823,6 @@
1.62 call_func0( sh4_sleep );
1.63 sh4_x86.in_delay_slot = FALSE;
1.64 INC_r32(R_ESI);
1.65 - exit_block(pc+2, pc+2);
1.66 return 2;
1.67 }
1.68 break;
1.69 @@ -833,6 +841,7 @@
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.74 return 4;
1.75 }
1.76 }
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.82 return 4;
1.83 }
1.84 }
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.90 return 4;
1.91 }
1.92 }
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.98 return 2;
1.99 }
1.100 }
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.106 return 2;
1.107 }
1.108 }
1.109 @@ -2311,7 +2320,6 @@
1.110 // not taken
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.114 return 4;
1.115 }
1.116 }
1.117 @@ -2330,7 +2338,6 @@
1.118 // not taken
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.122 return 4;
1.123 }
1.124 }
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.130 return 4;
1.131 }
1.132 }
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.138 return 4;
1.139 }
1.140 }
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;
1.146 return 2;
1.147 }
1.148 }
2.1 --- a/src/sh4/sh4x86.in Fri Sep 28 07:27:20 2007 +0000
2.2 +++ b/src/sh4/sh4x86.in Sat Sep 29 05:33:02 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: sh4x86.in,v 1.16 2007-09-28 07:27:20 nkeynes Exp $
2.6 + * $Id: sh4x86.in,v 1.17 2007-09-29 05:33:02 nkeynes Exp $
2.7 *
2.8 * SH4 => x86 translation. This version does no real optimization, it just
2.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
2.10 @@ -42,6 +42,7 @@
2.11 gboolean in_delay_slot;
2.12 gboolean priv_checked; /* true if we've already checked the cpu mode. */
2.13 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
2.14 + gboolean branch_taken; /* true if we branched unconditionally */
2.15 uint32_t block_start_pc;
2.16
2.17 /* Allocated memory for the (block-wide) back-patch list */
2.18 @@ -371,6 +372,7 @@
2.19 sh4_x86.in_delay_slot = FALSE;
2.20 sh4_x86.priv_checked = FALSE;
2.21 sh4_x86.fpuen_checked = FALSE;
2.22 + sh4_x86.branch_taken = FALSE;
2.23 sh4_x86.backpatch_posn = 0;
2.24 sh4_x86.block_start_pc = pc;
2.25 }
2.26 @@ -410,6 +412,10 @@
2.27 * Write the block trailer (exception handling block)
2.28 */
2.29 void sh4_translate_end_block( sh4addr_t pc ) {
2.30 + if( sh4_x86.branch_taken == FALSE ) {
2.31 + // Didn't exit unconditionally already, so write the termination here
2.32 + exit_block( pc, pc );
2.33 + }
2.34 if( sh4_x86.backpatch_posn != 0 ) {
2.35 uint8_t *end_ptr = xlat_output;
2.36 // Exception termination. Jump block for various exception codes:
2.37 @@ -1282,7 +1288,6 @@
2.38 JNE_rel8( 30, nottaken );
2.39 exit_block( disp + pc + 4, pc+2 );
2.40 JMP_TARGET(nottaken);
2.41 - exit_block( pc + 2, pc + 2 );
2.42 return 2;
2.43 }
2.44 :}
2.45 @@ -1298,7 +1303,6 @@
2.46 // not taken
2.47 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2.48 sh4_x86_translate_instruction(pc+2);
2.49 - exit_block( pc + 4, pc+4 );
2.50 return 4;
2.51 }
2.52 :}
2.53 @@ -1309,6 +1313,7 @@
2.54 sh4_x86.in_delay_slot = TRUE;
2.55 sh4_x86_translate_instruction( pc + 2 );
2.56 exit_block( disp + pc + 4, pc+4 );
2.57 + sh4_x86.branch_taken = TRUE;
2.58 return 4;
2.59 }
2.60 :}
2.61 @@ -1322,6 +1327,7 @@
2.62 sh4_x86.in_delay_slot = TRUE;
2.63 sh4_x86_translate_instruction( pc + 2 );
2.64 exit_block_pcset(pc+2);
2.65 + sh4_x86.branch_taken = TRUE;
2.66 return 4;
2.67 }
2.68 :}
2.69 @@ -1334,6 +1340,7 @@
2.70 sh4_x86.in_delay_slot = TRUE;
2.71 sh4_x86_translate_instruction( pc + 2 );
2.72 exit_block( disp + pc + 4, pc+4 );
2.73 + sh4_x86.branch_taken = TRUE;
2.74 return 4;
2.75 }
2.76 :}
2.77 @@ -1348,6 +1355,7 @@
2.78 sh4_x86.in_delay_slot = TRUE;
2.79 sh4_x86_translate_instruction( pc + 2 );
2.80 exit_block_pcset(pc+2);
2.81 + sh4_x86.branch_taken = TRUE;
2.82 return 4;
2.83 }
2.84 :}
2.85 @@ -1359,7 +1367,6 @@
2.86 JE_rel8( 30, nottaken );
2.87 exit_block( disp + pc + 4, pc+2 );
2.88 JMP_TARGET(nottaken);
2.89 - exit_block( pc + 2, pc+2 );
2.90 return 2;
2.91 }
2.92 :}
2.93 @@ -1375,7 +1382,6 @@
2.94 // not taken
2.95 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2.96 sh4_x86_translate_instruction(pc+2);
2.97 - exit_block( pc + 4, pc+4 );
2.98 return 4;
2.99 }
2.100 :}
2.101 @@ -1388,6 +1394,7 @@
2.102 sh4_x86.in_delay_slot = TRUE;
2.103 sh4_x86_translate_instruction(pc+2);
2.104 exit_block_pcset(pc+2);
2.105 + sh4_x86.branch_taken = TRUE;
2.106 return 4;
2.107 }
2.108 :}
2.109 @@ -1402,6 +1409,7 @@
2.110 sh4_x86.in_delay_slot = TRUE;
2.111 sh4_x86_translate_instruction(pc+2);
2.112 exit_block_pcset(pc+2);
2.113 + sh4_x86.branch_taken = TRUE;
2.114 return 4;
2.115 }
2.116 :}
2.117 @@ -1419,6 +1427,7 @@
2.118 sh4_x86.fpuen_checked = FALSE;
2.119 sh4_x86_translate_instruction(pc+2);
2.120 exit_block_pcset(pc+2);
2.121 + sh4_x86.branch_taken = TRUE;
2.122 return 4;
2.123 }
2.124 :}
2.125 @@ -1431,6 +1440,7 @@
2.126 sh4_x86.in_delay_slot = TRUE;
2.127 sh4_x86_translate_instruction(pc+2);
2.128 exit_block_pcset(pc+2);
2.129 + sh4_x86.branch_taken = TRUE;
2.130 return 4;
2.131 }
2.132 :}
2.133 @@ -1442,6 +1452,7 @@
2.134 call_func0( sh4_raise_trap );
2.135 ADD_imm8s_r32( 4, R_ESP );
2.136 exit_block_pcset(pc);
2.137 + sh4_x86.branch_taken = TRUE;
2.138 return 2;
2.139 }
2.140 :}
2.141 @@ -2283,7 +2294,6 @@
2.142 call_func0( sh4_sleep );
2.143 sh4_x86.in_delay_slot = FALSE;
2.144 INC_r32(R_ESI);
2.145 - exit_block(pc+2, pc+2);
2.146 return 2;
2.147 :}
2.148 STC SR, Rn {:
.