diff options
author | Richard Henderson <rth@twiddle.net> | 2016-11-16 09:23:28 +0100 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2017-01-10 08:06:11 -0800 |
commit | 0e28d0063bbd9e59a981ea2d20f82f30c5d956a8 (patch) | |
tree | 6e4a705fef28f5ffc5ab828ca9abcc13f5097927 /tcg/optimize.c | |
parent | 17280ff4a5f264e01e55ae514ee6d3586f9577b2 (diff) | |
download | qemu-0e28d0063bbd9e59a981ea2d20f82f30c5d956a8.zip qemu-0e28d0063bbd9e59a981ea2d20f82f30c5d956a8.tar.gz qemu-0e28d0063bbd9e59a981ea2d20f82f30c5d956a8.tar.bz2 |
tcg: Add clz and ctz opcodes
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/optimize.c')
-rw-r--r-- | tcg/optimize.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c index 9e26bb7..e7ecce4 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -296,6 +296,18 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) CASE_OP_32_64(nor): return ~(x | y); + case INDEX_op_clz_i32: + return (uint32_t)x ? clz32(x) : y; + + case INDEX_op_clz_i64: + return x ? clz64(x) : y; + + case INDEX_op_ctz_i32: + return (uint32_t)x ? ctz32(x) : y; + + case INDEX_op_ctz_i64: + return x ? ctz64(x) : y; + CASE_OP_32_64(ext8s): return (int8_t)x; @@ -896,6 +908,16 @@ void tcg_optimize(TCGContext *s) mask = temps[args[1]].mask | temps[args[2]].mask; break; + case INDEX_op_clz_i32: + case INDEX_op_ctz_i32: + mask = temps[args[2]].mask | 31; + break; + + case INDEX_op_clz_i64: + case INDEX_op_ctz_i64: + mask = temps[args[2]].mask | 63; + break; + CASE_OP_32_64(setcond): case INDEX_op_setcond2_i32: mask = 1; @@ -1052,6 +1074,20 @@ void tcg_optimize(TCGContext *s) } goto do_default; + CASE_OP_32_64(clz): + CASE_OP_32_64(ctz): + if (temp_is_const(args[1])) { + TCGArg v = temps[args[1]].val; + if (v != 0) { + tmp = do_constant_folding(opc, v, 0); + tcg_opt_gen_movi(s, op, args, args[0], tmp); + } else { + tcg_opt_gen_mov(s, op, args, args[0], args[2]); + } + break; + } + goto do_default; + CASE_OP_32_64(deposit): if (temp_is_const(args[1]) && temp_is_const(args[2])) { tmp = deposit64(temps[args[1]].val, args[3], args[4], |