]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/nios2/nios2.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.md
index a27df17670eaa5b377b7348944133d829d74ffe4..2a064946fe05df622ba3c45d6eab8adb9c10d144 100644 (file)
@@ -1,5 +1,5 @@
 ;; Machine Description for Altera Nios II.
-;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2024 Free Software Foundation, Inc.
 ;; Contributed by Jonah Graham (jgraham@altera.com) and 
 ;; Will Reece (wreece@altera.com).
 ;; Contributed by Mentor Graphics, Inc.
   UNSPECV_CUSTOM_XNXX
   UNSPECV_LDXIO
   UNSPECV_STXIO
+  UNSPECV_RDPRS
+  UNSPECV_FLUSHD
+  UNSPECV_FLUSHDA
+  UNSPECV_WRPIE
+  UNSPECV_ENI
+  UNSPECV_LDEX
+  UNSPECV_LDSEX
+  UNSPECV_STEX
+  UNSPECV_STSEX
 ])
 
 (define_c_enum "unspec" [
   "addi\\t%0, %1, %L2"
   [(set_attr "type" "alu")])
 
-(define_insn "movqi_internal"
+(define_insn_and_split "movqi_internal"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r")
         (match_operand:QI 1 "general_operand"       "rM,m,rI"))]
   "(register_operand (operands[0], QImode)
        gcc_unreachable ();
       }
   }
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+   || nios2_large_constant_memory_operand_p (operands[1]))"
+  [(set (match_dup 0) (match_dup 1))]
+  {
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+    else
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "st,ld,mov")])
 
-(define_insn "movhi_internal"
+(define_insn_and_split "movhi_internal"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r")
         (match_operand:HI 1 "general_operand"       "rM,m,rI"))]
   "(register_operand (operands[0], HImode)
     || reg_or_0_operand (operands[1], HImode))"
-  "@
-    sth%o0%.\\t%z1, %0
-    ldhu%o1%.\\t%0, %1
-    mov%i1%.\\t%0, %z1"
+  {
+    switch (which_alternative)
+      {
+      case 0:
+        return "sth%o0%.\\t%z1, %0";
+      case 1:
+        return "ldhu%o1%.\\t%0, %1";
+      case 2:
+        return "mov%i1%.\\t%0, %z1";
+      default:
+       gcc_unreachable ();
+      }
+  }
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+   || nios2_large_constant_memory_operand_p (operands[1]))"
+  [(set (match_dup 0) (match_dup 1))]
+  {
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+    else
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "st,ld,mov")])
 
-(define_insn "movsi_internal"
+(define_insn_and_split "movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r,   r")
         (match_operand:SI 1 "general_operand"       "rM,m,rIJK,S"))]
   "(register_operand (operands[0], SImode)
        gcc_unreachable ();
       }
   }
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+    || nios2_large_constant_memory_operand_p (operands[1])
+    || (nios2_large_constant_p (operands[1])
+        && !(CONST_INT_P (operands[1])
+            && (SMALL_INT_UNSIGNED (INTVAL (operands[1]))
+                || UPPER16_INT (INTVAL (operands[1]))))))"
+  [(set (match_dup 0) (match_dup 1))]
+  {
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+    else if (nios2_large_constant_memory_operand_p (operands[1]))
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+    else
+      operands[1] = nios2_split_large_constant (operands[1], operands[0]);
+  }
   [(set_attr "type" "st,ld,mov,alu")])
 
 (define_mode_iterator BH [QI HI])
 (define_mode_attr bhw [(QI "b") (HI "h") (SI "w")])
 (define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")])
 
-(define_insn "ld<bhw_uns>io"
+(define_insn_and_split "ld<bhw_uns>io"
   [(set (match_operand:BHW 0 "register_operand" "=r")
         (unspec_volatile:BHW
           [(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))]
   ""
   "ld<bhw_uns>io\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) 
+        (unspec_volatile:BHW [(match_dup 1)] UNSPECV_LDXIO))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "ld")])
 
 (define_expand "ld<bh>io"
   DONE;
 })
 
-(define_insn "ld<bh>io_signed"
+(define_insn_and_split "ld<bh>io_signed"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (sign_extend:SI
           (unspec_volatile:BH
             [(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))]
   ""
   "ld<bh>io\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) 
+        (sign_extend:SI (unspec_volatile:BH [(match_dup 1)] UNSPECV_LDXIO)))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "ld")])
 
-(define_insn "st<bhw>io"
+(define_insn_and_split "st<bhw>io"
   [(set (match_operand:BHW 0 "ldstio_memory_operand" "=w")
         (unspec_volatile:BHW
           [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
   ""
   "st<bhw>io\\t%z1, %0"
+  "nios2_large_constant_memory_operand_p (operands[0])"
+  [(set (match_dup 0) (unspec_volatile:BHW [(match_dup 1)] UNSPECV_STXIO))]
+  {
+    operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+  }
   [(set_attr "type" "st")])
 
 \f
 (define_mode_iterator QX [HI SI])
 
 ;; Zero extension patterns
-(define_insn "zero_extendhisi2"
+(define_insn_and_split "zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
   ""
   "@
     andi%.\\t%0, %1, 0xffff
     ldhu%o1%.\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type"     "and,ld")])
 
-(define_insn "zero_extendqi<mode>2"
+(define_insn_and_split "zero_extendqi<mode>2"
   [(set (match_operand:QX 0 "register_operand" "=r,r")
         (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
   ""
   "@
     andi%.\\t%0, %1, 0xff
     ldbu%o1%.\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) (zero_extend:QX (match_dup 1)))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type"     "and,ld")])
 
 ;; Sign extension patterns
 
-(define_insn "extendhisi2"
+(define_insn_and_split "extendhisi2"
   [(set (match_operand:SI 0 "register_operand"                     "=r,r")
         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand"  "r,m")))]
   ""
   "@
    #
    ldh%o1%.\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "alu,ld")])
 
-(define_insn "extendqi<mode>2"
+(define_insn_and_split "extendqi<mode>2"
   [(set (match_operand:QX 0 "register_operand"                     "=r,r")
         (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand"  "r,m")))]
   ""
   "@
    #
    ldb%o1%.\\t%0, %1"
+  "nios2_large_constant_memory_operand_p (operands[1])"
+  [(set (match_dup 0) (sign_extend:QX (match_dup 1)))]
+  {
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
+  }
   [(set_attr "type" "alu,ld")])
 
 ;; Split patterns for register alternative cases.
 (define_expand "return"
   [(simple_return)]
   "nios2_can_use_return_insn ()"
-  "")
+{
+  if (nios2_expand_return ())
+    DONE;
+})
 
 (define_insn "simple_return"
   [(simple_return)]
   "wrctl\\tctl%0, %z1"
   [(set_attr "type" "control")])
 
+(define_insn "rdprs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
+                             (match_operand:SI 2 "arith_operand"   "U")]
+         UNSPECV_RDPRS))]
+  ""
+  "rdprs\\t%0, %1, %2"
+  [(set_attr "type" "control")])
+
+;; Cache Instructions
+
+(define_insn "flushd"
+  [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+                       UNSPECV_FLUSHD)]
+  ""
+  "flushd\\t%0"
+  [(set_attr "type" "control")])
+
+(define_insn "flushda"
+  [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+                       UNSPECV_FLUSHDA)]
+  ""
+  "flushda\\t%0"
+  [(set_attr "type" "control")])
+
+;; R2 Instructions
+
+(define_insn "wrpie"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
+                            UNSPECV_WRPIE))]
+  "TARGET_ARCH_R2"
+  "wrpie\\t%0, %1"
+  [(set_attr "type" "control")])
+
+(define_insn "eni"
+  [(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
+                UNSPECV_ENI)]
+  "TARGET_ARCH_R2"
+  "eni\\t%0"
+  [(set_attr "type" "control")])
+
 ;; Trap patterns
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 3))]
   emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
   DONE;
 })
+
+;; Synchronization Primitives
+(include "sync.md")
+
+;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
+(include "ldstwm.md")
+