summaryrefslogtreecommitdiff
path: root/tcg/optimize.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-11-16 09:23:28 +0100
committerRichard Henderson <rth@twiddle.net>2017-01-10 08:06:11 -0800
commit0e28d0063bbd9e59a981ea2d20f82f30c5d956a8 (patch)
tree6e4a705fef28f5ffc5ab828ca9abcc13f5097927 /tcg/optimize.c
parent17280ff4a5f264e01e55ae514ee6d3586f9577b2 (diff)
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.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 9e26bb7e4e..e7ecce478e 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],