rs6000: rl[wd]imi without shift/rotate (PR68803)
authorSegher Boessenkool <segher@kernel.crashing.org>
Mon, 21 Nov 2016 22:29:34 +0000 (23:29 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Mon, 21 Nov 2016 22:29:34 +0000 (23:29 +0100)
We didn't have patterns yet for rl[wd]imi insns that do a rotate by 0.
This fixes it.

PR target/68803
* config/rs6000/rs6000.md (*rotlsi3_insert_5, *rotldi3_insert_6,
*rotldi3_insert_7): New define_insns.

From-SVN: r242681

gcc/ChangeLog
gcc/config/rs6000/rs6000.md

index 842e8ff5f2c4df5b6afd87cf0c514b09c598ac32..41772a0bdbf92b2cf2b503f8f23665a75d73e125 100644 (file)
@@ -1,3 +1,9 @@
+2016-11-21  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/68803
+       * config/rs6000/rs6000.md (*rotlsi3_insert_5, *rotldi3_insert_6,
+       *rotldi3_insert_7): New define_insns.
+
 2016-11-21  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000.md (movdi_internal32): Change constraints
index c932dac75a46d02e25ef4814cdb0cfad32484e9d..f3d1d7156e3a7245ebb1b3985b2627885ae2297d 100644 (file)
 }
   [(set_attr "type" "insert")])
 
+(define_insn "*rotlsi3_insert_5"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
+                       (match_operand:SI 2 "const_int_operand" "n,n"))
+               (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
+                       (match_operand:SI 4 "const_int_operand" "n,n"))))]
+  "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
+   && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
+  "@
+   rlwimi %0,%3,0,%4
+   rlwimi %0,%1,0,%2"
+  [(set_attr "type" "insert")])
+
+(define_insn "*rotldi3_insert_6"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
+                       (match_operand:DI 2 "const_int_operand" "n"))
+               (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
+                       (match_operand:DI 4 "const_int_operand" "n"))))]
+  "exact_log2 (-UINTVAL (operands[2])) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
+{
+  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
+  return "rldimi %0,%3,0,%5";
+}
+  [(set_attr "type" "insert")
+   (set_attr "size" "64")])
+
+(define_insn "*rotldi3_insert_7"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
+                       (match_operand:DI 4 "const_int_operand" "n"))
+               (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
+                       (match_operand:DI 2 "const_int_operand" "n"))))]
+  "exact_log2 (-UINTVAL (operands[2])) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
+{
+  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
+  return "rldimi %0,%3,0,%5";
+}
+  [(set_attr "type" "insert")
+   (set_attr "size" "64")])
+
 
 ; This handles the important case of multiple-precision shifts.  There is
 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.