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:
parent
0f10d7c5b0
commit
5255f48c1c
44
tcg/tci.c
44
tcg/tci.c
@ -589,6 +589,26 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||||||
tci_args_rrr(insn, &r0, &r1, &r2);
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
||||||
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
|
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
|
||||||
break;
|
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). */
|
/* 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);
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
||||||
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
|
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
|
||||||
break;
|
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). */
|
/* 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_not_i64:
|
||||||
case INDEX_op_neg_i32:
|
case INDEX_op_neg_i32:
|
||||||
case INDEX_op_neg_i64:
|
case INDEX_op_neg_i64:
|
||||||
|
case INDEX_op_ctpop_i32:
|
||||||
|
case INDEX_op_ctpop_i64:
|
||||||
tci_args_rr(insn, &r0, &r1);
|
tci_args_rr(insn, &r0, &r1);
|
||||||
info->fprintf_func(info->stream, "%-12s %s, %s",
|
info->fprintf_func(info->stream, "%-12s %s, %s",
|
||||||
op_name, str_r(r0), str_r(r1));
|
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_rotl_i64:
|
||||||
case INDEX_op_rotr_i32:
|
case INDEX_op_rotr_i32:
|
||||||
case INDEX_op_rotr_i64:
|
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);
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
||||||
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
|
||||||
op_name, str_r(r0), str_r(r1), str_r(r2));
|
op_name, str_r(r0), str_r(r1), str_r(r2));
|
||||||
|
@ -67,6 +67,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
|
|||||||
case INDEX_op_extract_i64:
|
case INDEX_op_extract_i64:
|
||||||
case INDEX_op_sextract_i32:
|
case INDEX_op_sextract_i32:
|
||||||
case INDEX_op_sextract_i64:
|
case INDEX_op_sextract_i64:
|
||||||
|
case INDEX_op_ctpop_i32:
|
||||||
|
case INDEX_op_ctpop_i64:
|
||||||
return C_O1_I1(r, r);
|
return C_O1_I1(r, r);
|
||||||
|
|
||||||
case INDEX_op_st8_i32:
|
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_setcond_i64:
|
||||||
case INDEX_op_deposit_i32:
|
case INDEX_op_deposit_i32:
|
||||||
case INDEX_op_deposit_i64:
|
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);
|
return C_O1_I2(r, r, r);
|
||||||
|
|
||||||
case INDEX_op_brcond_i32:
|
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(divu) /* Optional (TCG_TARGET_HAS_div_*). */
|
||||||
CASE_32_64(rem) /* 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(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]);
|
tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
|
||||||
break;
|
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(bswap16) /* Optional (TCG_TARGET_HAS_bswap16_*). */
|
||||||
CASE_32_64(bswap32) /* Optional (TCG_TARGET_HAS_bswap32_*). */
|
CASE_32_64(bswap32) /* Optional (TCG_TARGET_HAS_bswap32_*). */
|
||||||
CASE_64(bswap64) /* Optional (TCG_TARGET_HAS_bswap64_i64). */
|
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]);
|
tcg_out_op_rr(s, opc, args[0], args[1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@
|
|||||||
#define TCG_TARGET_HAS_eqv_i32 1
|
#define TCG_TARGET_HAS_eqv_i32 1
|
||||||
#define TCG_TARGET_HAS_nand_i32 1
|
#define TCG_TARGET_HAS_nand_i32 1
|
||||||
#define TCG_TARGET_HAS_nor_i32 1
|
#define TCG_TARGET_HAS_nor_i32 1
|
||||||
#define TCG_TARGET_HAS_clz_i32 0
|
#define TCG_TARGET_HAS_clz_i32 1
|
||||||
#define TCG_TARGET_HAS_ctz_i32 0
|
#define TCG_TARGET_HAS_ctz_i32 1
|
||||||
#define TCG_TARGET_HAS_ctpop_i32 0
|
#define TCG_TARGET_HAS_ctpop_i32 1
|
||||||
#define TCG_TARGET_HAS_neg_i32 1
|
#define TCG_TARGET_HAS_neg_i32 1
|
||||||
#define TCG_TARGET_HAS_not_i32 1
|
#define TCG_TARGET_HAS_not_i32 1
|
||||||
#define TCG_TARGET_HAS_orc_i32 1
|
#define TCG_TARGET_HAS_orc_i32 1
|
||||||
@ -113,9 +113,9 @@
|
|||||||
#define TCG_TARGET_HAS_eqv_i64 1
|
#define TCG_TARGET_HAS_eqv_i64 1
|
||||||
#define TCG_TARGET_HAS_nand_i64 1
|
#define TCG_TARGET_HAS_nand_i64 1
|
||||||
#define TCG_TARGET_HAS_nor_i64 1
|
#define TCG_TARGET_HAS_nor_i64 1
|
||||||
#define TCG_TARGET_HAS_clz_i64 0
|
#define TCG_TARGET_HAS_clz_i64 1
|
||||||
#define TCG_TARGET_HAS_ctz_i64 0
|
#define TCG_TARGET_HAS_ctz_i64 1
|
||||||
#define TCG_TARGET_HAS_ctpop_i64 0
|
#define TCG_TARGET_HAS_ctpop_i64 1
|
||||||
#define TCG_TARGET_HAS_neg_i64 1
|
#define TCG_TARGET_HAS_neg_i64 1
|
||||||
#define TCG_TARGET_HAS_not_i64 1
|
#define TCG_TARGET_HAS_not_i64 1
|
||||||
#define TCG_TARGET_HAS_orc_i64 1
|
#define TCG_TARGET_HAS_orc_i64 1
|
||||||
|
Loading…
Reference in New Issue
Block a user