This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Accessing IP on IA-64 with RTL
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: wilson at specifixinc dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 31 Jan 2005 14:20:48 -0800 (PST)
- Subject: Re: Accessing IP on IA-64 with RTL
> From: James E Wilson <wilson@specifixinc.com>
>
> If the glibc mcount is well written, we should be able to call it before
> or after the prologue. mcount calls are not visible outside the
> compiler/glibc, so this wouldn't be an ABI change. If the current glibc
> mcount doesn't work when called after the prologue, then yes we would
> need joint gcc/glibc patches, and I don't expect an HPUX hacker to do
> that for me.
I don't think the existing mcount can be called after the prologue. At
least I couldn't do it but that certainly doesn't mean you couldn't
figure out how to make it work. Long term it would be nice to change
the interface anyway because then we could get rid of the _mcount
assembly language stub in glibc.
> By the way, I just accepted from gas patches last week that add some
> error checking for unwind directives. As as result of this, gcc -pg
> gives a warning with the current assembler.
> tmp.s:18: Warning: Initial .prologue should precede any instructions
> This is the problem described in PR 12455. So this makes a fix a little
> more urgent. I will have to look at this myself when I have chance.
> --
> Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com
Here is what I have so far, it works with HP-UX based on some minimal
testing, but is obviously broken for the existing Linux mcount
interface.
Steve Ellcey
sje@cup.hp.com
2005-01-31 Steve Ellcey <sje@cup.hp.com>
PR target/12455
* config/ia64/ia64.c (mcount_func_rtx): New.
(ia64_compute_frame_size): Remove profile check.
(ia64_profile_hook): New.
* config/ia64/ia64-protos.h (ia64_profile_hook): New.
* config/ia64/ia64.h (FUNCTION_PROFILER): Make a NOOP.
(PROFILE_HOOK): New.
(NO_PROFILE_COUNTERS): New.
(PROFILE_BEFORE_PROLOGUE): Remove.
* config/ia64/ia64.md (*mov_pc): New.
*** gcc.orig/gcc/config/ia64/ia64.c Wed Jan 26 11:31:45 2005
--- gcc/gcc/config/ia64/ia64.c Mon Jan 31 14:09:09 2005
*************** gen_tls_get_addr (void)
*** 779,784 ****
--- 779,793 ----
return gen_tls_tga;
}
+ static GTY(()) rtx mcount_func_rtx;
+ static rtx
+ gen_mcount_func_rtx (void)
+ {
+ if (!mcount_func_rtx)
+ mcount_func_rtx = init_one_libfunc ("_mcount");
+ return mcount_func_rtx;
+ }
+
static GTY(()) rtx thread_pointer_rtx;
static rtx
gen_thread_pointer (void)
*************** ia64_compute_frame_size (HOST_WIDE_INT s
*** 1817,1823 ****
int spilled_gr_p = 0;
int spilled_fr_p = 0;
unsigned int regno;
- int i;
if (current_frame_info.initialized)
return;
--- 1826,1831 ----
*************** ia64_compute_frame_size (HOST_WIDE_INT s
*** 1865,1879 ****
for (regno = OUT_REG (7); regno >= OUT_REG (0); regno--)
if (regs_ever_live[regno])
break;
! i = regno - OUT_REG (0) + 1;
!
! /* When -p profiling, we need one output register for the mcount argument.
! Likewise for -a profiling for the bb_init_func argument. For -ax
! profiling, we need two output registers for the two bb_init_trace_func
! arguments. */
! if (current_function_profile)
! i = MAX (i, 1);
! current_frame_info.n_output_regs = i;
/* ??? No rotating register support yet. */
current_frame_info.n_rotate_regs = 0;
--- 1873,1879 ----
for (regno = OUT_REG (7); regno >= OUT_REG (0); regno--)
if (regs_ever_live[regno])
break;
! current_frame_info.n_output_regs = regno - OUT_REG (0) + 1;
/* ??? No rotating register support yet. */
current_frame_info.n_rotate_regs = 0;
*************** ia64_output_function_epilogue (FILE *fil
*** 3226,3231 ****
--- 3226,3263 ----
}
current_frame_info.initialized = 0;
+ }
+
+ void
+ ia64_profile_hook (int labelno)
+ {
+
+ if (TARGET_HPUX)
+ {
+ char buf[30];
+ const char *label_name;
+ rtx label, ip;
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+ label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
+ label = gen_rtx_SYMBOL_REF (Pmode, label_name);
+ ip = gen_reg_rtx (Pmode);
+ emit_insn (gen_ip_value (ip));
+ emit_library_call (gen_mcount_func_rtx (), LCT_NORMAL,
+ VOIDmode, 3,
+ gen_rtx_REG (Pmode, BR_REG (0)), Pmode,
+ ip, Pmode,
+ label, Pmode);
+ }
+ else
+ {
+ rtx ip = gen_reg_rtx (Pmode);
+ emit_insn (gen_ip_value (ip));
+ emit_library_call (gen_mcount_func_rtx (), LCT_NORMAL,
+ VOIDmode, 2,
+ gen_rtx_REG (Pmode, BR_REG (0)), Pmode,
+ ip, Pmode);
+ }
+
}
int
*** gcc.orig/gcc/config/ia64/ia64-protos.h Wed Jan 26 11:31:45 2005
--- gcc/gcc/config/ia64/ia64-protos.h Wed Jan 26 11:31:23 2005
*************** extern void ia64_reload_gp (void);
*** 55,60 ****
--- 55,61 ----
extern HOST_WIDE_INT ia64_initial_elimination_offset (int, int);
extern void ia64_expand_prologue (void);
extern void ia64_expand_epilogue (int);
+ extern void ia64_profile_hook (int);
extern int ia64_direct_return (void);
extern void ia64_expand_load_address (rtx, rtx);
*** gcc.orig/gcc/config/ia64/ia64.h Wed Jan 26 11:31:45 2005
--- gcc/gcc/config/ia64/ia64.h Mon Jan 31 14:08:21 2005
*************** do { \
*** 1436,1463 ****
/* Generating Code for Profiling. */
! /* A C statement or compound statement to output to FILE some assembler code to
! call the profiling subroutine `mcount'. */
#undef FUNCTION_PROFILER
! #define FUNCTION_PROFILER(FILE, LABELNO) \
! do { \
! char buf[20]; \
! ASM_GENERATE_INTERNAL_LABEL (buf, "LP", LABELNO); \
! fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", FILE); \
! if (TARGET_AUTO_PIC) \
! fputs ("\tmovl out3 = @gprel(", FILE); \
! else \
! fputs ("\taddl out3 = @ltoff(", FILE); \
! assemble_name (FILE, buf); \
! if (TARGET_AUTO_PIC) \
! fputs (");;\n", FILE); \
! else \
! fputs ("), r1;;\n", FILE); \
! fputs ("\tmov out1 = r1\n", FILE); \
! fputs ("\tmov out2 = b0\n", FILE); \
! fputs ("\tbr.call.sptk.many b0 = _mcount;;\n", FILE); \
! } while (0)
/* Trampolines for Nested Functions. */
--- 1436,1454 ----
/* Generating Code for Profiling. */
! /* A C statement or compound statement to generate RTL to
! call the profiling subroutine `_mcount'. */
+ #undef PROFILE_HOOK
+ #define PROFILE_HOOK(LABEL) ia64_profile_hook (LABEL)
+
+ /* All the work is done in PROFILE_HOOK, but still required. */
#undef FUNCTION_PROFILER
! #define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0)
!
! /* HP-UX needs a profile counter, Linux does not. */
! #undef NO_PROFILE_COUNTERS
! #define NO_PROFILE_COUNTERS (!TARGET_HPUX)
/* Trampolines for Nested Functions. */
*************** enum fetchop_code {
*** 2262,2272 ****
};
#define DONT_USE_BUILTIN_SETJMP
-
- /* Output any profiling code before the prologue. */
-
- #undef PROFILE_BEFORE_PROLOGUE
- #define PROFILE_BEFORE_PROLOGUE 1
/* Initialize library function table. */
#undef TARGET_INIT_LIBFUNCS
--- 2253,2258 ----
*** gcc.orig/gcc/config/ia64/ia64.md Wed Jan 26 11:31:45 2005
--- gcc/gcc/config/ia64/ia64.md Mon Jan 31 14:08:14 2005
***************
*** 5746,5751 ****
--- 5746,5762 ----
[(set_attr "itanium_class" "unknown")
(set_attr "predicable" "no")])
+
+ ;;
+ ;; Get instruction pointer
+
+ (define_insn "ip_value"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (pc))]
+ ""
+ "mov %0 = ip"
+ [(set_attr "itanium_class" "ialu")])
+
;; ??? The explicit stops are not ideal. It would be better if
;; rtx_needs_barrier took care of this, but this is something that can be
;; fixed later. This avoids an RSE DV.