aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitar Dimitrov <dimitar@dinux.eu>2022-08-22 21:49:21 +0300
committerDimitar Dimitrov <dimitar@dinux.eu>2022-08-22 22:29:07 +0300
commit151effa22106a81f5835bb2dab7b95130f8fe2ef (patch)
tree682589f6804e21a54aa28d4d5cfce170e3f085a1
parent10dd6dea95c5fc41c789c6506338e101e0590a02 (diff)
downloadgcc-151effa22106a81f5835bb2dab7b95130f8fe2ef.zip
gcc-151effa22106a81f5835bb2dab7b95130f8fe2ef.tar.gz
gcc-151effa22106a81f5835bb2dab7b95130f8fe2ef.tar.bz2
pru: Add mov variants to load const -1
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>
-rw-r--r--gcc/config/pru/pru.md25
-rw-r--r--gcc/testsuite/gcc.target/pru/mov-m1.c18
2 files changed, 32 insertions, 11 deletions
diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md
index 0311092..02e1135 100644
--- a/gcc/config/pru/pru.md
+++ b/gcc/config/pru/pru.md
@@ -206,8 +206,8 @@
;;
;; 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
@@ -215,9 +215,10 @@
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
@@ -247,8 +248,8 @@
; 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)
@@ -258,6 +259,8 @@
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])));
@@ -265,18 +268,18 @@
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
index 0000000..0b31020
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/mov-m1.c
@@ -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;
+}