diff options
Diffstat (limited to 'sysdeps/alpha/bb_init_func.S')
-rw-r--r-- | sysdeps/alpha/bb_init_func.S | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/sysdeps/alpha/bb_init_func.S b/sysdeps/alpha/bb_init_func.S new file mode 100644 index 0000000000..9bf985ccc0 --- /dev/null +++ b/sysdeps/alpha/bb_init_func.S @@ -0,0 +1,85 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __bb_init_func is invoked at the beginning of each function, before +any registers have been saved. It is therefore safe to use any +caller-saved (call-used) registers (except for argument registers +a1-a5). */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +# include <regdef.h> +#endif + +/* + * These offsets should match with "struct bb" declared in gcc/libgcc2.c. + */ +#define ZERO_WORD 0x00 +#define NEXT 0x20 + + .set noat + .set noreorder + +ENTRY(__bb_init_func) + ldq t0, ZERO_WORD(a0) /* t0 <- blocks->zero_word */ + beq t0, init /* not initialized yet -> */ + ret + + +init: subq sp, 0x38, sp + stq pv, 0x30(sp) + br pv, 1f +1: ldgp gp, 0(pv) + + lda t1, __bb_head + lda t3, _gmonparam + ldq t2, 0(t1) + ldl t3, 0(t3) /* t3 = _gmonparam.state */ + ldi t0, 1 + stq t0, ZERO_WORD(a0) /* blocks->zero_word = 1 */ + stq t2, NEXT(a0) /* blocks->next = __bb_head */ + stq a0, 0(t1) + bne t2, leave + beq t3, leave /* t3 == GMON_PROF_ON? yes -> */ + + /* also need to initialize destructor: */ + stq ra, 0x00(sp) + lda a0, __bb_exit_func + stq a1, 0x08(sp) + lda pv, atexit + stq a2, 0x10(sp) + stq a3, 0x18(sp) + stq a4, 0x20(sp) + stq a5, 0x28(sp) + jsr ra, (pv), atexit + ldq ra, 0x00(sp) + ldq a1, 0x08(sp) + ldq a2, 0x10(sp) + ldq a3, 0x18(sp) + ldq a4, 0x20(sp) + ldq a5, 0x28(sp) + +leave: ldq pv, 0x30(sp) + addq sp, 0x38, sp + ret + + .end __bb_init_func |