OSDN Git Service

PR target/60941
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
index d4827bd..3663b35 100644 (file)
@@ -28,6 +28,7 @@
   [(UNSPEC_MOVE_PIC            0)
    (UNSPEC_UPDATE_RETURN       1)
    (UNSPEC_LOAD_PCREL_SYM      2)
+   (UNSPEC_FRAME_BLOCKAGE      3)
    (UNSPEC_MOVE_PIC_LABEL      5)
    (UNSPEC_SETH44              6)
    (UNSPEC_SETM44              7)
@@ -41,6 +42,7 @@
    (UNSPEC_MOVE_GOTDATA                19)
 
    (UNSPEC_MEMBAR              20)
+   (UNSPEC_ATOMIC              21)
 
    (UNSPEC_TLSGD               30)
    (UNSPEC_TLSLDM              31)
@@ -97,7 +99,6 @@
 (define_constants
   [(UNSPECV_BLOCKAGE           0)
    (UNSPECV_FLUSHW             1)
-   (UNSPECV_GOTO               2)
    (UNSPECV_FLUSH              4)
    (UNSPECV_SAVEW              6)
    (UNSPECV_CAS                        8)
 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
 ;; that adds the PC value at the call point to register #(operand 3).
+;;
+;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
+;; because the RDPC instruction is extremely expensive and incurs a complete
+;; instruction pipeline flush.
 
 (define_insn "load_pcrel_sym<P:mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
 })
 
 (define_insn_and_split "*adddi3_insn_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
        (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
                 (match_operand:DI 2 "arith_double_operand" "rHI")))
    (clobber (reg:CC CC_REG))]
 }
   [(set_attr "type" "shift")])
 
-(define_insn "*ashlsi3_extend"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (ashift:SI (match_operand:SI 1 "register_operand" "r")
-                    (match_operand:SI 2 "arith_operand" "rI"))))]
-  "TARGET_ARCH64"
-{
-  if (GET_CODE (operands[2]) == CONST_INT)
-    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
-  return "sll\t%1, %2, %0";
-}
-  [(set_attr "type" "shift")])
-
 (define_expand "ashldi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ashift:DI (match_operand:DI 1 "register_operand" "r")
                   (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
    (clobber (match_scratch:SI 3 "=X,X,&h"))]
   "TARGET_V8PLUS"
-  "* return output_v8plus_shift (operands, insn, \"sllx\");"
+  "* return output_v8plus_shift (insn ,operands, \"sllx\");"
   [(set_attr "type" "multi")
    (set_attr "length" "5,5,6")])
 
                     (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
    (clobber (match_scratch:SI 3 "=X,X,&h"))]
   "TARGET_V8PLUS"
-  "* return output_v8plus_shift (operands, insn, \"srax\");"
+  "* return output_v8plus_shift (insn, operands, \"srax\");"
   [(set_attr "type" "multi")
    (set_attr "length" "5,5,6")])
 
                     (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
    (clobber (match_scratch:SI 3 "=X,X,&h"))]
   "TARGET_V8PLUS"
-  "* return output_v8plus_shift (operands, insn, \"srlx\");"
+  "* return output_v8plus_shift (insn, operands, \"srlx\");"
   [(set_attr "type" "multi")
    (set_attr "length" "5,5,6")])
 
   ""
   [(set_attr "length" "0")])
 
+;; Do not schedule instructions accessing memory before this point.
+
+(define_expand "frame_blockage"
+  [(set (match_dup 0)
+       (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+{
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+  MEM_VOLATILE_P (operands[0]) = 1;
+  operands[1] = stack_pointer_rtx;
+})
+
+(define_insn "*frame_blockage<P:mode>"
+  [(set (match_operand:BLK 0 "" "")
+       (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
+  ""
+  ""
+  [(set_attr "length" "0")])
+
 (define_expand "probe_stack"
   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
   ""
    (match_operand 3 "memory_operand" "")]
   ""
 {
+  rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
   rtx r_label = copy_to_reg (operands[1]);
   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
   rtx r_fp = operands[3];
   /* Restore frame pointer for containing function.  */
   emit_move_insn (hard_frame_pointer_rtx, r_fp);
   emit_stack_restore (SAVE_NONLOCAL, r_sp);
+  emit_move_insn (i7, r_i7);
 
   /* USE of hard_frame_pointer_rtx added for consistency;
      not clear if really needed.  */
   emit_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);
+  emit_use (i7);
 
-  /* We need to smuggle the load of %i7 as it is a fixed register.  */
-  emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
+  emit_jump_insn (gen_indirect_jump (r_label));
   emit_barrier ();
   DONE;
 })
 
-(define_insn "nonlocal_goto_internal"
-  [(unspec_volatile [(match_operand 0 "register_operand" "r")
-                     (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
-  "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
-{
-  if (flag_delayed_branch)
-    {
-      if (TARGET_ARCH64)
-       return "jmp\t%0\n\t ldx\t%1, %%i7";
-      else
-       return "jmp\t%0\n\t ld\t%1, %%i7";
-    }
-  else
-    {
-      if (TARGET_ARCH64)
-       return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
-      else
-       return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
-    }
-}
-  [(set (attr "type") (const_string "multi"))
-   (set (attr "length")
-       (if_then_else (eq_attr "delayed_branch" "true")
-                     (const_int 2)
-                     (const_int 3)))])
-
 (define_expand "builtin_setjmp_receiver"
   [(label_ref (match_operand 0 "" ""))]
   "flag_pic"
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:SI 1 "register_operand" "r")))
-       (match_operand:QI 0 "register_operand" "=r"))]
+       (match_operand:QI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH32"
   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:DI 1 "register_operand" "r")))
-       (match_operand:QI 0 "register_operand" "=r"))]
+       (match_operand:QI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH64"
   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:SI 1 "register_operand" "r")))
-       (match_operand:HI 0 "register_operand" "=r"))]
+       (match_operand:HI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH32"
   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:DI 1 "register_operand" "r")))
-       (match_operand:HI 0 "register_operand" "=r"))]
+       (match_operand:HI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH64"
   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:SI 1 "register_operand" "r")))
-       (match_operand:SI 0 "register_operand" "=r"))]
+       (match_operand:SI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH32"
   "st\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:DI 1 "register_operand" "r")))
-       (match_operand:SI 0 "register_operand" "=r"))]
+       (match_operand:SI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH64"
   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])
                                     (match_operand 3 "tld_symbolic_operand" "")]
                                    UNSPEC_TLSLDO)
                         (match_operand:DI 1 "register_operand" "r")))
-       (match_operand:DI 0 "register_operand" "=r"))]
+       (match_operand:DI 0 "register_operand" "r"))]
   "TARGET_TLS && TARGET_ARCH64"
   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
   [(set_attr "type" "store")])