Commit abd5c94ee110d4a5187eca3e2dff91cb3e9e5606

Authored by edgar_igl
1 parent 4a1e6bea

CRIS: Speedup btst by using a helper.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6203 c046a42c-6fe2-441c-8c8c-71466251a162
target-cris/helper.h
... ... @@ -10,6 +10,8 @@ DEF_HELPER_0(rfn, void);
10 10 DEF_HELPER_2(movl_sreg_reg, void, i32, i32)
11 11 DEF_HELPER_2(movl_reg_sreg, void, i32, i32)
12 12  
  13 +DEF_HELPER_FLAGS_3(btst, TCG_CALL_PURE, i32, i32, i32, i32);
  14 +
13 15 DEF_HELPER_0(evaluate_flags_muls, void)
14 16 DEF_HELPER_0(evaluate_flags_mulu, void)
15 17 DEF_HELPER_0(evaluate_flags_mcp, void)
... ...
target-cris/op_helper.c
... ... @@ -243,6 +243,32 @@ void helper_rfn(void)
243 243 env->pregs[PR_CCS] |= M_FLAG;
244 244 }
245 245  
  246 +uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
  247 +{
  248 + /* FIXME: clean this up. */
  249 +
  250 + /* des ref:
  251 + The N flag is set according to the selected bit in the dest reg.
  252 + The Z flag is set if the selected bit and all bits to the right are
  253 + zero.
  254 + The X flag is cleared.
  255 + Other flags are left untouched.
  256 + The destination reg is not affected.*/
  257 + unsigned int fz, sbit, bset, mask, masked_t0;
  258 +
  259 + sbit = t1 & 31;
  260 + bset = !!(t0 & (1 << sbit));
  261 + mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
  262 + masked_t0 = t0 & mask;
  263 + fz = !(masked_t0 | bset);
  264 +
  265 + /* Clear the X, N and Z flags. */
  266 + ccs = ccs & ~(X_FLAG | N_FLAG | Z_FLAG);
  267 + /* Set the N and Z flags accordingly. */
  268 + ccs |= (bset << 3) | (fz << 2);
  269 + return ccs;
  270 +}
  271 +
246 272 static void evaluate_flags_writeback(uint32_t flags)
247 273 {
248 274 unsigned int x, z, mask;
... ...
target-cris/translate.c
... ... @@ -388,64 +388,6 @@ static void t_gen_lz_i32(TCGv d, TCGv x)
388 388 tcg_temp_free(n);
389 389 }
390 390  
391   -static void t_gen_btst(TCGv d, TCGv a, TCGv b)
392   -{
393   - TCGv sbit;
394   - TCGv bset;
395   - TCGv t0;
396   - int l1;
397   -
398   - /* des ref:
399   - The N flag is set according to the selected bit in the dest reg.
400   - The Z flag is set if the selected bit and all bits to the right are
401   - zero.
402   - The X flag is cleared.
403   - Other flags are left untouched.
404   - The destination reg is not affected.
405   -
406   - unsigned int fz, sbit, bset, mask, masked_t0;
407   -
408   - sbit = T1 & 31;
409   - bset = !!(T0 & (1 << sbit));
410   - mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
411   - masked_t0 = T0 & mask;
412   - fz = !(masked_t0 | bset);
413   -
414   - // Clear the X, N and Z flags.
415   - T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG);
416   - // Set the N and Z flags accordingly.
417   - T0 |= (bset << 3) | (fz << 2);
418   - */
419   -
420   - l1 = gen_new_label();
421   - sbit = tcg_temp_new();
422   - bset = tcg_temp_new();
423   - t0 = tcg_temp_new();
424   -
425   - /* Compute bset and sbit. */
426   - tcg_gen_andi_tl(sbit, b, 31);
427   - tcg_gen_shl_tl(t0, tcg_const_tl(1), sbit);
428   - tcg_gen_and_tl(bset, a, t0);
429   - tcg_gen_shr_tl(bset, bset, sbit);
430   - /* Displace to N_FLAG. */
431   - tcg_gen_shli_tl(bset, bset, 3);
432   -
433   - tcg_gen_shl_tl(sbit, tcg_const_tl(2), sbit);
434   - tcg_gen_subi_tl(sbit, sbit, 1);
435   - tcg_gen_and_tl(sbit, a, sbit);
436   -
437   - tcg_gen_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG));
438   - /* or in the N_FLAG. */
439   - tcg_gen_or_tl(d, d, bset);
440   - tcg_gen_brcondi_tl(TCG_COND_NE, sbit, 0, l1);
441   - /* or in the Z_FLAG. */
442   - tcg_gen_ori_tl(d, d, Z_FLAG);
443   - gen_set_label(l1);
444   -
445   - tcg_temp_free(sbit);
446   - tcg_temp_free(bset);
447   -}
448   -
449 391 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
450 392 {
451 393 int l1;
... ... @@ -885,9 +827,6 @@ static void cris_alu_op_exec(DisasContext *dc, int op,
885 827 case CC_OP_LZ:
886 828 t_gen_lz_i32(dst, b);
887 829 break;
888   - case CC_OP_BTST:
889   - t_gen_btst(dst, a, b);
890   - break;
891 830 case CC_OP_MULS:
892 831 t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
893 832 break;
... ... @@ -932,7 +871,7 @@ static void cris_alu(DisasContext *dc, int op,
932 871  
933 872 writeback = 1;
934 873  
935   - if (op == CC_OP_BOUND || op == CC_OP_BTST)
  874 + if (op == CC_OP_BOUND)
936 875 tmp = tcg_temp_local_new();
937 876  
938 877 if (op == CC_OP_CMP) {
... ... @@ -1560,18 +1499,17 @@ static unsigned int dec_orq(DisasContext *dc)
1560 1499 }
1561 1500 static unsigned int dec_btstq(DisasContext *dc)
1562 1501 {
1563   - TCGv l0;
1564 1502 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
1565 1503 DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2));
1566 1504  
1567 1505 cris_cc_mask(dc, CC_MASK_NZ);
1568   - l0 = tcg_temp_local_new();
1569   - cris_alu(dc, CC_OP_BTST,
1570   - l0, cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
  1506 + cris_evaluate_flags(dc);
  1507 + gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
  1508 + tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
  1509 + cris_alu(dc, CC_OP_MOVE,
  1510 + cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
1571 1511 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1572   - t_gen_mov_preg_TN(dc, PR_CCS, l0);
1573 1512 dc->flags_uptodate = 1;
1574   - tcg_temp_free(l0);
1575 1513 return 2;
1576 1514 }
1577 1515 static unsigned int dec_asrq(DisasContext *dc)
... ... @@ -2012,17 +1950,16 @@ static unsigned int dec_neg_r(DisasContext *dc)
2012 1950  
2013 1951 static unsigned int dec_btst_r(DisasContext *dc)
2014 1952 {
2015   - TCGv l0;
2016 1953 DIS(fprintf (logfile, "btst $r%u, $r%u\n",
2017 1954 dc->op1, dc->op2));
2018 1955 cris_cc_mask(dc, CC_MASK_NZ);
2019   -
2020   - l0 = tcg_temp_local_new();
2021   - cris_alu(dc, CC_OP_BTST, l0, cpu_R[dc->op2], cpu_R[dc->op1], 4);
  1956 + cris_evaluate_flags(dc);
  1957 + gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
  1958 + cpu_R[dc->op1], cpu_PR[PR_CCS]);
  1959 + cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
  1960 + cpu_R[dc->op2], cpu_R[dc->op2], 4);
2022 1961 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2023   - t_gen_mov_preg_TN(dc, PR_CCS, l0);
2024 1962 dc->flags_uptodate = 1;
2025   - tcg_temp_free(l0);
2026 1963 return 2;
2027 1964 }
2028 1965  
... ...