On 07/08/14 20:32, Richard Henderson wrote:
On 08/07/2014 02:57 AM, Kyrill Tkachov wrote:
+  if (one_match > zero_match)
+    {
+      /* Set either first three quarters or all but the third.  */
+      mask = 0xffffll << (16 - first_not_ffff_match);
+      emit_insn (gen_rtx_SET (VOIDmode, dest,
+                             GEN_INT (val | mask | 0xffffffff00000000ull)));
+
+      /* Now insert other two quarters.         */
+      for (i = first_not_ffff_match + 16, mask <<= (first_not_ffff_match << 1);
+          i < 64; i += 16, mask <<= 16)
        {
          if ((val & mask) != mask)
+           emit_insn (gen_insv_immdi (dest, GEN_INT (i),
+                                      GEN_INT ((val >> i) & 0xffff)));
        }
+      return;
      }
if (zero_match == 2)
You should not place this three instruction sequence before the two instruction
sequences that follow.  I.e. place this just before simple_sequence.
Hi Richard,

Is the attached patch ok? It just moves the section as you suggested. I did a build of the Linux kernel with and without this patch to make sure no code-gen was accidentally affected.


I do wonder if we should be memo-izing these computations so that we only have
to do the complex search for a sequence only once for each constant...

We'd need to store a mapping from constant to RTXes and everytime we have a "cache hit" we'd have to tweak them to make sure the registers involved are correct. I had a quick play with this but ended up with LRA ICEs :(
Might look at it later on, but it's not high on my priorities right now.

Thanks,
Kyrill

2014-08-13  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Move
    one_match > zero_match case to just before simple_sequence.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 20debb9..a4e7158 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1136,24 +1136,6 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
       return;
     }
 
-  if (one_match > zero_match)
-    {
-      /* Set either first three quarters or all but the third.	 */
-      mask = 0xffffll << (16 - first_not_ffff_match);
-      emit_insn (gen_rtx_SET (VOIDmode, dest,
-			      GEN_INT (val | mask | 0xffffffff00000000ull)));
-
-      /* Now insert other two quarters.	 */
-      for (i = first_not_ffff_match + 16, mask <<= (first_not_ffff_match << 1);
-	   i < 64; i += 16, mask <<= 16)
-	{
-	  if ((val & mask) != mask)
-	    emit_insn (gen_insv_immdi (dest, GEN_INT (i),
-				       GEN_INT ((val >> i) & 0xffff)));
-	}
-      return;
-    }
-
   if (zero_match == 2)
     goto simple_sequence;
 
@@ -1270,6 +1252,24 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
 	}
     }
 
+  if (one_match > zero_match)
+    {
+      /* Set either first three quarters or all but the third.	 */
+      mask = 0xffffll << (16 - first_not_ffff_match);
+      emit_insn (gen_rtx_SET (VOIDmode, dest,
+			      GEN_INT (val | mask | 0xffffffff00000000ull)));
+
+      /* Now insert other two quarters.	 */
+      for (i = first_not_ffff_match + 16, mask <<= (first_not_ffff_match << 1);
+	   i < 64; i += 16, mask <<= 16)
+	{
+	  if ((val & mask) != mask)
+	    emit_insn (gen_insv_immdi (dest, GEN_INT (i),
+				       GEN_INT ((val >> i) & 0xffff)));
+	}
+      return;
+    }
+
  simple_sequence:
   first = true;
   mask = 0xffff;

Reply via email to