This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch sparc problems in egcs
- To: Dan Nicolaescu <dann at godzilla dot ics dot uci dot edu>
- Subject: Re: patch sparc problems in egcs
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 21 Jun 1999 17:46:48 -0700
- Cc: egcs-patches at egcs dot cygnus dot com
- References: <in1bteifurd.fsf@rigel.oac.uci.edu>
On Mon, Jun 14, 1999 at 12:27:02PM -0700, Dan Nicolaescu wrote:
> I think this patch submitted in February has fallen through the cracks...
>
> http://egcs.cygnus.com/ml/egcs-patches/1999-02/msg00368.html
>
> My copyright assignment is now on file.
* config/sparc/sparc.h (FUNCTION_BLOCK_PROFILER): Add a nop after call.
This part of the patch is incorrect.
I've rearranged all of this profiling stuff to avoid the
unnecessary duplication.
r~
* sparc.c (sparc_override_options): Don't allow profiling for
code models other than medlow.
(sparc_function_profiler): New function from old FUNCTION_PROFILER
macro. Use ASM_GENERATE_INTERNAL_LABEL and MCOUNT_FUNCTION.
(sparc_function_block_profiler): Likewise. Use user_label_prefix.
(sparc_block_profiler): Likewise.
(sparc_function_block_profiler_exit): Likewise.
* sparc.h (FUNCTION_PROFILER): Call new sparc.c function.
(FUNCTION_BLOCK_PROFILER): Likewise.
(BLOCK_PROFILER): Likewise.
(FUNCTION_BLOCK_PROFILER_EXIT): Likewise.
(MCOUNT_FUNCTION): New.
* sparc/pbd.h (FUNCTION_PROFILER): Delete.
(FUNCTION_BLOCK_PROFILER, BLOCK_PROFILER): Delete.
* sparc/sun4o3.h (FUNCTION_PROFILER): Delete.
(MCOUNT_FUNCTION): New.
* sparc/sysv4.h (FUNCTION_BLOCK_PROFILER): Delete.
(BLOCK_PROFILER): Delete.
(MCOUNT_FUNCTION): New.
Index: config/sparc/pbd.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/pbd.h,v
retrieving revision 1.3
diff -c -p -d -r1.3 pbd.h
*** pbd.h 1998/12/16 21:13:19 1.3
--- pbd.h 1999/06/22 00:11:59
*************** Boston, MA 02111-1307, USA. */
*** 144,178 ****
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
fprintf (FILE, "\t.word .L%d\n", VALUE)
! /* Output assembler code to FILE to increment profiler label # LABELNO
! for profiling a function entry. */
!
! #undef FUNCTION_PROFILER
! #define FUNCTION_PROFILER(FILE, LABELNO) \
! fprintf (FILE, "\tsethi %%hi(.LP%d),%%o0\n\tcall mcount\n\tor %%lo(.LP%d),%%o0,%%o0\n", \
! (LABELNO), (LABELNO))
!
! /* Output assembler code to FILE to initialize this source file's
! basic block profiling info, if that has not already been done. */
!
! #undef FUNCTION_BLOCK_PROFILER
! #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
! fprintf (FILE, "\tsethi %%hi(.LPBX0),%%o0\n\tld [%%lo(.LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne .LPY%d\n\tnop\n\tcall ___bb_init_func\n\tnop\n.LPY%d:\n", \
! (LABELNO), (LABELNO))
!
! /* Output assembler code to FILE to increment the entry-count for
! the BLOCKNO'th basic block in this source file. */
!
! #undef BLOCK_PROFILER
! #define BLOCK_PROFILER(FILE, BLOCKNO) \
! { \
! int blockn = (BLOCKNO); \
! fprintf (FILE, "\tsethi %%hi(.LPBX2+%d),%%g1\n\tld [%%lo(.LPBX2+%d)+%%g1],%%g2\n\
! \tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(.LPBX2+%d)+%%g1]\n", \
! 4 * blockn, 4 * blockn, 4 * blockn); \
! CC_STATUS_INIT; /* We have clobbered %g1. Also %g2. */ \
! }
! /* This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
#undef ASM_OUTPUT_SOURCE_LINE(file, line)
#define ASM_OUTPUT_SOURCE_LINE(file, line) \
--- 144,150 ----
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
fprintf (FILE, "\t.word .L%d\n", VALUE)
! /* This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
#undef ASM_OUTPUT_SOURCE_LINE(file, line)
#define ASM_OUTPUT_SOURCE_LINE(file, line) \
Index: config/sparc/sparc.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/sparc.c,v
retrieving revision 1.69
diff -c -p -d -r1.69 sparc.c
*** sparc.c 1999/04/18 13:09:33 1.69
--- sparc.c 1999/06/22 00:12:00
*************** sparc_override_options ()
*** 365,370 ****
--- 365,376 ----
/* Do various machine dependent initializations. */
sparc_init_modes ();
+
+ if ((profile_flag || profile_block_flag)
+ && sparc_cmodel != CM_MEDLOW)
+ {
+ error ("profiling does not support code models other than medlow");
+ }
}
/* Miscellaneous utilities. */
*************** sparc_return_peephole_ok (dest, src)
*** 7530,7533 ****
--- 7536,7843 ----
&& (GET_CODE (src) != REG || ! IN_OR_GLOBAL_P (src)))
return 0;
return IN_OR_GLOBAL_P (dest);
+ }
+
+ /* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry.
+
+ 32 bit sparc uses %g2 as the STATIC_CHAIN_REGNUM which gets clobbered
+ during profiling so we need to save/restore it around the call to mcount.
+ We're guaranteed that a save has just been done, and we use the space
+ allocated for intreg/fpreg value passing. */
+
+ void
+ sparc_function_profiler (file, labelno)
+ FILE *file;
+ int labelno;
+ {
+ char buf[32];
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+
+ if (! TARGET_ARCH64)
+ fputs ("\tst\t%g2,[%fp-4]\n", file);
+
+ fputs ("\tsethi\t%hi(", file);
+ assemble_name (file, buf);
+ fputs ("),%o0\n", file);
+
+ fputs ("\tcall\t", file);
+ assemble_name (file, MCOUNT_FUNCTION);
+ putc ('\n', file);
+
+ fputs ("\t or\t%o0,%lo(", file);
+ assemble_name (file, buf);
+ fputs ("),%o0\n", file);
+
+ if (! TARGET_ARCH64)
+ fputs ("\tld\t[%fp-4],%g2\n", file);
+ }
+
+
+ /* The following macro shall output assembler code to FILE
+ to initialize basic-block profiling.
+
+ If profile_block_flag == 2
+
+ Output code to call the subroutine `__bb_init_trace_func'
+ and pass two parameters to it. The first parameter is
+ the address of a block allocated in the object module.
+ The second parameter is the number of the first basic block
+ of the function.
+
+ The name of the block is a local symbol made with this statement:
+
+ ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
+
+ Of course, since you are writing the definition of
+ `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
+ can take a short cut in the definition of this macro and use the
+ name that you know will result.
+
+ The number of the first basic block of the function is
+ passed to the macro in BLOCK_OR_LABEL.
+
+ If described in a virtual assembler language the code to be
+ output looks like:
+
+ parameter1 <- LPBX0
+ parameter2 <- BLOCK_OR_LABEL
+ call __bb_init_trace_func
+
+ else if profile_block_flag != 0
+
+ Output code to call the subroutine `__bb_init_func'
+ and pass one single parameter to it, which is the same
+ as the first parameter to `__bb_init_trace_func'.
+
+ The first word of this parameter is a flag which will be nonzero if
+ the object module has already been initialized. So test this word
+ first, and do not call `__bb_init_func' if the flag is nonzero.
+ Note: When profile_block_flag == 2 the test need not be done
+ but `__bb_init_trace_func' *must* be called.
+
+ BLOCK_OR_LABEL may be used to generate a label number as a
+ branch destination in case `__bb_init_func' will not be called.
+
+ If described in a virtual assembler language the code to be
+ output looks like:
+
+ cmp (LPBX0),0
+ jne local_label
+ parameter1 <- LPBX0
+ call __bb_init_func
+ local_label:
+
+ */
+
+ void
+ sparc_function_block_profiler(file, block_or_label)
+ FILE *file;
+ int block_or_label;
+ {
+ char LPBX[32];
+ ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 0);
+
+ if (profile_block_flag == 2)
+ {
+ fputs ("\tsethi\t%hi(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%o0\n", file);
+
+ fprintf (file, "\tsethi\t%%hi(%d),%%o1\n", block_or_label);
+
+ fputs ("\tor\t%o0,%lo(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%o0\n", file);
+
+ fprintf (file, "\tcall\t%s__bb_init_trace_func\n", user_label_prefix);
+
+ fprintf (file, "\tor\t%%o1,%%lo(%d),%%o1\n", block_or_label);
+ }
+ else if (profile_block_flag != 0)
+ {
+ char LPBY[32];
+ ASM_GENERATE_INTERNAL_LABEL (LPBY, "LPBY", block_or_label);
+
+ fputs ("\tsethi\t%hi(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%o0\n", file);
+
+ fputs ("\tld\t[%lo(", file);
+ assemble_name (file, LPBX);
+ fputs (")+%o0],%o1\n", file);
+
+ fputs ("\ttst\t%o1\n", file);
+
+ if (TARGET_V9)
+ {
+ fputs ("\tbne,pn\t%icc,", file);
+ assemble_name (file, LPBY);
+ putc ('\n', file);
+ }
+ else
+ {
+ fputs ("\tbne\t", file);
+ assemble_name (file, LPBY);
+ putc ('\n', file);
+ }
+
+ fputs ("\t or\t%o0,%lo(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%o0\n", file);
+
+ fprintf (file, "\tcall\t%s__bb_init_func\n\t nop\n", user_label_prefix);
+
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LPBY", block_or_label);
+ }
+ }
+
+ /* The following macro shall output assembler code to FILE
+ to increment a counter associated with basic block number BLOCKNO.
+
+ If profile_block_flag == 2
+
+ Output code to initialize the global structure `__bb' and
+ call the function `__bb_trace_func' which will increment the
+ counter.
+
+ `__bb' consists of two words. In the first word the number
+ of the basic block has to be stored. In the second word
+ the address of a block allocated in the object module
+ has to be stored.
+
+ The basic block number is given by BLOCKNO.
+
+ The address of the block is given by the label created with
+
+ ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
+
+ by FUNCTION_BLOCK_PROFILER.
+
+ Of course, since you are writing the definition of
+ `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
+ can take a short cut in the definition of this macro and use the
+ name that you know will result.
+
+ If described in a virtual assembler language the code to be
+ output looks like:
+
+ move BLOCKNO -> (__bb)
+ move LPBX0 -> (__bb+4)
+ call __bb_trace_func
+
+ Note that function `__bb_trace_func' must not change the
+ machine state, especially the flag register. To grant
+ this, you must output code to save and restore registers
+ either in this macro or in the macros MACHINE_STATE_SAVE
+ and MACHINE_STATE_RESTORE. The last two macros will be
+ used in the function `__bb_trace_func', so you must make
+ sure that the function prologue does not change any
+ register prior to saving it with MACHINE_STATE_SAVE.
+
+ else if profile_block_flag != 0
+
+ Output code to increment the counter directly.
+ Basic blocks are numbered separately from zero within each
+ compiled object module. The count associated with block number
+ BLOCKNO is at index BLOCKNO in an array of words; the name of
+ this array is a local symbol made with this statement:
+
+ ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
+
+ Of course, since you are writing the definition of
+ `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
+ can take a short cut in the definition of this macro and use the
+ name that you know will result.
+
+ If described in a virtual assembler language, the code to be
+ output looks like:
+
+ inc (LPBX2+4*BLOCKNO)
+
+ */
+
+ void
+ sparc_block_profiler(file, blockno)
+ FILE *file;
+ int blockno;
+ {
+ char LPBX[32];
+
+ if (profile_block_flag == 2)
+ {
+ ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 0);
+
+ fprintf (file, "\tsethi\t%%hi(%s__bb),%%g1\n", user_label_prefix);
+ fprintf (file, "\tsethi\t%%hi(%d),%%g2\n", blockno);
+ fprintf (file, "\tor\t%%g1,%%lo(%s__bb),%%g1\n", user_label_prefix);
+ fprintf (file, "\tor\t%%g2,%%lo(%d),%%g2\n", blockno);
+
+ fputs ("\tst\t%g2,[%g1]\n", file);
+
+ fputs ("\tsethi\t%hi(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%g2\n", file);
+
+ fputs ("\tor\t%o0,%lo(", file);
+ assemble_name (file, LPBX);
+ fputs ("),%g2\n", file);
+
+ fputs ("\tst\t%g2,[%g1+4]\n", file);
+ fputs ("\tmov\t%o7,%g2\n", file);
+
+ fprintf (file, "\tcall\t%s__bb_trace_func\n\t nop\n", user_label_prefix);
+
+ fputs ("\tmov\t%g2,%o7\n", file);
+ }
+ else if (profile_block_flag != 0)
+ {
+ ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 2);
+
+ fputs ("\tsethi\t%hi(", file);
+ assemble_name (file, LPBX);
+ fprintf (file, "+%d),%%g1\n", blockno*4);
+
+ fputs ("\tld\t[%g1+%lo(", file);
+ assemble_name (file, LPBX);
+ fprintf (file, "+%d)],%%g2\n", blockno*4);
+
+ fputs ("\tadd\t%g2,1,%g2\n", file);
+
+ fputs ("\tst\t%g2,[%g1+%lo(", file);
+ assemble_name (file, LPBX);
+ fprintf (file, "+%d)]\n", blockno*4);
+ }
+ }
+
+ /* The following macro shall output assembler code to FILE
+ to indicate a return from function during basic-block profiling.
+
+ If profile_block_flag == 2:
+
+ Output assembler code to call function `__bb_trace_ret'.
+
+ Note that function `__bb_trace_ret' must not change the
+ machine state, especially the flag register. To grant
+ this, you must output code to save and restore registers
+ either in this macro or in the macros MACHINE_STATE_SAVE_RET
+ and MACHINE_STATE_RESTORE_RET. The last two macros will be
+ used in the function `__bb_trace_ret', so you must make
+ sure that the function prologue does not change any
+ register prior to saving it with MACHINE_STATE_SAVE_RET.
+
+ else if profile_block_flag != 0:
+
+ The macro will not be used, so it need not distinguish
+ these cases.
+ */
+
+ void
+ sparc_function_block_profiler_exit(file)
+ FILE *file;
+ {
+ if (profile_block_flag == 2)
+ fprintf (file, "\tcall\t%s__bb_trace_ret\n\tnop\n", user_label_prefix);
+ else
+ abort ();
}
Index: config/sparc/sparc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/sparc.h,v
retrieving revision 1.66
diff -c -p -d -r1.66 sparc.h
*** sparc.h 1999/06/21 03:45:19 1.66
--- sparc.h 1999/06/22 00:12:00
*************** do { \
*** 1844,2083 ****
current_function_uses_only_leaf_regs))
/* Output assembler code to FILE to increment profiler label # LABELNO
! for profiling a function entry.
!
! 32 bit sparc uses %g2 as the STATIC_CHAIN_REGNUM which gets clobbered
! during profiling so we need to save/restore it around the call to mcount.
! We're guaranteed that a save has just been done, and we use the space
! allocated for intreg/fpreg value passing. */
!
! #define FUNCTION_PROFILER(FILE, LABELNO) \
! do { \
! char buf[20]; \
! ASM_GENERATE_INTERNAL_LABEL (buf, "LP", (LABELNO)); \
! if (! TARGET_ARCH64) \
! fputs ("\tst %g2,[%fp-4]\n", FILE); \
! fputs ("\tsethi %hi(", FILE); \
! assemble_name (FILE, buf); \
! fputs ("),%o0\n", FILE); \
! fputs ("\tcall mcount\n\tadd %o0,%lo(", FILE); \
! assemble_name (FILE, buf); \
! fputs ("),%o0\n", FILE); \
! if (! TARGET_ARCH64) \
! fputs ("\tld [%fp-4],%g2\n", FILE); \
! } while (0)
!
! /* There are three profiling modes for basic blocks available.
! The modes are selected at compile time by using the options
! -a or -ax of the gnu compiler.
! The variable `profile_block_flag' will be set according to the
! selected option.
!
! profile_block_flag == 0, no option used:
!
! No profiling done.
!
! profile_block_flag == 1, -a option used.
!
! Count frequency of execution of every basic block.
!
! profile_block_flag == 2, -ax option used.
! Generate code to allow several different profiling modes at run time.
! Available modes are:
! Produce a trace of all basic blocks.
! Count frequency of jump instructions executed.
! In every mode it is possible to start profiling upon entering
! certain functions and to disable profiling of some other functions.
! The result of basic-block profiling will be written to a file `bb.out'.
! If the -ax option is used parameters for the profiling will be read
! from file `bb.in'.
! */
/* The following macro shall output assembler code to FILE
! to initialize basic-block profiling.
!
! If profile_block_flag == 2
!
! Output code to call the subroutine `__bb_init_trace_func'
! and pass two parameters to it. The first parameter is
! the address of a block allocated in the object module.
! The second parameter is the number of the first basic block
! of the function.
!
! The name of the block is a local symbol made with this statement:
!
! ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
!
! Of course, since you are writing the definition of
! `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
! can take a short cut in the definition of this macro and use the
! name that you know will result.
!
! The number of the first basic block of the function is
! passed to the macro in BLOCK_OR_LABEL.
!
! If described in a virtual assembler language the code to be
! output looks like:
!
! parameter1 <- LPBX0
! parameter2 <- BLOCK_OR_LABEL
! call __bb_init_trace_func
!
! else if profile_block_flag != 0
!
! Output code to call the subroutine `__bb_init_func'
! and pass one single parameter to it, which is the same
! as the first parameter to `__bb_init_trace_func'.
!
! The first word of this parameter is a flag which will be nonzero if
! the object module has already been initialized. So test this word
! first, and do not call `__bb_init_func' if the flag is nonzero.
! Note: When profile_block_flag == 2 the test need not be done
! but `__bb_init_trace_func' *must* be called.
!
! BLOCK_OR_LABEL may be used to generate a label number as a
! branch destination in case `__bb_init_func' will not be called.
!
! If described in a virtual assembler language the code to be
! output looks like:
!
! cmp (LPBX0),0
! jne local_label
! parameter1 <- LPBX0
! call __bb_init_func
! local_label:
!
! */
! #define FUNCTION_BLOCK_PROFILER(FILE, BLOCK_OR_LABEL) \
! do \
! { \
! int bol = (BLOCK_OR_LABEL); \
! switch (profile_block_flag) \
! { \
! case 2: \
! fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tor %%o0,%%lo(LPBX0),%%o0\n\tsethi %%hi(%d),%%o1\n\tcall ___bb_init_trace_func\n\tor %%o1,%%lo(%d),%%o1\n",\
! bol, bol); \
! break; \
! default: \
! fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n",\
! bol, bol); \
! break; \
! } \
! } \
! while (0)
/* The following macro shall output assembler code to FILE
! to increment a counter associated with basic block number BLOCKNO.
!
! If profile_block_flag == 2
!
! Output code to initialize the global structure `__bb' and
! call the function `__bb_trace_func' which will increment the
! counter.
!
! `__bb' consists of two words. In the first word the number
! of the basic block has to be stored. In the second word
! the address of a block allocated in the object module
! has to be stored.
!
! The basic block number is given by BLOCKNO.
!
! The address of the block is given by the label created with
!
! ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
!
! by FUNCTION_BLOCK_PROFILER.
!
! Of course, since you are writing the definition of
! `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
! can take a short cut in the definition of this macro and use the
! name that you know will result.
!
! If described in a virtual assembler language the code to be
! output looks like:
!
! move BLOCKNO -> (__bb)
! move LPBX0 -> (__bb+4)
! call __bb_trace_func
!
! Note that function `__bb_trace_func' must not change the
! machine state, especially the flag register. To grant
! this, you must output code to save and restore registers
! either in this macro or in the macros MACHINE_STATE_SAVE
! and MACHINE_STATE_RESTORE. The last two macros will be
! used in the function `__bb_trace_func', so you must make
! sure that the function prologue does not change any
! register prior to saving it with MACHINE_STATE_SAVE.
!
! else if profile_block_flag != 0
!
! Output code to increment the counter directly.
! Basic blocks are numbered separately from zero within each
! compiled object module. The count associated with block number
! BLOCKNO is at index BLOCKNO in an array of words; the name of
! this array is a local symbol made with this statement:
!
! ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
!
! Of course, since you are writing the definition of
! `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
! can take a short cut in the definition of this macro and use the
! name that you know will result.
!
! If described in a virtual assembler language, the code to be
! output looks like:
!
! inc (LPBX2+4*BLOCKNO)
!
! */
! #define BLOCK_PROFILER(FILE, BLOCKNO) \
! do \
! { \
! int blockn = (BLOCKNO); \
! switch (profile_block_flag) \
! { \
! case 2: \
! fprintf (FILE, "\tsethi %%hi(___bb),%%g1\n\tsethi %%hi(%d),%%g2\n\tor %%g2,%%lo(%d),%%g2\n\tst %%g2,[%%lo(___bb)+%%g1]\n\tsethi %%hi(LPBX0),%%g2\n\tor %%g2,%%lo(LPBX0),%%g2\n\tadd 4,%%g1,%%g1\n\tst %%g2,[%%lo(___bb)+%%g1]\n\tmov %%o7,%%g2\n\tcall ___bb_trace_func\n\tnop\n\tmov %%g2,%%o7\n",\
! blockn, blockn); \
! break; \
! default: \
! fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\
! \tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \
! 4 * blockn, 4 * blockn, 4 * blockn); \
! break; \
! } \
! } \
! while(0)
/* The following macro shall output assembler code to FILE
! to indicate a return from function during basic-block profiling.
!
! If profiling_block_flag == 2:
!
! Output assembler code to call function `__bb_trace_ret'.
!
! Note that function `__bb_trace_ret' must not change the
! machine state, especially the flag register. To grant
! this, you must output code to save and restore registers
! either in this macro or in the macros MACHINE_STATE_SAVE_RET
! and MACHINE_STATE_RESTORE_RET. The last two macros will be
! used in the function `__bb_trace_ret', so you must make
! sure that the function prologue does not change any
! register prior to saving it with MACHINE_STATE_SAVE_RET.
!
! else if profiling_block_flag != 0:
!
! The macro will not be used, so it need not distinguish
! these cases.
! */
#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \
! fprintf (FILE, "\tcall ___bb_trace_ret\n\tnop\n" );
/* The function `__bb_trace_func' is called in every basic block
and is not allowed to change the machine state. Saving (restoring)
--- 1844,1875 ----
current_function_uses_only_leaf_regs))
/* Output assembler code to FILE to increment profiler label # LABELNO
! for profiling a function entry. */
! #define FUNCTION_PROFILER(FILE, LABELNO) \
! sparc_function_profiler(FILE, LABELNO)
! /* Set the name of the mcount function for the system. */
! #define MCOUNT_FUNCTION "*mcount"
/* The following macro shall output assembler code to FILE
! to initialize basic-block profiling. */
! #define FUNCTION_BLOCK_PROFILER(FILE, BLOCK_OR_LABEL) \
! sparc_function_block_profiler(FILE, BLOCK_OR_LABEL)
/* The following macro shall output assembler code to FILE
! to increment a counter associated with basic block number BLOCKNO. */
! #define BLOCK_PROFILER(FILE, BLOCKNO) \
! sparc_block_profiler (FILE, BLOCKNO)
/* The following macro shall output assembler code to FILE
! to indicate a return from function during basic-block profiling. */
#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \
! sparc_function_block_profiler_exit(FILE)
/* The function `__bb_trace_func' is called in every basic block
and is not allowed to change the machine state. Saving (restoring)
*************** extern int v9_regcmp_p ();
*** 3496,3501 ****
--- 3288,3298 ----
extern unsigned long sparc_flat_compute_frame_size ();
extern unsigned long sparc_type_code ();
+
+ extern void sparc_function_profiler ();
+ extern void sparc_function_block_profiler ();
+ extern void sparc_block_profiler ();
+ extern void sparc_function_block_profiler_exit ();
extern char *sparc_v8plus_shift ();
Index: config/sparc/sun4o3.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/sun4o3.h,v
retrieving revision 1.3
diff -c -p -d -r1.3 sun4o3.h
*** sun4o3.h 1998/12/16 21:13:38 1.3
--- sun4o3.h 1999/06/22 00:12:00
***************
*** 1,9 ****
#include "sparc/sparc.h"
! #undef FUNCTION_PROFILER
! #define FUNCTION_PROFILER(FILE, LABELNO) \
! fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall .mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \
! (LABELNO), (LABELNO))
/* LINK_SPEC is needed only for SunOS 4. */
--- 1,9 ----
#include "sparc/sparc.h"
! /* Override the name of the mcount profiling function. */
!
! #undef MCOUNT_FUNCTION
! #define MCOUNT_FUNCTION "*.mcount"
/* LINK_SPEC is needed only for SunOS 4. */
Index: config/sparc/sysv4.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/sysv4.h,v
retrieving revision 1.10
diff -c -p -d -r1.10 sysv4.h
*** sysv4.h 1998/12/16 21:13:40 1.10
--- sysv4.h 1999/06/22 00:12:00
*************** do { \
*** 200,228 ****
else \
fprintf (FILE, ".section\t\"%s\",#alloc,#write\n", (NAME)); \
} while (0)
-
- /* Output assembler code to FILE to initialize this source file's
- basic block profiling info, if that has not already been done. */
-
- #undef FUNCTION_BLOCK_PROFILER
- #define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
- do { \
- fprintf (FILE, "\tsethi %%hi(.LLPBX0),%%o0\n\tld [%%lo(.LLPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(.LLPBX0),%%o0\n\tcall __bb_init_func\n\tnop\nLPY%d:\n", \
- (LABELNO), (LABELNO)); \
- } while (0)
- /* Output assembler code to FILE to increment the entry-count for
- the BLOCKNO'th basic block in this source file. */
-
- #undef BLOCK_PROFILER
- #define BLOCK_PROFILER(FILE, BLOCKNO) \
- { \
- int blockn = (BLOCKNO); \
- fprintf (FILE, "\tsethi %%hi(.LLPBX2+%d),%%g1\n\tld [%%lo(.LLPBX2+%d)+%%g1],%%g2\n\
- \tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(.LLPBX2+%d)+%%g1]\n", \
- 4 * blockn, 4 * blockn, 4 * blockn); \
- }
-
/* A C statement (sans semicolon) to output to the stdio stream
FILE the assembler definition of uninitialized global DECL named
NAME whose size is SIZE bytes and alignment is ALIGN bytes.
--- 200,206 ----
*************** do { \
*** 231,233 ****
--- 209,216 ----
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+ /* Override the name of the mcount profiling function. */
+
+ #undef MCOUNT_FUNCTION
+ #define MCOUNT_FUNCTION "*_mcount"