diff options
author | Richard Henderson <rth@twiddle.net> | 2012-10-02 11:32:28 -0700 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2012-10-17 17:51:37 +0200 |
commit | 212c328d615f6750659d39c6fd544d05be314fa1 (patch) | |
tree | 27fd57087428b1ae51c499b06cbe38999b5a6113 /tcg/optimize.c | |
parent | 6c4382f8f47d12eec24c7c5335141a9c78104016 (diff) |
tcg: Constant fold add2 and sub2
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'tcg/optimize.c')
-rw-r--r-- | tcg/optimize.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c index d9251e4677..05891ef380 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -796,6 +796,41 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, } goto do_default; + case INDEX_op_add2_i32: + case INDEX_op_sub2_i32: + if (temps[args[2]].state == TCG_TEMP_CONST + && temps[args[3]].state == TCG_TEMP_CONST + && temps[args[4]].state == TCG_TEMP_CONST + && temps[args[5]].state == TCG_TEMP_CONST) { + uint32_t al = temps[args[2]].val; + uint32_t ah = temps[args[3]].val; + uint32_t bl = temps[args[4]].val; + uint32_t bh = temps[args[5]].val; + uint64_t a = ((uint64_t)ah << 32) | al; + uint64_t b = ((uint64_t)bh << 32) | bl; + TCGArg rl, rh; + + if (op == INDEX_op_add2_i32) { + a += b; + } else { + a -= b; + } + + /* We emit the extra nop when we emit the add2/sub2. */ + assert(gen_opc_buf[op_index + 1] == INDEX_op_nop); + + rl = args[0]; + rh = args[1]; + gen_opc_buf[op_index] = INDEX_op_movi_i32; + gen_opc_buf[++op_index] = INDEX_op_movi_i32; + tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)a); + tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(a >> 32)); + gen_args += 4; + args += 6; + break; + } + goto do_default; + case INDEX_op_brcond2_i32: tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]); if (tmp != 2) { |