From patchwork Mon Sep 28 09:12:08 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 34373 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DB61EB7B65 for ; Mon, 28 Sep 2009 19:13:18 +1000 (EST) Received: from localhost ([127.0.0.1]:46642 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MsCIE-0006HJ-1Q for incoming@patchwork.ozlabs.org; Mon, 28 Sep 2009 05:13:14 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MsCHU-0006FC-LM for qemu-devel@nongnu.org; Mon, 28 Sep 2009 05:12:28 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MsCHT-0006E9-Ex for qemu-devel@nongnu.org; Mon, 28 Sep 2009 05:12:28 -0400 Received: from [199.232.76.173] (port=60455 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MsCHT-0006E5-Am for qemu-devel@nongnu.org; Mon, 28 Sep 2009 05:12:27 -0400 Received: from mx20.gnu.org ([199.232.41.8]:9845) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MsCHS-0006xC-B7 for qemu-devel@nongnu.org; Mon, 28 Sep 2009 05:12:26 -0400 Received: from hall.aurel32.net ([88.191.82.174]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MsCHN-0003kg-Tl for qemu-devel@nongnu.org; Mon, 28 Sep 2009 05:12:22 -0400 Received: from aurel32 by hall.aurel32.net with local (Exim 4.69) (envelope-from ) id 1MsCHA-0001dC-Ls for qemu-devel@nongnu.org; Mon, 28 Sep 2009 11:12:08 +0200 Date: Mon, 28 Sep 2009 11:12:08 +0200 From: Aurelien Jarno To: qemu-devel@nongnu.org Message-ID: <20090928091208.GB22663@hall.aurel32.net> MIME-Version: 1.0 Content-Disposition: inline X-Mailer: Mutt 1.5.18 (2008-05-17) User-Agent: Mutt/1.5.18 (2008-05-17) X-detected-operating-system: by mx20.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Subject: [Qemu-devel] [RFC] tcg: store constants without using registers when possible X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Currently only implemented for x86/x86_64. It may also be implemented for targets that keep one register for TCG internal use. Signed-off-by: Aurelien Jarno --- tcg/arm/tcg-target.c | 6 ++++++ tcg/hppa/tcg-target.c | 6 ++++++ tcg/i386/tcg-target.c | 9 +++++++++ tcg/ppc/tcg-target.c | 9 +++++++++ tcg/ppc64/tcg-target.c | 9 +++++++++ tcg/sparc/tcg-target.c | 9 +++++++++ tcg/tcg.c | 10 ++++++---- tcg/x86_64/tcg-target.c | 16 ++++++++++++++++ 8 files changed, 70 insertions(+), 4 deletions(-) diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index f8d626d..339026f 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1669,6 +1669,12 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, tcg_out_st32(s, COND_AL, arg, arg1, arg2); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + return 0; +} + static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) { if (val > 0) diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index ddce60c..ba885b1 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -285,6 +285,12 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int ret, tcg_abort(); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + return 0; +} + static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op) { tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2)); diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index b4e3b6f..d5494ce 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -276,6 +276,15 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + /* movl */ + tcg_out_modrm_offset(s, 0xc7, 0, arg1, arg2); + tcg_out32(s, val); + return 1; +} + static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val, int cf) { if (!cf && ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1))) { diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 07e6941..f23d375 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -958,6 +958,15 @@ static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1, tcg_out_ldst (s, arg, arg1, arg2, STW, STWX); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + /* movl */ + tcg_out_modrm_offset(s, 0xc7, 0, arg1, arg2); + tcg_out32(s, val); + return 1; +} + static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si) { if (!si && rt == ra) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 1bb13e6..c44b7f5 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -917,6 +917,15 @@ static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1, tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + /* movl */ + tcg_out_modrm_offset(s, 0xc7, 0, arg1, arg2); + tcg_out32(s, val); + return 1; +} + static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si) { if (!si && rt == ra) diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 23cd9cd..c723576 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -392,6 +392,15 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, tcg_out_ldst(s, arg, arg1, arg2, STX); } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + /* movl */ + tcg_out_modrm_offset(s, 0xc7, 0, arg1, arg2); + tcg_out32(s, val); + return 1; +} + static inline void tcg_out_sety(TCGContext *s, tcg_target_long val) { if (val == 0 || val == -1) diff --git a/tcg/tcg.c b/tcg/tcg.c index 93066e2..8818af3 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1385,12 +1385,14 @@ static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs) ts->val_type = TEMP_VAL_MEM; break; case TEMP_VAL_CONST: - reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], - allocated_regs); if (!ts->mem_allocated) temp_allocate_frame(s, temp); - tcg_out_movi(s, ts->type, reg, ts->val); - tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset); + if (!tcg_out_sti(s, ts->type, ts->val, ts->mem_reg, ts->mem_offset)) { + reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], + allocated_regs); + tcg_out_movi(s, ts->type, reg, ts->val); + tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset); + } ts->val_type = TEMP_VAL_MEM; break; case TEMP_VAL_MEM: diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c index b4ba65f..f069347 100644 --- a/tcg/x86_64/tcg-target.c +++ b/tcg/x86_64/tcg-target.c @@ -395,6 +395,22 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, tcg_out_modrm_offset(s, 0x89 | P_REXW, arg, arg1, arg2); /* movq */ } +static inline int tcg_out_sti(TCGContext *s, TCGType type, tcg_target_long val, + int arg1, tcg_target_long arg2) +{ + if (type == TCG_TYPE_I32) { + tcg_out_modrm_offset(s, 0xc7, 0, arg1, arg2); /* movl */ + tcg_out32(s, val); + } else { + if ((int32_t) val != val) { + return 0; + } + tcg_out_modrm_offset(s, 0xc7 | P_REXW, 0, arg1, arg2); /* movq */ + tcg_out32(s, val); + } + return 1; +} + static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val) { if ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1)) {