pa.c (hppa_profile_hook): Split gen_call_profiler into separate insns.
authorRandolph Chung <tausq@debian.org>
Thu, 27 Nov 2003 20:02:36 +0000 (20:02 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Thu, 27 Nov 2003 20:02:36 +0000 (20:02 +0000)
* pa.c (hppa_profile_hook): Split gen_call_profiler into separate
insns.  Use the regular call expander for the call to the profiler.
* pa.md (call_profiler): Delete.
(load_offset_label_address): New insn to load the address of the
current function for the profiler.
(lcla1, lcla2): New insns to output a code label and load its address.

Co-Authored-By: John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
From-SVN: r74004

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.md

index ab9c3619e3eac51434d7d1ec83163e97f2f92d63..4af2b9288dc2b93216dc4fbe3d1d84c3ec006156 100644 (file)
@@ -1,3 +1,13 @@
+2003-11-27  Randolph Chung  <tausq@debian.org>
+           John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       * pa.c (hppa_profile_hook): Split gen_call_profiler into separate 
+       insns.  Use the regular call expander for the call to the profiler.
+       * pa.md (call_profiler): Delete.
+       (load_offset_label_address): New insn to load the address of the
+       current function for the profiler.
+       (lcla1, lcla2): New insns to output a code label and load its address.
+
 2003-11-27  Kazu Hirata  <kazu@cs.umass.edu>
 
        * final.c (final_scan_insn): Remove commented-out code.
index 8c8aebbf31b7f3b1f31c4f31e3342dbe558eec83..f724c43222c84b2be4726dd089d398161ca03bf0 100644 (file)
@@ -4039,12 +4039,17 @@ hppa_pic_save_rtx (void)
 void
 hppa_profile_hook (int label_no)
 {
+  /* We use SImode for the address of the function in both 32 and
+     64-bit code to avoid having to provide DImode versions of the
+     lcla2 and load_offset_label_address insn patterns.  */
+  rtx reg = gen_reg_rtx (SImode);
+  rtx label_rtx = gen_label_rtx ();
   rtx begin_label_rtx, call_insn;
   char begin_label_name[16];
 
   ASM_GENERATE_INTERNAL_LABEL (begin_label_name, FUNC_BEGIN_PROLOG_LABEL,
                               label_no);
-  begin_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (begin_label_name));
+  begin_label_rtx = gen_rtx_SYMBOL_REF (SImode, ggc_strdup (begin_label_name));
 
   if (TARGET_64BIT)
     emit_move_insn (arg_pointer_rtx,
@@ -4053,6 +4058,18 @@ hppa_profile_hook (int label_no)
 
   emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2));
 
+  /* The address of the function is loaded into %r25 with a instruction-
+     relative sequence that avoids the use of relocations.  The sequence
+     is split so that the load_offset_label_address instruction can
+     occupy the delay slot of the call to _mcount.  */
+  if (TARGET_PA_20)
+    emit_insn (gen_lcla2 (reg, label_rtx));
+  else
+    emit_insn (gen_lcla1 (reg, label_rtx));
+
+  emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25), 
+                                           reg, begin_label_rtx, label_rtx));
+
 #ifndef NO_PROFILE_COUNTERS
   {
     rtx count_label_rtx, addr, r24;
@@ -4065,35 +4082,31 @@ hppa_profile_hook (int label_no)
     r24 = gen_rtx_REG (Pmode, 24);
     emit_move_insn (r24, addr);
 
-    /* %r25 is set from within the output pattern.  */
     call_insn =
-      emit_call_insn (gen_call_profiler (gen_rtx_SYMBOL_REF (Pmode, "_mcount"),
-                                        GEN_INT (TARGET_64BIT ? 24 : 12),
-                                        begin_label_rtx));
+      emit_call_insn (gen_call (gen_rtx_MEM (Pmode, 
+                                            gen_rtx_SYMBOL_REF (Pmode, 
+                                                                "_mcount")),
+                               GEN_INT (TARGET_64BIT ? 24 : 12)));
 
     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24);
   }
 #else
-    /* %r25 is set from within the output pattern.  */
+
   call_insn =
-    emit_call_insn (gen_call_profiler (gen_rtx_SYMBOL_REF (Pmode, "_mcount"),
-                                      GEN_INT (TARGET_64BIT ? 16 : 8),
-                                      begin_label_rtx));
+    emit_call_insn (gen_call (gen_rtx_MEM (Pmode, 
+                                          gen_rtx_SYMBOL_REF (Pmode, 
+                                                              "_mcount")),
+                             GEN_INT (TARGET_64BIT ? 16 : 8)));
+
 #endif
 
+  use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 25));
+  use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 26));
+
   /* Indicate the _mcount call cannot throw, nor will it execute a
      non-local goto.  */
   REG_NOTES (call_insn)
     = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx, REG_NOTES (call_insn));
-
-  if (flag_pic)
-    {
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-      if (TARGET_64BIT)
-       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
-
-      emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
-    }
 }
 
 /* Fetch the return address for the frame COUNT steps up from
index aa0bfcbe783a95164ac3de723da06ed2b1622258..6f0cdcffb289da8645ee4cf753a8b9dda7a853a1 100644 (file)
   DONE;
 }")
 
-;; Special because we use the value placed in %r2 by the bl instruction
-;; from within its delay slot to set the value for the 2nd parameter to
-;; the call.
-(define_insn "call_profiler"
-  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
-        (match_operand 1 "" ""))
-   (use (match_operand 2 "" ""))
-   (use (reg:SI 25))
-   (use (reg:SI 26))
-   (clobber (reg:SI 2))]
+; Used by hppa_profile_hook to load the starting address of the current
+; function; operand 1 contains the address of the label in operand 3
+(define_insn "load_offset_label_address"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (plus:SI (match_operand:SI 1 "register_operand" "r")
+                (minus:SI (match_operand:SI 2 "" "")
+                          (label_ref:SI (match_operand 3 "" "")))))]
   ""
+  "ldo %2-%l3(%1),%0"
+  [(set_attr "type" "multi")
+   (set_attr "length" "4")])
+
+; Output a code label and load its address.
+(define_insn "lcla1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (label_ref:SI (match_operand 1 "" "")))
+   (const_int 0)]
+  "!TARGET_PA_20"
   "*
 {
-  rtx xoperands[3];
-
-  output_arg_descriptor (insn);
-
-  xoperands[0] = operands[0];
-  xoperands[1] = operands[2];
-  xoperands[2] = gen_label_rtx ();
-  output_asm_insn (\"{bl|b,l} %0,%%r2\;ldo %1-%2(%%r2),%%r25\", xoperands);
-
+  output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-                            CODE_LABEL_NUMBER (xoperands[2]));
+                                     CODE_LABEL_NUMBER (operands[1]));
   return \"\";
 }"
   [(set_attr "type" "multi")
    (set_attr "length" "8")])
 
+(define_insn "lcla2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (label_ref:SI (match_operand 1 "" "")))
+   (const_int 0)]
+  "TARGET_PA_20"
+  "*
+{
+  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+                                     CODE_LABEL_NUMBER (operands[1]));
+  return \"mfia %0\";
+}"
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
+
 (define_insn "blockage"
   [(unspec_volatile [(const_int 2)] 0)]
   ""