All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: identifier scorpio <cidentifier@yahoo.com.cn>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Porting TCG to alpha platform
Date: Fri, 29 Jan 2010 11:19:20 -0800	[thread overview]
Message-ID: <4B6334B8.9040002@twiddle.net> (raw)
In-Reply-To: <4B5E4311.10707@twiddle.net>

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

> +        } else if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
> +            tcg_out_mem_long(s, INSN_LDA, TMP_REG1, arg1, -arg2);
> +            opc = (cond == TCG_COND_EQ ? INSN_BEQ : INSN_BNE);

Bug here.  What was intended was to add "arg1 = TMP_REG1".
But since the constraints use "I" for uint8_t input constants,
we might as well remove this hunk entirely.

Also, let's future-proof this routine against changes to
the layout of the TCGCond enumeration.


r~

[-- Attachment #2: commit-9d78757 --]
[-- Type: text/plain, Size: 4019 bytes --]

commit 9d787576342c193f13e2531953fc81442458de7e
Author: Richard Henderson <rth@twiddle.net>
Date:   Fri Jan 29 11:14:20 2010 -0800

    tcg-alpha: Fix EQ/NE with a constant.
    
    There was start of code to handle EQ and NE with arbitrary constants,
    but it wasn't completed.  Remove the half-done code and add a comment
    for future enhancements.
    
    Also, don't rely on the current layout of TCGCond; instead encode the
    need for inversion of the compare insn result by means of a low bit set
    in the cmp_opc table.  Reduce the element size of cmp_opc.

diff --git a/tcg/alpha/tcg-target.c b/tcg/alpha/tcg-target.c
index 5b7dd25..18ab2c8 100644
--- a/tcg/alpha/tcg-target.c
+++ b/tcg/alpha/tcg-target.c
@@ -540,9 +540,11 @@ static void tcg_out_br(TCGContext *s, int opc, int ra, int label_index)
     tcg_out_fmt_br(s, opc, ra, value);
 }
 
-static void tcg_out_brcond(TCGContext *s, int cond, TCGArg arg1,
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
                            TCGArg arg2, int const_arg2, int label_index)
 {
+    /* Note that unsigned comparisons are not present here, which means
+       that their entries will contain zeros.  */
     static const int br_opc[10] = {
         [TCG_COND_EQ] = INSN_BEQ,
         [TCG_COND_NE] = INSN_BNE,
@@ -552,38 +554,56 @@ static void tcg_out_brcond(TCGContext *s, int cond, TCGArg arg1,
         [TCG_COND_GT] = INSN_BGT
     };
 
-    static const uint64_t cmp_opc[10] = {
+    /* The low bit of these entries indicates that the result of 
+       the comparison must be inverted.  This bit should not be
+       output with the rest of the instruction.  */
+    static const int cmp_opc[10] = {
         [TCG_COND_EQ] = INSN_CMPEQ,
-        [TCG_COND_NE] = INSN_CMPEQ,
+        [TCG_COND_NE] = INSN_CMPEQ | 1,
         [TCG_COND_LT] = INSN_CMPLT,
-        [TCG_COND_GE] = INSN_CMPLT,
+        [TCG_COND_GE] = INSN_CMPLT | 1,
         [TCG_COND_LE] = INSN_CMPLE,
-        [TCG_COND_GT] = INSN_CMPLE,
+        [TCG_COND_GT] = INSN_CMPLE | 1,
         [TCG_COND_LTU] = INSN_CMPULT,
-        [TCG_COND_GEU] = INSN_CMPULT,
+        [TCG_COND_GEU] = INSN_CMPULT | 1,
         [TCG_COND_LEU] = INSN_CMPULE,
-        [TCG_COND_GTU] = INSN_CMPULE
+        [TCG_COND_GTU] = INSN_CMPULE | 1
     };
 
     int opc = 0;
 
-    if (const_arg2) {
-        if (arg2 == 0) {
-            opc = br_opc[cond];
-        } else if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
-            tcg_out_mem_long(s, INSN_LDA, TMP_REG1, arg1, -arg2);
-            opc = (cond == TCG_COND_EQ ? INSN_BEQ : INSN_BNE);
-        }
+    /* Possible improvements:
+       (1) Notice arg1 == $31 and !const_arg2.  In this case, swap the
+       two operands and swap the sense of the comparison to allow the
+       use of the direct branches.
+
+       (2) Allow arbitrary constants.  We can, on occasion, generate one
+       less instruction if we compute
+           TMP = ARG1 - CONST
+       instead of
+           TMP = ARG1 cmp TMP2
+       where TMP2 is the constant loaded into a register by generic code.
+       Note that for 64-bit operands this works only for EQ and NE.  For
+       32-bit operands, we would need to either limit this to signed
+       comparisons or properly zero-extend unsigned inputs.  The payoff
+       here isn't great though; much less than(1).  */
+
+    /* Notice signed comparisons vs zero.  These are handled by the
+       branch instructions directly.  */
+    if (const_arg2 && arg2 == 0) {
+        opc = br_opc[cond];
     }
 
+    /* Otherwise, generate a comparison into a temporary.  */
     if (opc == 0) {
-        opc = cmp_opc[cond];
+        opc = cmp_opc[cond] & ~1;
         if (const_arg2) {
             tcg_out_fmt_opi(s, opc, arg1, arg2, TMP_REG1);
         } else {
             tcg_out_fmt_opr(s, opc, arg1, arg2, TMP_REG1);
         }
-        opc = (cond & 1) ? INSN_BEQ : INSN_BNE;
+
+        opc = (cmp_opc[cond] & 1 ? INSN_BEQ : INSN_BNE);
         arg1 = TMP_REG1;
     }
 

  parent reply	other threads:[~2010-01-29 19:19 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-22 15:47 [Qemu-devel] [PATCH] Porting TCG to alpha platform identifier scorpio
2010-01-22 18:00 ` Richard Henderson
2010-01-26  1:19 ` Richard Henderson
2010-01-29  1:55   ` identifier scorpio
2010-01-29 17:04     ` Richard Henderson
2010-01-29 21:38       ` Edgar E. Iglesias
2010-01-29 23:04         ` Stefan Weil
2010-01-30  0:38           ` Edgar E. Iglesias
2010-01-30  1:14           ` Laurent Desnogues
2010-01-30  9:30             ` [Qemu-devel] [BUG] qemu-x86_64 crash when running bntest (was: [PATCH] Porting TCG to alpha platform) Stefan Weil
2010-01-30  9:59               ` Laurent Desnogues
2010-01-30 14:47               ` Laurent Desnogues
2010-01-29 17:37   ` [Qemu-devel] [PATCH] Porting TCG to alpha platform Richard Henderson
2010-01-29 19:19   ` Richard Henderson [this message]
2010-01-30  2:45     ` identifier scorpio
2010-01-31 23:09       ` Richard Henderson
  -- strict thread matches above, loose matches on Subject: below --
2010-01-21  3:42 identifier scorpio
2010-01-21 18:18 ` Stefan Weil
2010-01-20 17:19 identifier scorpio
2010-01-20 21:26 ` Richard Henderson
2010-01-19  8:47 identifier scorpio
2010-01-19 20:18 ` Richard Henderson
2010-01-19 21:35   ` malc
2010-01-19 21:42 ` Stefan Weil

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=4B6334B8.9040002@twiddle.net \
    --to=rth@twiddle.net \
    --cc=cidentifier@yahoo.com.cn \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.