diff options
author | Richard Henderson <rth@twiddle.net> | 2013-03-21 09:13:33 -0700 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2013-03-23 14:31:03 +0000 |
commit | 2d497542e1ee66598be8bb7ce6a4606d664417ac (patch) | |
tree | 34b03a69ce3c8f2a9779f96d798d5bcd63a2901a | |
parent | 4980ef9e3e12be3b4ef9092abc2d5a665199b422 (diff) |
tcg-optimize: Fold sub r,0,x to neg r,x
Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r-- | tcg/optimize.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c index bc6e5c16a9..1b6644c6c9 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -576,7 +576,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, break; } - /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */ + /* Simplify expressions for "shift/rot r, 0, a => movi r, 0", + and "sub r, 0, a => neg r, a" case. */ switch (op) { CASE_OP_32_64(shl): CASE_OP_32_64(shr): @@ -592,6 +593,37 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, continue; } break; + CASE_OP_32_64(sub): + { + TCGOpcode neg_op; + bool have_neg; + + if (temps[args[2]].state == TCG_TEMP_CONST) { + /* Proceed with possible constant folding. */ + break; + } + if (op == INDEX_op_sub_i32) { + neg_op = INDEX_op_neg_i32; + have_neg = TCG_TARGET_HAS_neg_i32; + } else { + neg_op = INDEX_op_neg_i64; + have_neg = TCG_TARGET_HAS_neg_i64; + } + if (!have_neg) { + break; + } + if (temps[args[1]].state == TCG_TEMP_CONST + && temps[args[1]].val == 0) { + s->gen_opc_buf[op_index] = neg_op; + reset_temp(args[0]); + gen_args[0] = args[0]; + gen_args[1] = args[2]; + args += 3; + gen_args += 2; + continue; + } + } + break; default: break; } |