diff options
author | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-09 06:58:18 +0000 |
---|---|---|
committer | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-09 06:58:18 +0000 |
commit | 1358fcaa01f460bb8d53e8902322b20361d46716 (patch) | |
tree | 9d5b1c2bba003748d3724d79ea5fd6bbe5256a24 /gnu/egcs/gcc | |
parent | eca8033b8e11d0064093cf7b131b17777ed3c340 (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.h | 257 |
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__ |