Commit 7dcfb0897b99110e2ac2428796d6f2215a610e3f
1 parent
4f9cc927
CRIS: Add branch-free versions of abs, lsl, lsr and asr.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5546 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
40 additions
and
29 deletions
target-cris/translate.c
| @@ -229,41 +229,52 @@ static inline void t_gen_raise_exception(uint32_t index) | @@ -229,41 +229,52 @@ static inline void t_gen_raise_exception(uint32_t index) | ||
| 229 | 229 | ||
| 230 | static void t_gen_lsl(TCGv d, TCGv a, TCGv b) | 230 | static void t_gen_lsl(TCGv d, TCGv a, TCGv b) |
| 231 | { | 231 | { |
| 232 | - int l1; | 232 | + TCGv t0, t_31; |
| 233 | 233 | ||
| 234 | - l1 = gen_new_label(); | ||
| 235 | - /* Speculative shift. */ | 234 | + t0 = tcg_temp_new(TCG_TYPE_TL); |
| 235 | + t_31 = tcg_temp_new(TCG_TYPE_TL); | ||
| 236 | tcg_gen_shl_tl(d, a, b); | 236 | tcg_gen_shl_tl(d, a, b); |
| 237 | - tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1); | ||
| 238 | - /* Clear dst if shift operands were to large. */ | ||
| 239 | - tcg_gen_movi_tl(d, 0); | ||
| 240 | - gen_set_label(l1); | 237 | + |
| 238 | + tcg_gen_movi_tl(t_31, 31); | ||
| 239 | + tcg_gen_sub_tl(t0, t_31, b); | ||
| 240 | + tcg_gen_sar_tl(t0, t0, t_31); | ||
| 241 | + tcg_gen_and_tl(t0, t0, d); | ||
| 242 | + tcg_gen_xor_tl(d, d, t0); | ||
| 243 | + tcg_temp_free(t0); | ||
| 244 | + tcg_temp_free(t_31); | ||
| 241 | } | 245 | } |
| 242 | 246 | ||
| 243 | static void t_gen_lsr(TCGv d, TCGv a, TCGv b) | 247 | static void t_gen_lsr(TCGv d, TCGv a, TCGv b) |
| 244 | { | 248 | { |
| 245 | - int l1; | 249 | + TCGv t0, t_31; |
| 246 | 250 | ||
| 247 | - l1 = gen_new_label(); | ||
| 248 | - /* Speculative shift. */ | 251 | + t0 = tcg_temp_new(TCG_TYPE_TL); |
| 252 | + t_31 = tcg_temp_new(TCG_TYPE_TL); | ||
| 249 | tcg_gen_shr_tl(d, a, b); | 253 | tcg_gen_shr_tl(d, a, b); |
| 250 | - tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1); | ||
| 251 | - /* Clear dst if shift operands were to large. */ | ||
| 252 | - tcg_gen_movi_tl(d, 0); | ||
| 253 | - gen_set_label(l1); | 254 | + |
| 255 | + tcg_gen_movi_tl(t_31, 31); | ||
| 256 | + tcg_gen_sub_tl(t0, t_31, b); | ||
| 257 | + tcg_gen_sar_tl(t0, t0, t_31); | ||
| 258 | + tcg_gen_and_tl(t0, t0, d); | ||
| 259 | + tcg_gen_xor_tl(d, d, t0); | ||
| 260 | + tcg_temp_free(t0); | ||
| 261 | + tcg_temp_free(t_31); | ||
| 254 | } | 262 | } |
| 255 | 263 | ||
| 256 | static void t_gen_asr(TCGv d, TCGv a, TCGv b) | 264 | static void t_gen_asr(TCGv d, TCGv a, TCGv b) |
| 257 | { | 265 | { |
| 258 | - int l1; | 266 | + TCGv t0, t_31; |
| 259 | 267 | ||
| 260 | - l1 = gen_new_label(); | ||
| 261 | - /* Speculative shift. */ | 268 | + t0 = tcg_temp_new(TCG_TYPE_TL); |
| 269 | + t_31 = tcg_temp_new(TCG_TYPE_TL); | ||
| 262 | tcg_gen_sar_tl(d, a, b); | 270 | tcg_gen_sar_tl(d, a, b); |
| 263 | - tcg_gen_brcondi_tl(TCG_COND_LEU, b, 31, l1); | ||
| 264 | - /* Clear dst if shift operands were to large. */ | ||
| 265 | - tcg_gen_sar_tl(d, a, tcg_const_tl(30)); | ||
| 266 | - gen_set_label(l1); | 271 | + |
| 272 | + tcg_gen_movi_tl(t_31, 31); | ||
| 273 | + tcg_gen_sub_tl(t0, t_31, b); | ||
| 274 | + tcg_gen_sar_tl(t0, t0, t_31); | ||
| 275 | + tcg_gen_or_tl(d, d, t0); | ||
| 276 | + tcg_temp_free(t0); | ||
| 277 | + tcg_temp_free(t_31); | ||
| 267 | } | 278 | } |
| 268 | 279 | ||
| 269 | /* 64-bit signed mul, lower result in d and upper in d2. */ | 280 | /* 64-bit signed mul, lower result in d and upper in d2. */ |
| @@ -1777,20 +1788,20 @@ static unsigned int dec_cmp_r(DisasContext *dc) | @@ -1777,20 +1788,20 @@ static unsigned int dec_cmp_r(DisasContext *dc) | ||
| 1777 | 1788 | ||
| 1778 | static unsigned int dec_abs_r(DisasContext *dc) | 1789 | static unsigned int dec_abs_r(DisasContext *dc) |
| 1779 | { | 1790 | { |
| 1780 | - int l1; | 1791 | + TCGv t0; |
| 1781 | 1792 | ||
| 1782 | DIS(fprintf (logfile, "abs $r%u, $r%u\n", | 1793 | DIS(fprintf (logfile, "abs $r%u, $r%u\n", |
| 1783 | dc->op1, dc->op2)); | 1794 | dc->op1, dc->op2)); |
| 1784 | cris_cc_mask(dc, CC_MASK_NZ); | 1795 | cris_cc_mask(dc, CC_MASK_NZ); |
| 1785 | - dec_prep_move_r(dc, dc->op1, dc->op2, 4, 0, cpu_T[1]); | ||
| 1786 | 1796 | ||
| 1787 | - /* TODO: consider a branch free approach. */ | ||
| 1788 | - l1 = gen_new_label(); | ||
| 1789 | - tcg_gen_brcondi_tl(TCG_COND_GE, cpu_T[1], 0, l1); | ||
| 1790 | - tcg_gen_neg_tl(cpu_T[1], cpu_T[1]); | ||
| 1791 | - gen_set_label(l1); | 1797 | + t0 = tcg_temp_new(TCG_TYPE_TL); |
| 1798 | + tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31); | ||
| 1799 | + tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0); | ||
| 1800 | + tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0); | ||
| 1801 | + tcg_temp_free(t0); | ||
| 1802 | + | ||
| 1792 | cris_alu(dc, CC_OP_MOVE, | 1803 | cris_alu(dc, CC_OP_MOVE, |
| 1793 | - cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); | 1804 | + cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4); |
| 1794 | return 2; | 1805 | return 2; |
| 1795 | } | 1806 | } |
| 1796 | 1807 |