From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:44744) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UIi85-0001FN-1c for qemu-devel@nongnu.org; Thu, 21 Mar 2013 12:14:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UIi81-0000LG-OP for qemu-devel@nongnu.org; Thu, 21 Mar 2013 12:14:12 -0400 Received: from mail-ve0-f173.google.com ([209.85.128.173]:49310) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UIi81-0000Kp-L6 for qemu-devel@nongnu.org; Thu, 21 Mar 2013 12:14:09 -0400 Received: by mail-ve0-f173.google.com with SMTP id oz10so2572428veb.4 for ; Thu, 21 Mar 2013 09:14:08 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Thu, 21 Mar 2013 09:13:33 -0700 Message-Id: <1363882413-15534-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH v2] tcg-optimize: Fold sub r,0,x to neg r,x List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Blue Swirl Cc: Blue Swirl Signed-off-by: Richard Henderson --- V2 properly does a reset_temp on the output of the neg. This was the cause of the sparc32 boot problem. r~ --- tcg/optimize.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index bc6e5c1..1b6644c 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; } -- 1.8.1.4