]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/config/aarch64/aarch64.md
aarch64: Fix up casesi patterns for purecap
[gcc.git] / gcc / config / aarch64 / aarch64.md
index deca0004fedcb41c1e6b88ef3f8b4b187b4eecf8..d885eb8de3e464bed961603435dac3f8373e71b5 100644 (file)
 ;; Attribute that specifies whether the alternative uses MOVPRFX.
 (define_attr "movprfx" "no,yes" (const_string "no"))
 
+;; Attribute to specify that an alternative has the length of a single
+;; instruction plus a speculation barrier.
+(define_attr "sls_length" "none,retbr,casesi" (const_string "none"))
+
 (define_attr "length" ""
   (cond [(eq_attr "movprfx" "yes")
            (const_int 8)
-        ] (const_int 4)))
+
+        (eq_attr "sls_length" "retbr")
+          (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 4)
+                 (match_test "TARGET_SB") (const_int 8)]
+                (const_int 12))
+
+        (eq_attr "sls_length" "casesi")
+          (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 16)
+                 (match_test "TARGET_SB") (const_int 20)]
+                (const_int 24))
+       ]
+         (const_int 4)))
 
 ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has
 ;; no predicated insns.
 ;; -------------------------------------------------------------------
 
 (define_insn "indirect_jump"
-  [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
+  [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
   ""
-  "br\\t%0"
-  [(set_attr "type" "branch")]
+  {
+    output_asm_insn ("br\\t%0", operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+  }
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_insn "jump"
                                                 const0_rtx),
                                    operands[0], operands[2], operands[4]));
 
-    operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[3]));
+    operands[2] = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[3]));
     operands[2]
       = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[2], operands[0]),
                        UNSPEC_CASESI);
-    operands[2] = gen_rtx_MEM (DImode, operands[2]);
+    operands[2] = gen_rtx_MEM (Pmode, operands[2]);
     MEM_READONLY_P (operands[2]) = 1;
     MEM_NOTRAP_P (operands[2]) = 1;
-    emit_jump_insn (gen_casesi_dispatch (operands[2], operands[3]));
+
+    emit_jump_insn (gen_casesi_dispatch (Pmode, operands[2], operands[3]));
     DONE;
   }
 )
 
-(define_expand "casesi_dispatch"
+(define_expand "@casesi_dispatch<mode>"
   [(parallel
-    [(set (pc) (match_operand:DI 0 ""))
+    [(set (pc) (match_operand:ADDR 0 ""))
      (clobber (reg:CC CC_REGNUM))
-     (clobber (match_scratch:DI 2))
-     (clobber (match_scratch:DI 3))
-     (use (label_ref:DI (match_operand 1 "")))])]
+     (clobber (match_scratch:ADDR 2))
+     (clobber (match_scratch:ADDR 3))
+     (use (label_ref:ADDR (match_operand 1 "")))])]
   "")
 
 (define_insn "*casesi_dispatch"
   [(parallel
     [(set (pc)
-         (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
-                          (match_operand:SI 1 "register_operand" "r")]
+         (mem:ADDR (unspec [(match_operand:ADDR 0 "register_operand" "r")
+                            (match_operand:SI 1 "register_operand" "r")]
                        UNSPEC_CASESI)))
      (clobber (reg:CC CC_REGNUM))
-     (clobber (match_scratch:DI 3 "=r"))
-     (clobber (match_scratch:DI 4 "=r"))
-     (use (label_ref:DI (match_operand 2 "" "")))])]
+     (clobber (match_scratch:ADDR 3 "=r"))
+     (clobber (match_scratch:ADDR 4 "=r"))
+     (use (label_ref:ADDR (match_operand 2 "" "")))])]
   ""
   "*
   return aarch64_output_casesi (operands);
   "
-  [(set_attr "length" "16")
+  [(set_attr "sls_length" "casesi")
    (set_attr "type" "branch")]
 )
 
   [(return)]
   ""
   {
+    const char *ret = NULL;
     if (aarch64_return_address_signing_enabled ()
        && TARGET_ARMV8_3
        && !crtl->calls_eh_return)
       {
        if (aarch64_ra_sign_key == AARCH64_KEY_B)
-         return "retab";
+         ret = "retab";
        else
-         return "retaa";
+         ret = "retaa";
       }
-    return "ret";
+    else
+      ret = "ret";
+    output_asm_insn (ret, operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
   }
-  [(set_attr "type" "branch")]
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_expand "return"
 (define_insn "simple_return"
   [(simple_return)]
   ""
-  "ret"
-  [(set_attr "type" "branch")]
+  {
+    output_asm_insn ("ret", operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+  }
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_insn "*cb<optab><mode>1"
 )
 
 (define_insn "*call_insn"
-  [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "r, Usf"))
+  [(call (mem:DI (match_operand:ADDR 0 "aarch64_call_insn_operand" "Ucr, Usf"))
         (match_operand 1 "" ""))
    (unspec:DI [(match_operand:DI 2 "const_int_operand")] UNSPEC_CALLEE_ABI)
-   (clobber (reg:DI LR_REGNUM))]
+   (clobber (reg:ADDR LR_REGNUM))]
   ""
   "@
-  blr\\t%0
+  * return aarch64_indirect_call_asm (operands[0]);
   bl\\t%c0"
-  [(set_attr "type" "call, call")]
-)
+  [(set_attr "type" "call, call")])
 
 (define_expand "call_value"
   [(parallel
 
 (define_insn "*call_value_insn"
   [(set (match_operand 0 "" "")
-       (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "r, Usf"))
+       (call (mem:DI (match_operand:ADDR 1 "aarch64_call_insn_operand" "Ucr, Usf"))
                      (match_operand 2 "" "")))
    (unspec:DI [(match_operand:DI 3 "const_int_operand")] UNSPEC_CALLEE_ABI)
-   (clobber (reg:DI LR_REGNUM))]
+   (clobber (reg:ADDR LR_REGNUM))]
   ""
   "@
-  blr\\t%1
+  * return aarch64_indirect_call_asm (operands[1]);
   bl\\t%c1"
   [(set_attr "type" "call, call")]
 )
 )
 
 (define_insn "*sibcall_insn"
-  [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
+  [(call (mem:DI (match_operand:ADDR 0 "aarch64_call_insn_operand" "Ucs, Usf"))
         (match_operand 1 ""))
    (unspec:DI [(match_operand:DI 2 "const_int_operand")] UNSPEC_CALLEE_ABI)
    (return)]
   "SIBLING_CALL_P (insn)"
-  "@
-   br\\t%0
-   b\\t%c0"
-  [(set_attr "type" "branch, branch")]
+  {
+    if (which_alternative == 0)
+      {
+       output_asm_insn ("br\\t%0", operands);
+       return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+      }
+    return "b\\t%c0";
+  }
+  [(set_attr "type" "branch, branch")
+   (set_attr "sls_length" "retbr,none")]
 )
 
 (define_insn "*sibcall_value_insn"
   [(set (match_operand 0 "")
        (call (mem:DI
-               (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
+               (match_operand:ADDR 1 "aarch64_call_insn_operand" "Ucs, Usf"))
              (match_operand 2 "")))
    (unspec:DI [(match_operand:DI 3 "const_int_operand")] UNSPEC_CALLEE_ABI)
    (return)]
   "SIBLING_CALL_P (insn)"
-  "@
-   br\\t%1
-   b\\t%c1"
-  [(set_attr "type" "branch, branch")]
+  {
+    if (which_alternative == 0)
+      {
+       output_asm_insn ("br\\t%1", operands);
+       return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+      }
+    return "b\\t%c1";
+  }
+  [(set_attr "type" "branch, branch")
+   (set_attr "sls_length" "retbr,none")]
 )
 
 ;; Call subroutine returning any type.
 )
 
 (define_expand "mov<mode>"
-  [(set (match_operand:GPI 0 "nonimmediate_operand")
-       (match_operand:GPI 1 "general_operand"))]
+  [(set (match_operand:GPIC 0 "nonimmediate_operand")
+       (match_operand:GPIC 1 "general_operand"))]
   ""
   "
     if (MEM_P (operands[0]) && !MEM_VOLATILE_P (operands[0])
                                XEXP (operands[1], 0),
                                GET_MODE_SIZE (<SX:MODE>mode)))"
   "@
-   ldp\\t%w0, %w2, %1
-   ldp\\t%s0, %s2, %1"
+   ldp\\t%w0, %w2, %z1
+   ldp\\t%s0, %s2, %z1"
   [(set_attr "type" "load_8,neon_load1_2reg")
    (set_attr "arch" "*,fp")]
 )
                                XEXP (operands[1], 0),
                                GET_MODE_SIZE (<DX:MODE>mode)))"
   "@
-   ldp\\t%x0, %x2, %1
-   ldp\\t%d0, %d2, %1"
+   ldp\\t%x0, %x2, %z1
+   ldp\\t%d0, %d2, %z1"
   [(set_attr "type" "load_16,neon_load1_2reg")
    (set_attr "arch" "*,fp")]
 )
                    plus_constant (Pmode,
                                   XEXP (operands[1], 0),
                                   GET_MODE_SIZE (TFmode)))"
-  "ldp\\t%q0, %q2, %1"
+  "ldp\\t%q0, %q2, %z1"
   [(set_attr "type" "neon_ldp_q")
    (set_attr "fp" "yes")]
 )
                                XEXP (operands[0], 0),
                                GET_MODE_SIZE (<SX:MODE>mode)))"
   "@
-   stp\\t%w1, %w3, %0
-   stp\\t%s1, %s3, %0"
+   stp\\t%w1, %w3, %z0
+   stp\\t%s1, %s3, %z0"
   [(set_attr "type" "store_8,neon_store1_2reg")
    (set_attr "arch" "*,fp")]
 )
                                XEXP (operands[0], 0),
                                GET_MODE_SIZE (<DX:MODE>mode)))"
   "@
-   stp\\t%x1, %x3, %0
-   stp\\t%d1, %d3, %0"
+   stp\\t%x1, %x3, %z0
+   stp\\t%d1, %d3, %z0"
   [(set_attr "type" "store_16,neon_store1_2reg")
    (set_attr "arch" "*,fp")]
 )
                 plus_constant (Pmode,
                                XEXP (operands[0], 0),
                                GET_MODE_SIZE (TFmode)))"
-  "stp\\t%q1, %q3, %0"
+  "stp\\t%q1, %q3, %z0"
   [(set_attr "type" "neon_stp_q")
    (set_attr "fp" "yes")]
 )
 
 ;; Load pair with post-index writeback.  This is primarily used in function
 ;; epilogues.
-(define_insn "loadwb_pair<GPI:mode>_<P:mode>"
+;;
+;; MORELLO TODO: pure-cap.
+(define_insn "@loadwb_pair<GPI:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
+    [(set (match_operand:ADDR 0 "register_operand" "=k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+           (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
      (set (match_operand:GPI 2 "register_operand" "=r")
           (mem:GPI (match_dup 1)))
      (set (match_operand:GPI 3 "register_operand" "=r")
-          (mem:GPI (plus:P (match_dup 1)
-                   (match_operand:P 5 "const_int_operand" "n"))))])]
+          (mem:GPI (<ADDR:PLUS>:ADDR
+                    (match_dup 1)
+                    (match_operand:DI 5 "const_int_operand" "n"))))])]
   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
   "ldp\\t%<GPI:w>2, %<GPI:w>3, [%1], %4"
   [(set_attr "type" "load_<GPI:ldpstp_sz>")]
 )
 
-(define_insn "loadwb_pair<GPF:mode>_<P:mode>"
+(define_insn "@loadwb_pair<GPF:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
+    [(set (match_operand:ADDR 0 "register_operand" "=k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+            (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
      (set (match_operand:GPF 2 "register_operand" "=w")
           (mem:GPF (match_dup 1)))
      (set (match_operand:GPF 3 "register_operand" "=w")
-          (mem:GPF (plus:P (match_dup 1)
-                   (match_operand:P 5 "const_int_operand" "n"))))])]
+          (mem:GPF (<ADDR:PLUS>:ADDR
+                    (match_dup 1)
+                    (match_operand:DI 5 "const_int_operand" "n"))))])]
   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
   "ldp\\t%<GPF:w>2, %<GPF:w>3, [%1], %4"
   [(set_attr "type" "neon_load1_2reg")]
 )
 
-(define_insn "loadwb_pair<TX:mode>_<P:mode>"
+(define_insn "@loadwb_pair<TX:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
+    [(set (match_operand:ADDR 0 "register_operand" "=k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+           (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
      (set (match_operand:TX 2 "register_operand" "=w")
           (mem:TX (match_dup 1)))
      (set (match_operand:TX 3 "register_operand" "=w")
-          (mem:TX (plus:P (match_dup 1)
-                         (match_operand:P 5 "const_int_operand" "n"))))])]
+          (mem:TX (<ADDR:PLUS>:ADDR
+                   (match_dup 1)
+                   (match_operand:DI 5 "const_int_operand" "n"))))])]
   "TARGET_SIMD && INTVAL (operands[5]) == GET_MODE_SIZE (<TX:MODE>mode)"
   "ldp\\t%q2, %q3, [%1], %4"
   [(set_attr "type" "neon_ldp_q")]
 
 ;; Store pair with pre-index writeback.  This is primarily used in function
 ;; prologues.
-(define_insn "storewb_pair<GPI:mode>_<P:mode>"
+;;
+;; MORELLO TODO: pure-cap.
+(define_insn "@storewb_pair<GPI:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=&k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
-     (set (mem:GPI (plus:P (match_dup 0)
-                   (match_dup 4)))
+    [(set (match_operand:ADDR 0 "register_operand" "=&k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+           (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
+     (set (mem:GPI (<ADDR:PLUS>:ADDR (match_dup 0) (match_dup 4)))
           (match_operand:GPI 2 "register_operand" "r"))
-     (set (mem:GPI (plus:P (match_dup 0)
-                   (match_operand:P 5 "const_int_operand" "n")))
+     (set (mem:GPI (<ADDR:PLUS>:ADDR
+                    (match_dup 0)
+                    (match_operand:DI 5 "const_int_operand" "n")))
           (match_operand:GPI 3 "register_operand" "r"))])]
   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
   "stp\\t%<GPI:w>2, %<GPI:w>3, [%0, %4]!"
   [(set_attr "type" "store_<GPI:ldpstp_sz>")]
 )
 
-(define_insn "storewb_pair<GPF:mode>_<P:mode>"
+(define_insn "@storewb_pair<GPF:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=&k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
-     (set (mem:GPF (plus:P (match_dup 0)
-                   (match_dup 4)))
+    [(set (match_operand:ADDR 0 "register_operand" "=&k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+           (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
+     (set (mem:GPF (<ADDR:PLUS>:ADDR (match_dup 0) (match_dup 4)))
           (match_operand:GPF 2 "register_operand" "w"))
-     (set (mem:GPF (plus:P (match_dup 0)
-                   (match_operand:P 5 "const_int_operand" "n")))
+     (set (mem:GPF (<ADDR:PLUS>:ADDR
+                    (match_dup 0)
+                    (match_operand:DI 5 "const_int_operand" "n")))
           (match_operand:GPF 3 "register_operand" "w"))])]
   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
   "stp\\t%<GPF:w>2, %<GPF:w>3, [%0, %4]!"
   [(set_attr "type" "neon_store1_2reg<q>")]
 )
 
-(define_insn "storewb_pair<TX:mode>_<P:mode>"
+(define_insn "@storewb_pair<TX:mode>_<ADDR:mode>"
   [(parallel
-    [(set (match_operand:P 0 "register_operand" "=&k")
-          (plus:P (match_operand:P 1 "register_operand" "0")
-                  (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
-     (set (mem:TX (plus:P (match_dup 0)
-                         (match_dup 4)))
+    [(set (match_operand:ADDR 0 "register_operand" "=&k")
+          (<ADDR:PLUS>:ADDR
+           (match_operand:ADDR 1 "register_operand" "0")
+            (match_operand:DI 4 "aarch64_mem_pair_offset" "n")))
+     (set (mem:TX (<ADDR:PLUS>:ADDR (match_dup 0) (match_dup 4)))
           (match_operand:TX 2 "register_operand" "w"))
-     (set (mem:TX (plus:P (match_dup 0)
-                         (match_operand:P 5 "const_int_operand" "n")))
+     (set (mem:TX (<ADDR:PLUS>:ADDR
+                   (match_dup 0)
+                   (match_operand:DI 5 "const_int_operand" "n")))
           (match_operand:TX 3 "register_operand" "w"))])]
   "TARGET_SIMD
    && INTVAL (operands[5])
                plus_constant (Pmode,
                               XEXP (operands[1], 0),
                               GET_MODE_SIZE (SImode)))"
-  "ldpsw\\t%0, %2, %1"
+  "ldpsw\\t%0, %2, %z1"
   [(set_attr "type" "load_8")]
 )
 
                               XEXP (operands[1], 0),
                               GET_MODE_SIZE (SImode)))"
   "@
-   ldp\t%w0, %w2, %1
-   ldp\t%s0, %s2, %1"
+   ldp\t%w0, %w2, %z1
+   ldp\t%s0, %s2, %z1"
   [(set_attr "type" "load_8,neon_load1_2reg")
    (set_attr "arch" "*,fp")]
 )
   ""
 {
   machine_mode mode = GET_MODE (operands[0]);
-
-  emit_insn ((mode == DImode
-             ? gen_add_losym_di
-             : gen_add_losym_si) (operands[0],
-                                  operands[1],
-                                  operands[2]));
+  emit_insn (gen_add_losym (mode, operands[0], operands[1], operands[2]));
   DONE;
 })
 
-(define_insn "add_losym_<mode>"
+(define_insn "@add_losym_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (lo_sum:P (match_operand:P 1 "register_operand" "r")
                  (match_operand 2 "aarch64_valid_symref" "S")))]
   [(set_attr "type" "alu_imm")]
 )
 
-(define_insn "ldr_got_small_<mode>"
+(define_insn "@ldr_got_small_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "=r")
        (unspec:PTR [(mem:PTR (lo_sum:PTR
                              (match_operand:PTR 1 "register_operand" "r")
   [(set_attr "type" "load_4")]
 )
 
-(define_insn "ldr_got_small_28k_<mode>"
+(define_insn "@ldr_got_small_28k_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "=r")
        (unspec:PTR [(mem:PTR (lo_sum:PTR
                              (match_operand:PTR 1 "register_operand" "r")
   [(set_attr "type" "load_4")]
 )
 
-(define_insn "aarch64_load_tp_hard"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (unspec:DI [(const_int 0)] UNSPEC_TLS))]
+(define_insn "@aarch64_load_tp_hard_<mode>"
+  [(set (match_operand:ADDR 0 "register_operand" "=r")
+       (unspec:ADDR [(const_int 0)] UNSPEC_TLS))]
   ""
   "mrs\\t%0, tpidr_el0"
   [(set_attr "type" "mrs")]
   [(set_attr "type" "call")
    (set_attr "length" "16")])
 
-(define_insn "tlsie_small_<mode>"
-  [(set (match_operand:PTR 0 "register_operand" "=r")
-        (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
+(define_insn "@tlsie_small_<mode>"
+  [(set (match_operand:<PTR_OFF> 0 "register_operand" "=r")
+        (unspec:<PTR_OFF>
+         [(match_operand 1 "aarch64_tls_ie_symref" "S")
+          (match_operand:PTR 2 "register_operand" "r")]
                   UNSPEC_GOTSMALLTLS))]
-  ""
+  "aarch64_lowpart_regs_p (operands[0], operands[2])"
   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
   [(set_attr "type" "load_4")
    (set_attr "length" "8")]
    (set_attr "length" "8")]
 )
 
-(define_insn "tlsie_tiny_<mode>"
+(define_insn "@tlsie_tiny_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "=&r")
        (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
                     (match_operand:PTR 2 "register_operand" "r")]
    (set_attr "length" "8")]
 )
 
-(define_insn "tlsle12_<mode>"
+(define_insn "@tlsle12_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand:P 1 "register_operand" "r")
                   (match_operand 2 "aarch64_tls_le_symref" "S")]
    (set_attr "length" "4")]
 )
 
-(define_insn "tlsle24_<mode>"
+(define_insn "@tlsle24_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand:P 1 "register_operand" "r")
                   (match_operand 2 "aarch64_tls_le_symref" "S")]
    (set_attr "length" "8")]
 )
 
-(define_insn "tlsle32_<mode>"
+(define_insn "@tlsle32_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
                   UNSPEC_TLSLE32))]
    (set_attr "length" "8")]
 )
 
-(define_insn "tlsle48_<mode>"
+(define_insn "@tlsle48_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
                   UNSPEC_TLSLE48))]
    (set_attr "length" "12")]
 )
 
-(define_expand "tlsdesc_small_<mode>"
+(define_expand "@tlsdesc_small_<mode>"
   [(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
   "TARGET_TLS_DESC"
   {
   [(set (reg:PTR R0_REGNUM)
         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
                    UNSPEC_TLSDESC))
-   (clobber (reg:DI LR_REGNUM))
+   (clobber (reg:<P_OF_PTR> LR_REGNUM))
    (clobber (reg:CC CC_REGNUM))
-   (clobber (match_scratch:DI 1 "=r"))
-   (use (reg:DI FP_REGNUM))]
+   (clobber (match_scratch:<P_OF_PTR> 1 "=r"))
+   (use (reg:<P_OF_PTR> FP_REGNUM))]
   "TARGET_TLS_DESC && !TARGET_SVE"
-  "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
+  {
+    if (<MODE>mode == CADImode)
+      return "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1";
+    else
+      return "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1";
+  }
   [(set_attr "type" "call")
    (set_attr "length" "16")])
 
 
 (define_insn "stack_tie"
   [(set (mem:BLK (scratch))
-       (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
-                    (match_operand:DI 1 "register_operand" "rk")]
+       (unspec:BLK [(match_operand 0 "pmode_register_operand" "rk")
+                    (match_operand 1 "pmode_register_operand" "rk")]
                    UNSPEC_PRLG_STK))]
   ""
   ""
 (define_insn "aarch64_fjcvtzs"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI [(match_operand:DF 1 "register_operand" "w")]
-                  UNSPEC_FJCVTZS))]
+                  UNSPEC_FJCVTZS))
+   (clobber (reg:CC CC_REGNUM))]
   "TARGET_JSCVT"
   "fjcvtzs\\t%w0, %d1"
   [(set_attr "type" "f_cvtf2i")]
    (set_attr "type" "block")]
 )
 
-(define_insn "probe_stack_range"
-  [(set (match_operand:DI 0 "register_operand" "=rk")
-       (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")
-                            (match_operand:DI 2 "register_operand" "r")]
+(define_insn "probe_stack_range_<mode>"
+  [(set (match_operand:ADDR 0 "register_operand" "=rk")
+       (unspec_volatile:ADDR [(match_operand:ADDR 1 "register_operand" "0")
+                              (match_operand:ADDR 2 "register_operand" "r")]
                              UNSPECV_PROBE_STACK_RANGE))]
   ""
 {
 ;; probing loop.  We can't change the control flow during prologue and epilogue
 ;; code generation.  So we must emit a volatile unspec and expand it later on.
 
+;; MORELLO TODO The pattern here uses Pmode for everything, but the
+;; min_probe_threshold, adjustment, and guard_size should all be in POmode.
 (define_insn "@probe_sve_stack_clash_<mode>"
   [(set (match_operand:P 0 "register_operand" "=rk")
        (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
   {
     /* Generate access through the system register.  */
     rtx tmp_reg = gen_reg_rtx (mode);
-    if (mode == DImode)
-    {
-        emit_insn (gen_reg_stack_protect_address_di (tmp_reg));
-        emit_insn (gen_adddi3 (tmp_reg, tmp_reg,
-                              GEN_INT (aarch64_stack_protector_guard_offset)));
-    }
-    else
-    {
-       emit_insn (gen_reg_stack_protect_address_si (tmp_reg));
-       emit_insn (gen_addsi3 (tmp_reg, tmp_reg,
-                              GEN_INT (aarch64_stack_protector_guard_offset)));
-
-    }
+    emit_insn (gen_reg_stack_protect_address (mode, tmp_reg));
+    emit_insn (gen_add3_insn (tmp_reg, tmp_reg,
+                             GEN_INT (aarch64_stack_protector_guard_offset)));
     operands[1] = gen_rtx_MEM (mode, tmp_reg);
   }
-  
-  emit_insn ((mode == DImode
-             ? gen_stack_protect_set_di
-             : gen_stack_protect_set_si) (operands[0], operands[1]));
+
+  emit_insn (gen_stack_protect_set (mode, operands[0], operands[1]));
   DONE;
 })
 
-(define_insn "reg_stack_protect_address_<mode>"
+(define_insn "@reg_stack_protect_address_<mode>"
  [(set (match_operand:PTR 0 "register_operand" "=r")
        (unspec:PTR [(const_int 0)]
        UNSPEC_SSP_SYSREG))]
 
 ;; DO NOT SPLIT THIS PATTERN.  It is important for security reasons that the
 ;; canary value does not live beyond the life of this sequence.
-(define_insn "stack_protect_set_<mode>"
+(define_insn "@stack_protect_set_<mode>"
   [(set (match_operand:PTR 0 "memory_operand" "=m")
        (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
         UNSPEC_SP_SET))
    (match_operand 2)]
   ""
 {
-  rtx result;
   machine_mode mode = GET_MODE (operands[0]);
 
-  result = gen_reg_rtx(mode);
   if (aarch64_stack_protector_guard != SSP_GLOBAL)
   {
     /* Generate access through the system register. The
        mrs scratch_reg, <system_register>
        add scratch_reg, scratch_reg, :lo12:offset. */
     rtx tmp_reg = gen_reg_rtx (mode);
-    if (mode == DImode)
-    {
-       emit_insn (gen_reg_stack_protect_address_di (tmp_reg));
-       emit_insn (gen_adddi3 (tmp_reg, tmp_reg,
-                                     GEN_INT (aarch64_stack_protector_guard_offset)));
-    }
-    else
-    {
-       emit_insn (gen_reg_stack_protect_address_si (tmp_reg));
-       emit_insn (gen_addsi3 (tmp_reg, tmp_reg,
-                              GEN_INT (aarch64_stack_protector_guard_offset)));
 
-    }
+    emit_insn (gen_reg_stack_protect_address (mode, tmp_reg));
+    emit_insn (gen_add3_insn (tmp_reg, tmp_reg,
+                             GEN_INT (aarch64_stack_protector_guard_offset)));
     operands[1] = gen_rtx_MEM (mode, tmp_reg);
   }
-  emit_insn ((mode == DImode
-                 ? gen_stack_protect_test_di
-                 : gen_stack_protect_test_si) (result,
-                                               operands[0],
-                                               operands[1]));
-
-  if (mode == DImode)
-    emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
-                                   result, const0_rtx, operands[2]));
-  else
-    emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
-                                   result, const0_rtx, operands[2]));
+  emit_insn (gen_stack_protect_test (mode, operands[0], operands[1]));
+
+  rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
+  emit_jump_insn (gen_condjump (gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx),
+                               cc_reg, operands[2]));
   DONE;
 })
 
-(define_insn "stack_protect_test_<mode>"
-  [(set (match_operand:PTR 0 "register_operand" "=r")
-       (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
-                    (match_operand:PTR 2 "memory_operand" "m")]
-        UNSPEC_SP_TEST))
+;; DO NOT SPLIT THIS PATTERN.  It is important for security reasons that the
+;; canary value does not live beyond the end of this sequence.
+(define_insn "@stack_protect_test_<mode>"
+  [(set (reg:CC CC_REGNUM)
+       (unspec:CC [(match_operand:PTR 0 "memory_operand" "m")
+                   (match_operand:PTR 1 "memory_operand" "m")]
+                  UNSPEC_SP_TEST))
+   (clobber (match_scratch:PTR 2 "=&r"))
    (clobber (match_scratch:PTR 3 "=&r"))]
   ""
-  "ldr\t%<w>3, %1\;ldr\t%<w>0, %2\;eor\t%<w>0, %<w>3, %<w>0"
-  [(set_attr "length" "12")
+  "ldr\t%<w>2, %0\;ldr\t%<w>3, %1\;subs\t%<w>2, %<w>2, %<w>3\;mov\t%3, 0"
+  [(set_attr "length" "16")
    (set_attr "type" "multiple")])
 
-;; Write Floating-point Control Register.
-(define_insn "set_fpcr"
-  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
+;; Write into the Floating-point Status or Control Register.
+(define_insn "@aarch64_set_<fpscr_name><GPI:mode>"
+  [(unspec_volatile [(match_operand:GPI 0 "register_operand" "r")] SET_FPSCR)]
   ""
-  "msr\\tfpcr, %0"
+  "msr\\t<fpscr_name>, %0"
   [(set_attr "type" "mrs")])
 
-;; Read Floating-point Control Register.
-(define_insn "get_fpcr"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
-  ""
-  "mrs\\t%0, fpcr"
-  [(set_attr "type" "mrs")])
-
-;; Write Floating-point Status Register.
-(define_insn "set_fpsr"
-  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
-  ""
-  "msr\\tfpsr, %0"
-  [(set_attr "type" "mrs")])
-
-;; Read Floating-point Status Register.
-(define_insn "get_fpsr"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
+;; Read into the Floating-point Status or Control Register.
+(define_insn "@aarch64_get_<fpscr_name><GPI:mode>"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+        (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))]
   ""
-  "mrs\\t%0, fpsr"
+  "mrs\\t%0, <fpscr_name>"
   [(set_attr "type" "mrs")])
 
-
 ;; Define the subtract-one-and-jump insns so loop.c
 ;; knows what to generate.
 (define_expand "doloop_end"
 
 ;; SVE2.
 (include "aarch64-sve2.md")
+
+;; Morello
+(include "aarch64-morello.md")
This page took 0.065981 seconds and 5 git commands to generate.