qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: James Hogan <james.hogan@imgtec.com>, qemu-devel@nongnu.org
Cc: Leon Alrae <leon.alrae@imgtec.com>,
	Aurelien Jarno <aurelien@aurel32.net>
Subject: Re: [Qemu-devel] [PATCH v2 6/6] tcg/mips: Support r6 SEL{NE, EQ}Z instead of MOVN/MOVZ
Date: Fri, 2 Oct 2015 05:53:37 +1000	[thread overview]
Message-ID: <560D8F41.5090409@twiddle.net> (raw)
In-Reply-To: <1443697130-21431-7-git-send-email-james.hogan@imgtec.com>

On 10/01/2015 08:58 PM, James Hogan wrote:
> Extend MIPS movcond implementation to support the SELNEZ/SELEQZ
> instructions introduced in MIPS r6 (where MOVN/MOVZ have been removed).
>
> Whereas the "MOVN/MOVZ rd, rs, rt" instructions have the following
> semantics:
>   rd = [!]rt ? rs : rd
>
> The "SELNEZ/SELEQZ rd, rs, rt" instructions are slightly different:
>   rd = [!]rt ? rs : 0
>
> First we ensure that if one of the movcond input values is zero that it
> comes last (we can swap the input arguments if we invert the condition).
> This is so that it can exactly match one of the SELNEZ/SELEQZ
> instructions and avoid the need to emit the other one.
>
> Otherwise we emit the opposite instruction first into a temporary
> register, and OR that into the result:
>   SELNEZ/SELEQZ  TMP1, v2, c1
>   SELEQZ/SELNEZ  ret, v1, c1
>   OR             ret, ret, TMP1
>
> Which does the following:
>   ret = cond ? v1 : v2
>
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - Combine with patch 6 from v1, and drop functional changes to movcond
>    implementation pre-r6. We now provide different constraints for
>    movcond depending on presence of r6. (thanks Richard for feedback).
> ---
>   tcg/mips/tcg-target.c | 40 ++++++++++++++++++++++++++++++++++------
>   1 file changed, 34 insertions(+), 6 deletions(-)
>
> diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
> index a937b1475d04..ef1e85a75e22 100644
> --- a/tcg/mips/tcg-target.c
> +++ b/tcg/mips/tcg-target.c
> @@ -314,6 +314,8 @@ typedef enum {
>       OPC_NOR      = OPC_SPECIAL | 0x27,
>       OPC_SLT      = OPC_SPECIAL | 0x2A,
>       OPC_SLTU     = OPC_SPECIAL | 0x2B,
> +    OPC_SELEQZ   = OPC_SPECIAL | 0x35,
> +    OPC_SELNEZ   = OPC_SPECIAL | 0x37,
>
>       OPC_REGIMM   = 0x01 << 26,
>       OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
> @@ -858,13 +860,24 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
>   }
>
>   static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
> -                            TCGReg c1, TCGReg c2, TCGReg v)
> +                            TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
>   {
> -    MIPSInsn m_opc = OPC_MOVN;
> +    MIPSInsn m_opc_t = use_mips32r6_instructions ? OPC_SELNEZ : OPC_MOVN;
> +    MIPSInsn m_opc_f = use_mips32r6_instructions ? OPC_SELEQZ : OPC_MOVZ;
> +    const MIPSInsn m_opc_t_inv = m_opc_f;
> +    const MIPSInsn m_opc_f_inv = m_opc_t;
> +
> +    /* If one of the values is zero, put it last to match SEL*Z instructions */
> +    if (use_mips32r6_instructions && v1 == 0) {
> +        v1 = v2;
> +        v2 = 0;
> +        cond = tcg_invert_cond(cond);
> +    }
>
>       switch (cond) {
>       case TCG_COND_EQ:
> -        m_opc = OPC_MOVZ;
> +        m_opc_t = m_opc_t_inv;
> +        m_opc_f = m_opc_f_inv;
>           /* FALLTHRU */
>       case TCG_COND_NE:
>           if (c2 != 0) {
> @@ -877,14 +890,25 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
>           /* Minimize code size by preferring a compare not requiring INV.  */
>           if (mips_cmp_map[cond] & MIPS_CMP_INV) {
>               cond = tcg_invert_cond(cond);
> -            m_opc = OPC_MOVZ;
> +            m_opc_t = m_opc_t_inv;
> +            m_opc_f = m_opc_f_inv;
>           }
>           tcg_out_setcond(s, cond, TCG_TMP0, c1, c2);
>           c1 = TCG_TMP0;
>           break;
>       }
>
> -    tcg_out_opc_reg(s, m_opc, ret, v, c1);
> +    if (use_mips32r6_instructions) {
> +        if (v2 != 0) {
> +            tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
> +        }
> +        tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
> +        if (v2 != 0) {
> +            tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
> +        }
> +    } else {
> +        tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
> +    }
>   }

I think it's worth just using on "bool ne" in the generic code.  Then when you 
get down to the r6 conditional selecting the insns.

E.g.

     if (use_mips32r6_instructions) {
         MIPSInsn m_opc_t = ne ? OPC_SELNEZ : OPC_SELEQZ;
         MIPSInsn m_opf_f = ne ? OPC_SELEQZ : OPC_SELNEZ;
         ...
     } else {
         MIPSInsn m_opc = ne ? OPC_MOVN : OPC_MOVZ;
         ...
     }

And maybe add either a tcg_debug_assert or a comment in the !r6 path to remind 
the reader that we took care of ret == v2 via constraints.


r~

  reply	other threads:[~2015-10-01 19:53 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-01 10:58 [Qemu-devel] [PATCH v2 0/6] tcg/mips: Minimal R6 support James Hogan
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 1/6] tcg-opc.h: Simplify debug_insn_start def James Hogan
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 2/6] disas/mips: Add R6 jr/jr.hb to disassembler James Hogan
2015-10-01 19:42   ` Richard Henderson
2015-10-02  9:19   ` Leon Alrae
2015-10-02  9:22     ` James Hogan
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 3/6] tcg/mips: Add use_mips32r6_instructions definition James Hogan
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 4/6] tcg/mips: Support r6 JR encoding James Hogan
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 5/6] tcg/mips: Support r6 multiply/divide encodings James Hogan
2015-10-01 19:40   ` Richard Henderson
2015-10-01 10:58 ` [Qemu-devel] [PATCH v2 6/6] tcg/mips: Support r6 SEL{NE, EQ}Z instead of MOVN/MOVZ James Hogan
2015-10-01 19:53   ` Richard Henderson [this message]
2015-10-02  9:31     ` James Hogan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=560D8F41.5090409@twiddle.net \
    --to=rth@twiddle.net \
    --cc=aurelien@aurel32.net \
    --cc=james.hogan@imgtec.com \
    --cc=leon.alrae@imgtec.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).