alpha.c (print_operand): Remove.
authorRichard Henderson <rth@redhat.com>
Thu, 5 Apr 2007 22:39:56 +0000 (15:39 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 5 Apr 2007 22:39:56 +0000 (15:39 -0700)
        * config/alpha/alpha.c (print_operand) [+]: Remove.
        (alpha_end_function): Print nop if call at end of function.
        * config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Remove +.
        * config/alpha/alpha.md (UNSPEC_LDGP1): New.
        (call_osf_1_er_noreturn, call_value_osf_1_er_noreturn): New.
        (call_osf_2_er_nogp, call_value_osf_2_er_nogp): New.
        (call_osf_2_er, call_value_osf_2_er): Merge the ldgp highpart into
        the call pattern. Update peepholes to match.

From-SVN: r123529

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md

index 906f1c37d717953643e9ea34248c6bbf633955a8..1df7b55640451cef5d96c2a874356f6036124a4c 100644 (file)
@@ -1,3 +1,14 @@
+2007-04-05  Richard Henderson  <rth@redhat.com>
+
+       * config/alpha/alpha.c (print_operand) [+]: Remove.
+       (alpha_end_function): Print nop if call at end of function.
+       * config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Remove +.
+       * config/alpha/alpha.md (UNSPEC_LDGP1): New.
+       (call_osf_1_er_noreturn, call_value_osf_1_er_noreturn): New.
+       (call_osf_2_er_nogp, call_value_osf_2_er_nogp): New.
+       (call_osf_2_er, call_value_osf_2_er): Merge the ldgp highpart into
+       the call pattern. Update peepholes to match.
+
 2007-04-05  Janis Johnson  <janis187@us.ibm.com>
 
        * doc/extend.texi (Other Builtins): Add decimal float variants
index 817aa47947946001694e616434c77d8063a155e4..976111462c14a50b5152baad0c3df52d9c6dad53 100644 (file)
@@ -4990,13 +4990,6 @@ print_operand (FILE *file, rtx x, int code)
       fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
       break;
 
-    case '+':
-      /* Generates a nop after a noreturn call at the very end of the
-        function.  */
-      if (next_real_insn (current_output_insn) == 0)
-       fprintf (file, "\n\tnop");
-      break;
-
     case '#':
       if (alpha_this_literal_sequence_number == 0)
        alpha_this_literal_sequence_number = alpha_next_sequence_number++;
@@ -8221,6 +8214,17 @@ alpha_expand_epilogue (void)
 void
 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
 {
+  rtx insn;
+
+  /* We output a nop after noreturn calls at the very end of the function to
+     ensure that the return address always remains in the caller's code range,
+     as not doing so might confuse unwinding engines.  */
+  insn = get_last_insn ();
+  if (!INSN_P (insn))
+    insn = prev_active_insn (insn);
+  if (GET_CODE (insn) == CALL_INSN)
+    output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
+
 #if TARGET_ABI_OPEN_VMS
   alpha_write_linkage (file, fnname, decl);
 #endif
index 382fe12056508e4d3439c577af219446a817c2c1..a52ae2c5727da66b6e1d2398d3f3995060e571ba 100644 (file)
@@ -1363,14 +1363,11 @@ do {                                            \
 
    -   Generates double precision suffix for floating point
        instructions (t for IEEE, g for VAX)
-
-   +   Generates a nop instruction after a noreturn call at the very end
-       of the function
    */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
   ((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
-   || (CODE) == '#' || (CODE) == '*' || (CODE) == '&' || (CODE) == '+')
+   || (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
 
 /* Print a memory address as an operand to reference that memory location.  */
 
index 2e9e13114054e714c300c098319f6c6ad1e806c5..7f323af83ea3bb8598d608ff74d7c4dd8852e048 100644 (file)
@@ -26,6 +26,7 @@
 
 (define_constants
   [(UNSPEC_ARG_HOME    0)
+   (UNSPEC_LDGP1       1)
    (UNSPEC_INSXH       2)
    (UNSPEC_MSKXH       3)
    (UNSPEC_CVTQL       4)
   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
 })
 
+(define_insn "*call_osf_1_er_noreturn"
+  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
+        (match_operand 1 "" ""))
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  "@
+   jsr $26,($27),0
+   bsr $26,%0\t\t!samegp
+   ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "*,*,8")])
+
 (define_insn "*call_osf_1_er"
   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
         (match_operand 1 "" ""))
        || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(call (mem:DI (match_dup 2))
                    (match_dup 1))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (use (reg:DI 29))
              (use (match_dup 0))
-             (use (match_dup 3))])]
+             (use (match_dup 3))
+             (clobber (reg:DI 26))])]
 {
   if (CONSTANT_P (operands[0]))
     {
          || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(call (mem:DI (match_dup 2))
                    (match_dup 1))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
              (use (match_dup 0))
-             (use (match_dup 4))])
-   (set (reg:DI 29)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
-   (set (reg:DI 29)
-       (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
+             (use (match_dup 4))
+             (clobber (reg:DI 26))])
+   (set (match_dup 5)
+       (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
 {
   if (CONSTANT_P (operands[0]))
     {
       operands[4] = const0_rtx;
     }
   operands[3] = GEN_INT (alpha_next_sequence_number++);
+  operands[5] = pic_offset_table_rtx;
 })
 
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
+(define_insn "*call_osf_2_er_nogp"
+  [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
+        (match_operand 1 "" ""))
+   (use (reg:DI 29))
+   (use (match_operand 2 "" ""))
+   (use (match_operand 3 "const_int_operand" ""))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+  "jsr $26,(%0),%2%J3"
+  [(set_attr "type" "jsr")])
 
 (define_insn "*call_osf_2_er"
   [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
         (match_operand 1 "" ""))
-   (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+   (set (reg:DI 29)
+       (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
+                  UNSPEC_LDGP1))
    (use (match_operand 2 "" ""))
-   (use (match_operand 3 "const_int_operand" ""))]
+   (use (match_operand 3 "const_int_operand" ""))
+   (clobber (reg:DI 26))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "jsr $26,(%0),%2%J3"
+  "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
   [(set_attr "type" "jsr")
-   (set_attr "cannot_copy" "true")])
-
-;; We output a nop after noreturn calls at the very end of the function to
-;; ensure that the return address always remains in the caller's code range,
-;; as not doing so might confuse unwinding engines.
-;;
-;; The potential change in insn length is not reflected in the length
-;; attributes at this stage. Since the extra space is only actually added at
-;; the very end of the compilation process (via final/print_operand), it
-;; really seems harmless and not worth the trouble of some extra computation
-;; cost and complexity.
+   (set_attr "cannot_copy" "true")
+   (set_attr "length" "8")])
 
 (define_insn "*call_osf_1_noreturn"
   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
   "@
-   jsr $26,($27),0%+
-   bsr $26,$%0..ng%+
-   jsr $26,%0%+"
+   jsr $26,($27),0
+   bsr $26,$%0..ng
+   jsr $26,%0"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,*,8")])
 
   [(set_attr "type" "jsr")
    (set_attr "length" "12,*,16")])
 
-;; Note that the DEC assembler expands "jmp foo" with $at, which
-;; doesn't do what we want.
 (define_insn "*sibcall_osf_1_er"
   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
         (match_operand 1 "" ""))
   [(set_attr "type" "jsr")
    (set_attr "length" "*,8")])
 
+;; Note that the DEC assembler expands "jmp foo" with $at, which
+;; doesn't do what we want.
 (define_insn "*sibcall_osf_1"
   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
         (match_operand 1 "" ""))
 
 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
 ;; want to have to include pal.h in our .s file.
-;;
-;; Technically the type for call_pal is jsr, but we use that for determining
-;; if we need a GP.  Use ibr instead since it has the same EV5 scheduling
-;; characteristics.
 (define_insn "imb"
   [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
   ""
 ;; The call patterns are at the end of the file because their
 ;; wildcard operand0 interferes with nice recognition.
 
+(define_insn "*call_value_osf_1_er_noreturn"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+             (match_operand 2 "" "")))
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  "@
+   jsr $26,($27),0
+   bsr $26,%1\t\t!samegp
+   ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "*,*,8")])
+
 (define_insn "*call_value_osf_1_er"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
   [(parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (match_dup 2)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (use (reg:DI 29))
              (use (match_dup 1))
-             (use (match_dup 4))])]
+             (use (match_dup 4))
+             (clobber (reg:DI 26))])]
 {
   if (CONSTANT_P (operands[1]))
     {
   [(parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (match_dup 2)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (set (match_dup 6)
+                  (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
              (use (match_dup 1))
-             (use (match_dup 5))])
-   (set (reg:DI 29)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
-   (set (reg:DI 29)
-       (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+             (use (match_dup 5))
+             (clobber (reg:DI 26))])
+   (set (match_dup 6)
+       (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
 {
   if (CONSTANT_P (operands[1]))
     {
       operands[5] = const0_rtx;
     }
   operands[4] = GEN_INT (alpha_next_sequence_number++);
+  operands[6] = pic_offset_table_rtx;
 })
 
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
-(define_insn "*call_value_osf_2_er"
+(define_insn "*call_value_osf_2_er_nogp"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
              (match_operand 2 "" "")))
-   (set (reg:DI 26)
-       (plus:DI (pc) (const_int 4)))
-   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+   (use (reg:DI 29))
    (use (match_operand 3 "" ""))
-   (use (match_operand 4 "" ""))]
+   (use (match_operand 4 "" ""))
+   (clobber (reg:DI 26))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "jsr $26,(%1),%3%J4"
+  [(set_attr "type" "jsr")])
+
+(define_insn "*call_value_osf_2_er"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
+             (match_operand 2 "" "")))
+   (set (reg:DI 29)
+       (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
+                  UNSPEC_LDGP1))
+   (use (match_operand 3 "" ""))
+   (use (match_operand 4 "" ""))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+  "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
   [(set_attr "type" "jsr")
-   (set_attr "cannot_copy" "true")])
+   (set_attr "cannot_copy" "true")
+   (set_attr "length" "8")])
 
 (define_insn "*call_value_osf_1_noreturn"
   [(set (match_operand 0 "" "")
   "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
   "@
-   jsr $26,($27),0%+
-   bsr $26,$%1..ng%+
-   jsr $26,%1%+"
+   jsr $26,($27),0
+   bsr $26,$%1..ng
+   jsr $26,%1"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,*,8")])
 
    (parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (const_int 0)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
              (use (match_dup 1))
-             (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))])
-   (set (match_dup 5)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
+             (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))
+             (clobber (reg:DI 26))])
    (set (match_dup 5)
        (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
 {
    (parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (const_int 0)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
              (use (match_dup 1))
-             (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))])
-   (set (reg:DI 29)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
-   (set (reg:DI 29)
-       (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+             (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))
+             (clobber (reg:DI 26))])
+   (set (match_dup 5)
+       (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
 {
   operands[3] = gen_rtx_REG (Pmode, 27);
   operands[4] = GEN_INT (alpha_next_sequence_number++);