tcg/tci: Implement clz, ctz, ctpop

Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-02-02 17:01:57 -08:00
parent 0f10d7c5b0
commit 5255f48c1c
3 changed files with 59 additions and 6 deletions

View File

@ -589,6 +589,26 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
break;
#if TCG_TARGET_HAS_clz_i32
case INDEX_op_clz_i32:
tci_args_rrr(insn, &r0, &r1, &r2);
tmp32 = regs[r1];
regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
break;
#endif
#if TCG_TARGET_HAS_ctz_i32
case INDEX_op_ctz_i32:
tci_args_rrr(insn, &r0, &r1, &r2);
tmp32 = regs[r1];
regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
break;
#endif
#if TCG_TARGET_HAS_ctpop_i32
case INDEX_op_ctpop_i32:
tci_args_rr(insn, &r0, &r1);
regs[r0] = ctpop32(regs[r1]);
break;
#endif
/* Shift/rotate operations (32 bit). */
@ -741,6 +761,24 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
break;
#if TCG_TARGET_HAS_clz_i64
case INDEX_op_clz_i64:
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
break;
#endif
#if TCG_TARGET_HAS_ctz_i64
case INDEX_op_ctz_i64:
tci_args_rrr(insn, &r0, &r1, &r2);
regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
break;
#endif
#if TCG_TARGET_HAS_ctpop_i64
case INDEX_op_ctpop_i64:
tci_args_rr(insn, &r0, &r1);
regs[r0] = ctpop64(regs[r1]);
break;
#endif
/* Shift/rotate operations (64 bit). */
@ -1167,6 +1205,8 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_not_i64:
case INDEX_op_neg_i32:
case INDEX_op_neg_i64:
case INDEX_op_ctpop_i32:
case INDEX_op_ctpop_i64:
tci_args_rr(insn, &r0, &r1);
info->fprintf_func(info->stream, "%-12s %s, %s",
op_name, str_r(r0), str_r(r1));
@ -1212,6 +1252,10 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
case INDEX_op_rotl_i64:
case INDEX_op_rotr_i32:
case INDEX_op_rotr_i64:
case INDEX_op_clz_i32:
case INDEX_op_clz_i64:
case INDEX_op_ctz_i32:
case INDEX_op_ctz_i64:
tci_args_rrr(insn, &r0, &r1, &r2);
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
op_name, str_r(r0), str_r(r1), str_r(r2));

View File

@ -67,6 +67,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_extract_i64:
case INDEX_op_sextract_i32:
case INDEX_op_sextract_i64:
case INDEX_op_ctpop_i32:
case INDEX_op_ctpop_i64:
return C_O1_I1(r, r);
case INDEX_op_st8_i32:
@ -122,6 +124,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
case INDEX_op_setcond_i64:
case INDEX_op_deposit_i32:
case INDEX_op_deposit_i64:
case INDEX_op_clz_i32:
case INDEX_op_clz_i64:
case INDEX_op_ctz_i32:
case INDEX_op_ctz_i64:
return C_O1_I2(r, r, r);
case INDEX_op_brcond_i32:
@ -655,6 +661,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
CASE_32_64(divu) /* Optional (TCG_TARGET_HAS_div_*). */
CASE_32_64(rem) /* Optional (TCG_TARGET_HAS_div_*). */
CASE_32_64(remu) /* Optional (TCG_TARGET_HAS_div_*). */
CASE_32_64(clz) /* Optional (TCG_TARGET_HAS_clz_*). */
CASE_32_64(ctz) /* Optional (TCG_TARGET_HAS_ctz_*). */
tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
break;
@ -703,6 +711,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
CASE_32_64(bswap16) /* Optional (TCG_TARGET_HAS_bswap16_*). */
CASE_32_64(bswap32) /* Optional (TCG_TARGET_HAS_bswap32_*). */
CASE_64(bswap64) /* Optional (TCG_TARGET_HAS_bswap64_i64). */
CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
tcg_out_op_rr(s, opc, args[0], args[1]);
break;

View File

@ -76,9 +76,9 @@
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_clz_i32 0
#define TCG_TARGET_HAS_ctz_i32 0
#define TCG_TARGET_HAS_ctpop_i32 0
#define TCG_TARGET_HAS_clz_i32 1
#define TCG_TARGET_HAS_ctz_i32 1
#define TCG_TARGET_HAS_ctpop_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_orc_i32 1
@ -113,9 +113,9 @@
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_clz_i64 0
#define TCG_TARGET_HAS_ctz_i64 0
#define TCG_TARGET_HAS_ctpop_i64 0
#define TCG_TARGET_HAS_clz_i64 1
#define TCG_TARGET_HAS_ctz_i64 1
#define TCG_TARGET_HAS_ctpop_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_orc_i64 1