From nobody Mon Feb 9 16:02:51 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15018279311406.123935418794645; Thu, 3 Aug 2017 23:25:31 -0700 (PDT) Received: from localhost ([::1]:38460 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddW35-0005Ju-RI for importer@patchew.org; Fri, 04 Aug 2017 02:25:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ddW14-0003Ws-9A for qemu-devel@nongnu.org; Fri, 04 Aug 2017 02:23:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ddW11-0005Ni-Hi for qemu-devel@nongnu.org; Fri, 04 Aug 2017 02:23:22 -0400 Received: from mail-pg0-x242.google.com ([2607:f8b0:400e:c05::242]:34782) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ddW11-0005Mt-9a for qemu-devel@nongnu.org; Fri, 04 Aug 2017 02:23:19 -0400 Received: by mail-pg0-x242.google.com with SMTP id y192so919163pgd.1 for ; Thu, 03 Aug 2017 23:23:19 -0700 (PDT) Received: from bigtime.twiddle.net (97-126-108-236.tukw.qwest.net. [97.126.108.236]) by smtp.gmail.com with ESMTPSA id q199sm1335819pfq.135.2017.08.03.23.23.16 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Aug 2017 23:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=paorHe3sqTqEIdLPxMp8BCggiDO+kJcJ6vXqbOfRtig=; b=kiqBtk3vz29wzbCA5Id1KuOxJaMHKxYCzULbOMbN2O3V2DW/rTJRh50DPGJUH+tC6l 4RcPNAPYAEmSSUNUZ90/o7kBrBppmaY2CaVLJky7DxFP2L5NuDPnSDq0G4fcSDwvElRB UfjNXuvtYkn7UpFQVRlgsPb/aCoMkG5eELjXzmdXnp+KxutOVuCLRrOttp684RVwkxvu /VbAbHBHF+Pm3uQ8ntAzZ+J1LPAkdSUNjHTh/Y/pYTBWb5bkS3KN9QklvVGAf13IlXSA BGGcTMGKe/FRj/QCISxooqHnZEsoP6bCFt8M5ZPdPi09v5Cz1EocJKsT0xkAroy/8F7e RPtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=paorHe3sqTqEIdLPxMp8BCggiDO+kJcJ6vXqbOfRtig=; b=KOb2EJeR+TjsyvqNOZeuw5MG25PwXuMDGJAx30I1nsWGyNfuBRjf2Pt0jJlc6h/PEs eZV+tuFaR8eHAoKfiWd+7GjoEwBXahbH4hphkU+nWPuYgkwaSUpRf0oTEJ7A/SVXKkwT JdwHr8IAUVeCu8+8qViu57yCZL/ch/QRuHw8fomMrBHN6+0H3F3qhl77MBTkvJgghOfS GW0vYPPpBUvDp8JmLiXngKPT5VOczodcXyboxmsZ6SmmPZZgsz7PiT/1VSp1mvfbQ45P aH00WU5/qRmp/Ck9rsW8nshARvsCIJ7cwx0ThmMLGLrAKxZIp6kjtN8b8u4/Ocu1asFf FO2w== X-Gm-Message-State: AIVw110oQxJiTdZ1m9eFfHhHvHPVjiWHaRFQe0uTZvw57zVizXnliMHn tqMqBLQFs2bJPtDqEn4= X-Received: by 10.101.69.196 with SMTP id m4mr1216503pgr.105.1501827798075; Thu, 03 Aug 2017 23:23:18 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 3 Aug 2017 23:23:09 -0700 Message-Id: <20170804062314.12594-2-rth@twiddle.net> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170804062314.12594-1-rth@twiddle.net> References: <20170804062314.12594-1-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::242 Subject: [Qemu-devel] [PATCH for-2.11 1/6] tcg: Add tcg_reg_alloc_new X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This allows the backend to allocate an otherwise unused register. This can allow the backend to avoid having to reserve a full-time temporary register. Signed-off-by: Richard Henderson --- tcg/tcg.h | 1 + tcg/tcg.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/tcg/tcg.h b/tcg/tcg.h index ac94133870..dd97095af5 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -655,6 +655,7 @@ struct TCGContext { uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */ uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */ =20 + TCGRegSet regs_in_use; TCGRegSet reserved_regs; intptr_t current_frame_offset; intptr_t frame_start; diff --git a/tcg/tcg.c b/tcg/tcg.c index fd8a3dfe93..787c8ba0f7 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -112,6 +112,8 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TC= GArg val, static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct); +static TCGReg tcg_reg_alloc_new(TCGContext *s, TCGType t) + __attribute__((unused)); #ifdef TCG_TARGET_NEED_LDST_LABELS static bool tcg_out_ldst_finalize(TCGContext *s); #endif @@ -1947,16 +1949,19 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, /* If we're going to free the temp immediately, then we won't require it later in a register, so attempt to store the constant to memory directly. */ - if (free_or_dead - && tcg_out_sti(s, ts->type, ts->val, - ts->mem_base->reg, ts->mem_offset)) { - break; + if (free_or_dead) { + s->regs_in_use =3D -1; + if (tcg_out_sti(s, ts->type, ts->val, + ts->mem_base->reg, ts->mem_offset)) { + break; + } } temp_load(s, ts, tcg_target_available_regs[ts->type], allocated_regs); /* fallthrough */ =20 case TEMP_VAL_REG: + s->regs_in_use =3D -1; tcg_out_st(s, ts->type, ts->reg, ts->mem_base->reg, ts->mem_offset); break; @@ -2015,6 +2020,14 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet= desired_regs, tcg_abort(); } =20 +static TCGReg tcg_reg_alloc_new(TCGContext *s, TCGType t) +{ + TCGReg r; + r =3D tcg_reg_alloc(s, tcg_target_available_regs[t], s->regs_in_use, 0= ); + tcg_regset_set_reg(s->regs_in_use, r); + return r; +} + /* Make sure the temporary is in a register. If needed, allocate the regi= ster from DESIRED while avoiding ALLOCATED. */ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, @@ -2027,11 +2040,13 @@ static void temp_load(TCGContext *s, TCGTemp *ts, T= CGRegSet desired_regs, return; case TEMP_VAL_CONST: reg =3D tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirec= t_base); + s->regs_in_use =3D allocated_regs; tcg_out_movi(s, ts->type, reg, ts->val); ts->mem_coherent =3D 0; break; case TEMP_VAL_MEM: reg =3D tcg_reg_alloc(s, desired_regs, allocated_regs, ts->indirec= t_base); + s->regs_in_use =3D -1; tcg_out_ld(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset); ts->mem_coherent =3D 1; break; @@ -2105,6 +2120,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGT= emp *ots, { if (ots->fixed_reg) { /* For fixed registers, we do not do any constant propagation. */ + s->regs_in_use =3D s->reserved_regs; tcg_out_movi(s, ots->type, ots->reg, val); return; } @@ -2129,17 +2145,16 @@ static void tcg_reg_alloc_movi(TCGContext *s, const= TCGArg *args, TCGTemp *ots =3D &s->temps[args[0]]; tcg_target_ulong val =3D args[1]; =20 + s->regs_in_use =3D s->reserved_regs; tcg_reg_alloc_do_movi(s, ots, val, arg_life); } =20 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, const TCGArg *args, TCGLifeData arg_life) { - TCGRegSet allocated_regs; TCGTemp *ts, *ots; TCGType otype, itype; =20 - tcg_regset_set(allocated_regs, s->reserved_regs); ots =3D &s->temps[args[0]]; ts =3D &s->temps[args[1]]; =20 @@ -2153,6 +2168,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TC= GOpDef *def, if (IS_DEAD_ARG(1)) { temp_dead(s, ts); } + s->regs_in_use =3D s->reserved_regs; tcg_reg_alloc_do_movi(s, ots, val, arg_life); return; } @@ -2162,7 +2178,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TC= GOpDef *def, the SOURCE value into its own register first, that way we don't have to reload SOURCE the next time it is used. */ if (ts->val_type =3D=3D TEMP_VAL_MEM) { - temp_load(s, ts, tcg_target_available_regs[itype], allocated_regs); + temp_load(s, ts, tcg_target_available_regs[itype], s->reserved_reg= s); } =20 tcg_debug_assert(ts->val_type =3D=3D TEMP_VAL_REG); @@ -2173,12 +2189,14 @@ static void tcg_reg_alloc_mov(TCGContext *s, const = TCGOpDef *def, if (!ots->mem_allocated) { temp_allocate_frame(s, args[0]); } + s->regs_in_use =3D -1; tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset); if (IS_DEAD_ARG(1)) { temp_dead(s, ts); } temp_dead(s, ots); } else { + TCGRegSet allocated_regs; if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) { /* the mov can be suppressed */ if (ots->val_type =3D=3D TEMP_VAL_REG) { @@ -2188,19 +2206,21 @@ static void tcg_reg_alloc_mov(TCGContext *s, const = TCGOpDef *def, temp_dead(s, ts); } else { if (ots->val_type !=3D TEMP_VAL_REG) { - /* When allocating a new register, make sure to not spill = the - input one. */ + /* When allocating a new register, make sure to not + spill the input one. */ + allocated_regs =3D s->reserved_regs; tcg_regset_set_reg(allocated_regs, ts->reg); ots->reg =3D tcg_reg_alloc(s, tcg_target_available_regs[ot= ype], allocated_regs, ots->indirect_bas= e); } + s->regs_in_use =3D -1; tcg_out_mov(s, otype, ots->reg, ts->reg); } ots->val_type =3D TEMP_VAL_REG; ots->mem_coherent =3D 0; s->reg_to_temp[ots->reg] =3D ots; if (NEED_SYNC_ARG(0)) { - temp_sync(s, ots, allocated_regs, 0); + temp_sync(s, ots, s->reserved_regs, 0); } } } @@ -2281,6 +2301,7 @@ static void tcg_reg_alloc_op(TCGContext *s, and move the temporary register into it */ reg =3D tcg_reg_alloc(s, arg_ct->u.regs, i_allocated_regs, ts->indirect_base); + s->regs_in_use =3D -1; tcg_out_mov(s, ts->type, reg, ts->reg); } new_args[i] =3D reg; @@ -2355,6 +2376,7 @@ static void tcg_reg_alloc_op(TCGContext *s, } =20 /* emit instruction */ + s->regs_in_use =3D i_allocated_regs | o_allocated_regs; tcg_out_op(s, opc, new_args, const_args); =20 /* move the outputs in the correct register if needed */ @@ -2362,6 +2384,7 @@ static void tcg_reg_alloc_op(TCGContext *s, ts =3D &s->temps[args[i]]; reg =3D new_args[i]; if (ts->fixed_reg && ts->reg !=3D reg) { + s->regs_in_use =3D -1; tcg_out_mov(s, ts->type, ts->reg, reg); } if (NEED_SYNC_ARG(i)) { @@ -2420,6 +2443,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_= oargs, int nb_iargs, ts =3D &s->temps[arg]; temp_load(s, ts, tcg_target_available_regs[ts->type], s->reserved_regs); + s->regs_in_use =3D -1; tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_off= set); } #ifndef TCG_TARGET_STACK_GROWSUP @@ -2428,7 +2452,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_= oargs, int nb_iargs, } =20 /* assign input registers */ - tcg_regset_set(allocated_regs, s->reserved_regs); + allocated_regs =3D s->reserved_regs; for(i =3D 0; i < nb_regs; i++) { arg =3D args[nb_oargs + i]; if (arg !=3D TCG_CALL_DUMMY_ARG) { @@ -2438,6 +2462,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_= oargs, int nb_iargs, =20 if (ts->val_type =3D=3D TEMP_VAL_REG) { if (ts->reg !=3D reg) { + s->regs_in_use =3D -1; tcg_out_mov(s, ts->type, reg, ts->reg); } } else { @@ -2458,7 +2483,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_= oargs, int nb_iargs, temp_dead(s, &s->temps[args[i]]); } } - =20 + /* clobber call registers */ for (i =3D 0; i < TCG_TARGET_NB_REGS; i++) { if (tcg_regset_test_reg(tcg_target_call_clobber_regs, i)) { @@ -2476,10 +2501,16 @@ static void tcg_reg_alloc_call(TCGContext *s, int n= b_oargs, int nb_iargs, save_globals(s, allocated_regs); } =20 + s->regs_in_use =3D allocated_regs; tcg_out_call(s, func_addr); =20 /* assign output registers and emit moves if needed */ - for(i =3D 0; i < nb_oargs; i++) { + allocated_regs =3D s->reserved_regs; + for (i =3D 0; i < nb_oargs; i++) { + reg =3D tcg_target_call_oarg_regs[i]; + tcg_regset_set_reg(allocated_regs, reg); + } + for (i =3D 0; i < nb_oargs; i++) { arg =3D args[i]; ts =3D &s->temps[arg]; reg =3D tcg_target_call_oarg_regs[i]; @@ -2487,6 +2518,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_= oargs, int nb_iargs, =20 if (ts->fixed_reg) { if (ts->reg !=3D reg) { + s->regs_in_use =3D -1; tcg_out_mov(s, ts->type, ts->reg, reg); } } else { --=20 2.13.3