diff mbox

[7/8] tcg/optimize: add constant folding for setcond

Message ID 1346943657-17256-8-git-send-email-aurelien@aurel32.net
State New
Headers show

Commit Message

Aurelien Jarno Sept. 6, 2012, 3 p.m. UTC
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 tcg/optimize.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

Comments

Richard Henderson Sept. 6, 2012, 4:40 p.m. UTC | #1
On 09/06/2012 08:00 AM, Aurelien Jarno wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  tcg/optimize.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 79 insertions(+)
> 
> diff --git a/tcg/optimize.c b/tcg/optimize.c
> index 7debc8a..c4af1e8 100644
> --- a/tcg/optimize.c
> +++ b/tcg/optimize.c
> @@ -267,6 +267,65 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
>      return res;
>  }
>  
> +static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
> +                                       TCGArg y, TCGCond c)
> +{
> +    switch (op_bits(op)) {
> +    case 32:
> +        switch (c) {
> +        case TCG_COND_EQ:
> +            return (uint32_t)x == (uint32_t)y;
> +        case TCG_COND_NE:
> +            return (uint32_t)x != (uint32_t)y;
> +        case TCG_COND_LT:
> +            return (int32_t)x < (int32_t)y;
> +        case TCG_COND_GE:
> +            return (int32_t)x >= (int32_t)y;
> +        case TCG_COND_LE:
> +            return (int32_t)x <= (int32_t)y;
> +        case TCG_COND_GT:
> +            return (int32_t)x > (int32_t)y;
> +        case TCG_COND_LTU:
> +            return (uint32_t)x < (uint32_t)y;
> +        case TCG_COND_GEU:
> +            return (uint32_t)x >= (uint32_t)y;
> +        case TCG_COND_LEU:
> +            return (uint32_t)x <= (uint32_t)y;
> +        case TCG_COND_GTU:
> +            return (uint32_t)x > (uint32_t)y;
> +    }
> +    case 64:
> +        switch (c) {
> +        case TCG_COND_EQ:
> +            return (uint64_t)x == (uint64_t)y;
> +        case TCG_COND_NE:
> +            return (uint64_t)x != (uint64_t)y;
> +        case TCG_COND_LT:
> +            return (int64_t)x < (int64_t)y;
> +        case TCG_COND_GE:
> +            return (int64_t)x >= (int64_t)y;
> +        case TCG_COND_LE:
> +            return (int64_t)x <= (int64_t)y;
> +        case TCG_COND_GT:
> +            return (int64_t)x > (int64_t)y;
> +        case TCG_COND_LTU:
> +            return (uint64_t)x < (uint64_t)y;
> +        case TCG_COND_GEU:
> +            return (uint64_t)x >= (uint64_t)y;
> +        case TCG_COND_LEU:
> +            return (uint64_t)x <= (uint64_t)y;
> +        case TCG_COND_GTU:
> +            return (uint64_t)x > (uint64_t)y;
> +    }
> +    default:
> +        fprintf(stderr,
> +                "Unrecognized bitness %d or condition %d in "
> +                "do_constant_folding_cond.\n", op_bits(op), c);
> +        tcg_abort();
> +    }

You probably don't want the default here, but the statements after
the outer switch, and with proper breaks between the two cases.
Otherwise the error doesn't do what you wanted it to do.



r~
Aurelien Jarno Sept. 7, 2012, 10:05 a.m. UTC | #2
On Thu, Sep 06, 2012 at 09:40:57AM -0700, Richard Henderson wrote:
> On 09/06/2012 08:00 AM, Aurelien Jarno wrote:
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> >  tcg/optimize.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 79 insertions(+)
> > 
> > diff --git a/tcg/optimize.c b/tcg/optimize.c
> > index 7debc8a..c4af1e8 100644
> > --- a/tcg/optimize.c
> > +++ b/tcg/optimize.c
> > @@ -267,6 +267,65 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
> >      return res;
> >  }
> >  
> > +static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
> > +                                       TCGArg y, TCGCond c)
> > +{
> > +    switch (op_bits(op)) {
> > +    case 32:
> > +        switch (c) {
> > +        case TCG_COND_EQ:
> > +            return (uint32_t)x == (uint32_t)y;
> > +        case TCG_COND_NE:
> > +            return (uint32_t)x != (uint32_t)y;
> > +        case TCG_COND_LT:
> > +            return (int32_t)x < (int32_t)y;
> > +        case TCG_COND_GE:
> > +            return (int32_t)x >= (int32_t)y;
> > +        case TCG_COND_LE:
> > +            return (int32_t)x <= (int32_t)y;
> > +        case TCG_COND_GT:
> > +            return (int32_t)x > (int32_t)y;
> > +        case TCG_COND_LTU:
> > +            return (uint32_t)x < (uint32_t)y;
> > +        case TCG_COND_GEU:
> > +            return (uint32_t)x >= (uint32_t)y;
> > +        case TCG_COND_LEU:
> > +            return (uint32_t)x <= (uint32_t)y;
> > +        case TCG_COND_GTU:
> > +            return (uint32_t)x > (uint32_t)y;
> > +    }
> > +    case 64:
> > +        switch (c) {
> > +        case TCG_COND_EQ:
> > +            return (uint64_t)x == (uint64_t)y;
> > +        case TCG_COND_NE:
> > +            return (uint64_t)x != (uint64_t)y;
> > +        case TCG_COND_LT:
> > +            return (int64_t)x < (int64_t)y;
> > +        case TCG_COND_GE:
> > +            return (int64_t)x >= (int64_t)y;
> > +        case TCG_COND_LE:
> > +            return (int64_t)x <= (int64_t)y;
> > +        case TCG_COND_GT:
> > +            return (int64_t)x > (int64_t)y;
> > +        case TCG_COND_LTU:
> > +            return (uint64_t)x < (uint64_t)y;
> > +        case TCG_COND_GEU:
> > +            return (uint64_t)x >= (uint64_t)y;
> > +        case TCG_COND_LEU:
> > +            return (uint64_t)x <= (uint64_t)y;
> > +        case TCG_COND_GTU:
> > +            return (uint64_t)x > (uint64_t)y;
> > +    }
> > +    default:
> > +        fprintf(stderr,
> > +                "Unrecognized bitness %d or condition %d in "
> > +                "do_constant_folding_cond.\n", op_bits(op), c);
> > +        tcg_abort();
> > +    }
> 
> You probably don't want the default here, but the statements after
> the outer switch, and with proper breaks between the two cases.
> Otherwise the error doesn't do what you wanted it to do.
> 

Good catch, i'll fix that in version 2.
diff mbox

Patch

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 7debc8a..c4af1e8 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -267,6 +267,65 @@  static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
     return res;
 }
 
+static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
+                                       TCGArg y, TCGCond c)
+{
+    switch (op_bits(op)) {
+    case 32:
+        switch (c) {
+        case TCG_COND_EQ:
+            return (uint32_t)x == (uint32_t)y;
+        case TCG_COND_NE:
+            return (uint32_t)x != (uint32_t)y;
+        case TCG_COND_LT:
+            return (int32_t)x < (int32_t)y;
+        case TCG_COND_GE:
+            return (int32_t)x >= (int32_t)y;
+        case TCG_COND_LE:
+            return (int32_t)x <= (int32_t)y;
+        case TCG_COND_GT:
+            return (int32_t)x > (int32_t)y;
+        case TCG_COND_LTU:
+            return (uint32_t)x < (uint32_t)y;
+        case TCG_COND_GEU:
+            return (uint32_t)x >= (uint32_t)y;
+        case TCG_COND_LEU:
+            return (uint32_t)x <= (uint32_t)y;
+        case TCG_COND_GTU:
+            return (uint32_t)x > (uint32_t)y;
+    }
+    case 64:
+        switch (c) {
+        case TCG_COND_EQ:
+            return (uint64_t)x == (uint64_t)y;
+        case TCG_COND_NE:
+            return (uint64_t)x != (uint64_t)y;
+        case TCG_COND_LT:
+            return (int64_t)x < (int64_t)y;
+        case TCG_COND_GE:
+            return (int64_t)x >= (int64_t)y;
+        case TCG_COND_LE:
+            return (int64_t)x <= (int64_t)y;
+        case TCG_COND_GT:
+            return (int64_t)x > (int64_t)y;
+        case TCG_COND_LTU:
+            return (uint64_t)x < (uint64_t)y;
+        case TCG_COND_GEU:
+            return (uint64_t)x >= (uint64_t)y;
+        case TCG_COND_LEU:
+            return (uint64_t)x <= (uint64_t)y;
+        case TCG_COND_GTU:
+            return (uint64_t)x > (uint64_t)y;
+    }
+    default:
+        fprintf(stderr,
+                "Unrecognized bitness %d or condition %d in "
+                "do_constant_folding_cond.\n", op_bits(op), c);
+        tcg_abort();
+    }
+}
+
+
 /* Propagate constants and copies, fold constant expressions. */
 static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                     TCGArg *args, TCGOpDef *tcg_op_defs)
@@ -522,6 +581,26 @@  static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                 args += 3;
                 break;
             }
+        CASE_OP_32_64(setcond):
+            if (temps[args[1]].state == TCG_TEMP_CONST
+                && temps[args[2]].state == TCG_TEMP_CONST) {
+                gen_opc_buf[op_index] = op_to_movi(op);
+                tmp = do_constant_folding_cond(op, temps[args[1]].val,
+                                               temps[args[2]].val, args[3]);
+                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
+                gen_args += 2;
+                args += 4;
+                break;
+            } else {
+                reset_temp(args[0], nb_temps, nb_globals);
+                gen_args[0] = args[0];
+                gen_args[1] = args[1];
+                gen_args[2] = args[2];
+                gen_args[3] = args[3];
+                gen_args += 4;
+                args += 4;
+                break;
+            }
         case INDEX_op_call:
             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {