summaryrefslogtreecommitdiff
path: root/gnu/egcs/gcc
diff options
context:
space:
mode:
authorHenric Jungheim <henric@cvs.openbsd.org>2003-03-09 06:58:18 +0000
committerHenric Jungheim <henric@cvs.openbsd.org>2003-03-09 06:58:18 +0000
commit1358fcaa01f460bb8d53e8902322b20361d46716 (patch)
tree9d5b1c2bba003748d3724d79ea5fd6bbe5256a24 /gnu/egcs/gcc
parenteca8033b8e11d0064093cf7b131b17777ed3c340 (diff)
Originally from gcc:
2002-06-14 Jeff Sturm <jsturm@one-point.com> * config/sparc/sparc.h (DYNAMIC_CHAIN_ADDRESS): Add SPARC_STACK_BIAS. 2002-03-12 Andrew MacLeod <amacleod@redhat.com> * config/sparc/sparc.h (RETURN_ADDR_RTX): Include v9 stack bias in address calculation. through Hiroaki Etoh (thanks). This gets "__builtin_return_address()" to work on sparc64. ok deraadt@
Diffstat (limited to 'gnu/egcs/gcc')
-rw-r--r--gnu/egcs/gcc/config/sparc/sparc.h257
1 files changed, 31 insertions, 226 deletions
diff --git a/gnu/egcs/gcc/config/sparc/sparc.h b/gnu/egcs/gcc/config/sparc/sparc.h
index b00a145164d..e38c6124d19 100644
--- a/gnu/egcs/gcc/config/sparc/sparc.h
+++ b/gnu/egcs/gcc/config/sparc/sparc.h
@@ -1844,240 +1844,32 @@ do { \
current_function_uses_only_leaf_regs))
/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry.
+ 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) \
+ sparc_function_profiler(FILE, LABELNO)
-#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.
+/* Set the name of the mcount function for the system. */
- 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'.
-
-*/
+#define MCOUNT_FUNCTION "*mcount"
/* 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);
+ to initialize basic-block profiling. */
- 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)
+#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.
-
- If profile_block_flag == 2
+ to increment a counter associated with basic block number BLOCKNO. */
- 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)
+#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.
-
- 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.
-*/
+ to indicate a return from function during basic-block profiling. */
#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \
- fprintf (FILE, "\tcall ___bb_trace_ret\n\tnop\n" );
+ 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)
@@ -2276,7 +2068,7 @@ extern struct rtx_def *sparc_builtin_saveregs ();
that holds the dynamic chain--the previous frame's address.
??? -mflat support? */
#define DYNAMIC_CHAIN_ADDRESS(frame) \
- gen_rtx_PLUS (Pmode, frame, GEN_INT (14 * UNITS_PER_WORD))
+ plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
/* The return address isn't on the stack, it is in a register, so we can't
access it from the current frame pointer. We can access it from the
@@ -2297,7 +2089,9 @@ extern struct rtx_def *sparc_builtin_saveregs ();
((count == -1) \
? gen_rtx_REG (Pmode, 31) \
: gen_rtx_MEM (Pmode, \
- memory_address (Pmode, plus_constant (frame, 15 * UNITS_PER_WORD))))
+ memory_address (Pmode, plus_constant (frame, \
+ 15 * UNITS_PER_WORD \
+ + SPARC_STACK_BIAS))))
/* Before the prologue, the return address is %o7 + 8. OK, sometimes it's
+12, but always using +8 is close enough for frame unwind purposes.
@@ -2584,8 +2378,11 @@ extern struct rtx_def *legitimize_pic_address ();
For Sparc 32, we wish to handle addresses by splitting them into
HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
- This cuts the number of extra insns by one. */
-
+ This cuts the number of extra insns by one.
+
+ Do nothing when generating PIC code and the address is a
+ symbolic operand or requires a scratch register. */
+
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
/* Decompose SImode constants into hi+lo_sum. We do have to \
@@ -2593,7 +2390,10 @@ do { \
if (CONSTANT_P (X) \
&& (MODE != TFmode || TARGET_V9) \
&& GET_MODE (X) == SImode \
- && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH) \
+ && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \
+ && ! (flag_pic \
+ && (symbolic_operand (X, Pmode) \
+ || pic_address_needs_scratch (X)))) \
{ \
X = gen_rtx_LO_SUM (GET_MODE (X), \
gen_rtx_HIGH (GET_MODE (X), X), X); \
@@ -3491,6 +3291,11 @@ extern int v9_regcmp_p ();
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 ();
#ifdef __STDC__