Patchwork [04/20] tcg-ia64: Simplify brcond

login
register
mail settings
Submitter Richard Henderson
Date Oct. 31, 2013, 8:21 p.m.
Message ID <1383250929-10288-5-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/287603/
State New
Headers show

Comments

Richard Henderson - Oct. 31, 2013, 8:21 p.m.
There was a misconception that a stop bit is required between a compare
and the branch that uses the predicate set by the compare.  This lead to
the usage of an extra bundle in which to perform the compare.  The extra
bundle left room for constants to be loaded for use with the compare insn.

If we pack the compare and the branch together in the same bundle, then
there's no longer any room for non-zero constants.  At which point we
can eliminate half the function by not handling them.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ia64/tcg-target.c | 42 +++++++++---------------------------------
 1 file changed, 9 insertions(+), 33 deletions(-)
Aurelien Jarno - Nov. 3, 2013, 10:56 p.m.
On Thu, Oct 31, 2013 at 01:21:53PM -0700, Richard Henderson wrote:
> There was a misconception that a stop bit is required between a compare
> and the branch that uses the predicate set by the compare.  This lead to

This seems to be true.

> the usage of an extra bundle in which to perform the compare.  The extra
> bundle left room for constants to be loaded for use with the compare insn.
> 
> If we pack the compare and the branch together in the same bundle, then
> there's no longer any room for non-zero constants.  At which point we
> can eliminate half the function by not handling them.

That said the implementation is likely wrong as with this patch applied,
qemu-system-x86_64 is not even able to execute seabios to the first
printed message. Please do at least basic testing.

> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  tcg/ia64/tcg-target.c | 42 +++++++++---------------------------------
>  1 file changed, 9 insertions(+), 33 deletions(-)
> 
> diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
> index b19e298..2fdc38a5 100644
> --- a/tcg/ia64/tcg-target.c
> +++ b/tcg/ia64/tcg-target.c
> @@ -1444,38 +1444,16 @@ static inline uint64_t tcg_opc_cmp_a(int qp, TCGCond cond, TCGArg arg1,
>      }
>  }
>  
> -static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
> -                                  int const_arg1, TCGArg arg2, int const_arg2,
> -                                  int label_index, int cmp4)
> +static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
> +                                  TCGReg arg2, int label_index, int cmp4)
>  {
>      TCGLabel *l = &s->labels[label_index];
> -    uint64_t opc1, opc2;
>  
> -    if (const_arg1 && arg1 != 0) {
> -        opc1 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5, TCG_REG_R2,
> -                          arg1, TCG_REG_R0);
> -        arg1 = TCG_REG_R2;
> -    } else {
> -        opc1 = INSN_NOP_M;
> -    }
> -
> -    if (const_arg2 && arg2 != 0) {
> -        opc2 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5, TCG_REG_R3,
> -                          arg2, TCG_REG_R0);
> -        arg2 = TCG_REG_R3;
> -    } else {
> -        opc2 = INSN_NOP_I;
> -    }
> -
> -    tcg_out_bundle(s, mII,
> -                   opc1,
> -                   opc2,
> -                   tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4));
> -    tcg_out_bundle(s, mmB,
> -                   INSN_NOP_M,
> +    tcg_out_bundle(s, miB,
>                     INSN_NOP_M,
> -                   tcg_opc_b1 (TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
> -                               get_reloc_pcrel21b(s->code_ptr + 2)));
> +                   tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
> +                   tcg_opc_b1(TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
> +                              get_reloc_pcrel21b(s->code_ptr + 2)));
>  
>      if (l->has_value) {
>          reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
> @@ -2224,12 +2202,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
>          break;
>  
>      case INDEX_op_brcond_i32:
> -        tcg_out_brcond(s, args[2], args[0], const_args[0],
> -                       args[1], const_args[1], args[3], 1);
> +        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 1);
>          break;
>      case INDEX_op_brcond_i64:
> -        tcg_out_brcond(s, args[2], args[0], const_args[0],
> -                       args[1], const_args[1], args[3], 0);
> +        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 0);
>          break;
>      case INDEX_op_setcond_i32:
>          tcg_out_setcond(s, args[3], args[0], args[1], args[2], 1);
> @@ -2333,7 +2309,7 @@ static const TCGTargetOpDef ia64_op_defs[] = {
>      { INDEX_op_bswap16_i32, { "r", "rZ" } },
>      { INDEX_op_bswap32_i32, { "r", "rZ" } },
>  
> -    { INDEX_op_brcond_i32, { "rI", "rI" } },
> +    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
>      { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
>      { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rI", "rI" } },
>  
> -- 
> 1.8.3.1
> 
>
Richard Henderson - Nov. 3, 2013, 11:34 p.m.
On 11/03/2013 12:56 PM, Aurelien Jarno wrote:
> That said the implementation is likely wrong as with this patch applied,
> qemu-system-x86_64 is not even able to execute seabios to the first
> printed message. Please do at least basic testing.

Really?  I'll look into it.

I do basic testing -- arm, sparc, alpha.  Those are the ones that can
usefully boot via serial console instead of having to set up a tunnel
for a vnc viewer.


r~
Aurelien Jarno - Nov. 6, 2013, 10:04 p.m.
On Sun, Nov 03, 2013 at 01:34:12PM -1000, Richard Henderson wrote:
> On 11/03/2013 12:56 PM, Aurelien Jarno wrote:
> > That said the implementation is likely wrong as with this patch applied,
> > qemu-system-x86_64 is not even able to execute seabios to the first
> > printed message. Please do at least basic testing.
> 
> Really?  I'll look into it.
> 
> I do basic testing -- arm, sparc, alpha.  Those are the ones that can
> usefully boot via serial console instead of having to set up a tunnel
> for a vnc viewer.

If you don't want to setup a VNC tunnel, you can also uses -curses
(provide the curses support is compiled) for i386 and x86-64.

Patch

diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index b19e298..2fdc38a5 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -1444,38 +1444,16 @@  static inline uint64_t tcg_opc_cmp_a(int qp, TCGCond cond, TCGArg arg1,
     }
 }
 
-static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
-                                  int const_arg1, TCGArg arg2, int const_arg2,
-                                  int label_index, int cmp4)
+static inline void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+                                  TCGReg arg2, int label_index, int cmp4)
 {
     TCGLabel *l = &s->labels[label_index];
-    uint64_t opc1, opc2;
 
-    if (const_arg1 && arg1 != 0) {
-        opc1 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5, TCG_REG_R2,
-                          arg1, TCG_REG_R0);
-        arg1 = TCG_REG_R2;
-    } else {
-        opc1 = INSN_NOP_M;
-    }
-
-    if (const_arg2 && arg2 != 0) {
-        opc2 = tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5, TCG_REG_R3,
-                          arg2, TCG_REG_R0);
-        arg2 = TCG_REG_R3;
-    } else {
-        opc2 = INSN_NOP_I;
-    }
-
-    tcg_out_bundle(s, mII,
-                   opc1,
-                   opc2,
-                   tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4));
-    tcg_out_bundle(s, mmB,
-                   INSN_NOP_M,
+    tcg_out_bundle(s, miB,
                    INSN_NOP_M,
-                   tcg_opc_b1 (TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
-                               get_reloc_pcrel21b(s->code_ptr + 2)));
+                   tcg_opc_cmp_a(TCG_REG_P0, cond, arg1, arg2, cmp4),
+                   tcg_opc_b1(TCG_REG_P6, OPC_BR_DPTK_FEW_B1,
+                              get_reloc_pcrel21b(s->code_ptr + 2)));
 
     if (l->has_value) {
         reloc_pcrel21b((s->code_ptr - 16) + 2, l->u.value);
@@ -2224,12 +2202,10 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_brcond_i32:
-        tcg_out_brcond(s, args[2], args[0], const_args[0],
-                       args[1], const_args[1], args[3], 1);
+        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 1);
         break;
     case INDEX_op_brcond_i64:
-        tcg_out_brcond(s, args[2], args[0], const_args[0],
-                       args[1], const_args[1], args[3], 0);
+        tcg_out_brcond(s, args[2], args[0], args[1], args[3], 0);
         break;
     case INDEX_op_setcond_i32:
         tcg_out_setcond(s, args[3], args[0], args[1], args[2], 1);
@@ -2333,7 +2309,7 @@  static const TCGTargetOpDef ia64_op_defs[] = {
     { INDEX_op_bswap16_i32, { "r", "rZ" } },
     { INDEX_op_bswap32_i32, { "r", "rZ" } },
 
-    { INDEX_op_brcond_i32, { "rI", "rI" } },
+    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rI", "rI" } },