This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: patch sparc problems in egcs


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"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]