]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
pru: Add mov variants to load const -1
authorDimitar Dimitrov <dimitar@dinux.eu>
Mon, 22 Aug 2022 18:49:21 +0000 (21:49 +0300)
committerDimitar Dimitrov <dimitar@dinux.eu>
Mon, 22 Aug 2022 19:29:07 +0000 (22:29 +0300)
Use the FILL instruction to efficiently load -1 constants.

gcc/ChangeLog:

* config/pru/pru.md (prumov<mode>, mov<mode>): Add
variants for loading -1 consts.

gcc/testsuite/ChangeLog:

* gcc.target/pru/mov-m1.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
gcc/config/pru/pru.md
gcc/testsuite/gcc.target/pru/mov-m1.c [new file with mode: 0644]

index 031109236d6575371e73070bdafea767e9214f9f..02e11350a4dc1d684edeb8eb1a6ba2b31ae5421a 100644 (file)
 ;;
 ;; Note: Assume that Program Mem (T constraint) can fit in 16 bits!
 (define_insn "prumov<mode>"
-  [(set (match_operand:MOV32 0 "nonimmediate_operand" "=m,r,r,r,r,r")
-       (match_operand:MOV32 1 "general_operand"      "r,m,r,T,J,iF"))]
+  [(set (match_operand:MOV32 0 "nonimmediate_operand" "=m,r,r,r,r,r,r")
+       (match_operand:MOV32 1 "general_operand"      "r,m,r,T,J,Um,iF"))]
   ""
   "@
     sb%B0o\\t%b1, %0, %S0
     mov\\t%0, %1
     ldi\\t%0, %%pmem(%1)
     ldi\\t%0, %1
+    fill\\t%0, 4
     ldi32\\t%0, %1"
-  [(set_attr "type" "st,ld,alu,alu,alu,alu")
-   (set_attr "length" "4,4,4,4,4,8")])
+  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")
+   (set_attr "length" "4,4,4,4,4,4,8")])
 
 
 ;; Separate pattern for 8 and 16 bit moves, since LDI32 pseudo instruction
 ; Forcing DI reg alignment (akin to microblaze's HARD_REGNO_MODE_OK)
 ; does not seem efficient, and will violate TI ABI.
 (define_insn "mov<mode>"
-  [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r")
-       (match_operand:MOV64 1 "general_operand"      "r,m,r,T,J,nF"))]
+  [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r,r")
+       (match_operand:MOV64 1 "general_operand"      "r,m,Um,r,T,J,nF"))]
   ""
 {
   switch (which_alternative)
     case 1:
       return "lb%B1o\\t%b0, %1, %S1";
     case 2:
+      return "fill\\t%F0, 8";
+    case 3:
       /* careful with overlapping source and destination regs.  */
       gcc_assert (GP_REG_P (REGNO (operands[0])));
       gcc_assert (GP_REG_P (REGNO (operands[1])));
        return "mov\\t%N0, %N1\;mov\\t%F0, %F1";
       else
        return "mov\\t%F0, %F1\;mov\\t%N0, %N1";
-    case 3:
-      return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
     case 4:
-      return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
+      return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
     case 5:
+      return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
+    case 6:
       return "ldi32\\t%F0, %w1\;ldi32\\t%N0, %W1";
     default:
       gcc_unreachable ();
   }
 }
-  [(set_attr "type" "st,ld,alu,alu,alu,alu")
-   (set_attr "length" "4,4,8,8,8,16")])
+  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")
+   (set_attr "length" "4,4,4,8,8,8,16")])
 
 ;
 ; load_multiple pattern(s).
diff --git a/gcc/testsuite/gcc.target/pru/mov-m1.c b/gcc/testsuite/gcc.target/pru/mov-m1.c
new file mode 100644 (file)
index 0000000..0b31020
--- /dev/null
@@ -0,0 +1,18 @@
+/* Loading a register with constant -1 integer value.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+int
+test_set_m1_si (void)
+{
+  /* { dg-final { scan-assembler "fill\\tr14(.b0)?, 4" } } */
+  return -1;
+}
+
+long long
+test_set_m1_di (void)
+{
+  /* { dg-final { scan-assembler "fill\\tr14(.b0)?, 8" } } */
+  return -1;
+}