+ 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)
+ the state can either be done in the BLOCK_PROFILER macro,
+ before calling function (rsp. after returning from function)
+ `__bb_trace_func', or it can be done inside the function by
+ defining the macros:
+
+ MACHINE_STATE_SAVE(ID)
+ MACHINE_STATE_RESTORE(ID)
+
+ In the latter case care must be taken, that the prologue code
+ of function `__bb_trace_func' does not already change the
+ state prior to saving it with MACHINE_STATE_SAVE.
+
+ The parameter `ID' is a string identifying a unique macro use.
+
+ On sparc it is sufficient to save the psw register to memory.
+ Unfortunately the psw register can be read in supervisor mode only,
+ so we read only the condition codes by using branch instructions
+ and hope that this is enough. */
+
+#define MACHINE_STATE_SAVE(ID) \
+ asm (" mov %g0,%l0");\
+ asm (" be,a LFLGNZ" ID);\
+ asm (" or %l0,4,%l0");\
+ asm ("LFLGNZ" ID ": bcs,a LFLGNC" ID);\
+ asm (" or %l0,1,%l0");\
+ asm ("LFLGNC" ID ": bvs,a LFLGNV" ID);\
+ asm (" or %l0,2,%l0");\
+ asm ("LFLGNV" ID ": bneg,a LFLGNN" ID);\
+ asm (" or %l0,8,%l0");\
+ asm ("LFLGNN" ID ": sethi %hi(LFLAGS" ID "),%l1");\
+ asm (" st %l0,[%l1+%lo(LFLAGS" ID ")]"); \
+ asm (" st %g2,[%l1+%lo(LSAVRET" ID ")]");
+
+/* On sparc MACHINE_STATE_RESTORE restores the psw register from memory.
+ The psw register can be written in supervisor mode only,
+ which is true even for simple condition codes.
+ We use some combination of instructions to produce the
+ proper condition codes, but some flag combinations can not
+ be generated in this way. If this happens an unimplemented
+ instruction will be executed to abort the program. */
+
+#define MACHINE_STATE_RESTORE(ID) \
+ asm (" sethi %hi(LFLGTAB" ID "),%l1");\
+ asm (" ld [%l1+%lo(LFLGTAB" ID "-(LFLGTAB" ID "-LFLAGS" ID "))],%l0");\
+ asm (" ld [%l1+%lo(LFLGTAB" ID "-(LFLGTAB" ID "-LSAVRET" ID "))],%g2");\
+ asm (" sll %l0,2,%l0");\
+ asm (" add %l0,%l1,%l0");\
+ asm (" ld [%l0+%lo(LFLGTAB" ID ")],%l1");\
+ asm (" jmp %l1");\
+ asm (" nop");\
+ asm (".data");\
+ asm (" .align 4");\
+ asm ("LFLAGS" ID ":");\
+ asm (" .word 0");\
+ asm ("LSAVRET" ID ":");\
+ asm (" .word 0");\
+ asm ("LFLGTAB" ID ": ");\
+ asm (" .word LSFLG0" ID);\
+ asm (" .word LSFLGC" ID);\
+ asm (" .word LSFLGV" ID);\
+ asm (" .word LSFLGVC" ID);\
+ asm (" .word LSFLGZ" ID);\
+ asm (" .word LSFLGZC" ID);\
+ asm (" .word LSFLGZV" ID);\
+ asm (" .word LSFLGZVC" ID);\
+ asm (" .word LSFLGN" ID);\
+ asm (" .word LSFLGNC" ID);\
+ asm (" .word LSFLGNV" ID);\
+ asm (" .word LSFLGNVC" ID);\
+ asm (" .word LSFLGNZ" ID);\
+ asm (" .word LSFLGNZC" ID);\
+ asm (" .word LSFLGNZV" ID);\
+ asm (" .word LSFLGNZVC" ID);\
+ asm (".text");\
+ asm ("LSFLGVC" ID ": mov -1,%l0");\
+ asm (" addcc 2,%l0,%g0");\
+ asm (" sethi %hi(0x80000000),%l0");\
+ asm (" mov %l0,%l1");\
+ asm (" ba LFLGRET" ID);\
+ asm (" addxcc %l0,%l1,%l0");\
+ asm ("LSFLGC" ID ": mov -1,%l0");\
+ asm (" ba LFLGRET" ID);\
+ asm (" addcc 2,%l0,%g0");\
+ asm ("LSFLGZC" ID ": mov -1,%l0");\
+ asm (" ba LFLGRET" ID);\
+ asm (" addcc 1,%l0,%l0");\
+ asm ("LSFLGZVC" ID ": sethi %hi(0x80000000),%l0");\
+ asm (" mov %l0,%l1");\
+ asm (" ba LFLGRET" ID);\
+ asm (" addcc %l0,%l1,%l0");\
+ asm ("LSFLGZ" ID ": ba LFLGRET" ID);\
+ asm (" subcc %g0,%g0,%g0");\
+ asm ("LSFLGNC" ID ": add %g0,1,%l0");\
+ asm (" ba LFLGRET" ID);\
+ asm (" subcc %g0,%l0,%g0");\
+ asm ("LSFLG0" ID ": ba LFLGRET" ID);\
+ asm (" orcc 1,%g0,%g0");\
+ asm ("LSFLGN" ID ": ba LFLGRET" ID);\
+ asm (" orcc -1,%g0,%g0");\
+ asm ("LSFLGV" ID ":");\
+ asm ("LSFLGZV" ID ":");\
+ asm ("LSFLGNV" ID ":");\
+ asm ("LSFLGNVC" ID ":");\
+ asm ("LSFLGNZ" ID ":");\
+ asm ("LSFLGNZC" ID ":");\
+ asm ("LSFLGNZV" ID ":");\
+ asm ("LSFLGNZVC" ID ":");\
+ asm (" unimp");\
+ asm ("LFLGRET" ID ":");
+\f