alpha.c (alpha_initialize_trampoline): Take arguments describing the layout.

* alpha.c (alpha_initialize_trampoline): Take arguments describing
        the layout.  Use ptr_mode.  Disable hint generation.  Use gen_imb.
        * alpha.h (INITIALIZE_TRAMPOLINE): Pass extra args to the init func.
        (TRANSFER_FROM_TRAMPOLINE): Move ...
        * alpha/osf.h: ... here.
        * alpha/vms.h (INITIALIZE_TRAMPOLINE): Use alpha_initialize_trampoline.
        (TRANSFER_FROM_TRAMPOLINE): Remove undef.
        * alpha/win-nt.h: Likewise.
        * alpha/vxworks.h: Likewise.
        * alpha/linux.h: Revert gcc2 merge lossage.

From-SVN: r20864
This commit is contained in:
Richard Henderson 1998-06-30 20:56:35 -07:00 committed by Richard Henderson
parent 03369c9399
commit c714f03d30
9 changed files with 77 additions and 98 deletions

View file

@ -1,3 +1,17 @@
Wed Jul 1 03:48:00 1998 Richard Henderson <rth@cygnus.com>
* alpha.c (alpha_initialize_trampoline): Take arguments describing
the layout. Use ptr_mode. Disable hint generation. Use gen_imb.
* alpha.h (INITIALIZE_TRAMPOLINE): Pass extra args to the init func.
(TRANSFER_FROM_TRAMPOLINE): Move ...
* alpha/osf.h: ... here.
* alpha/vms.h (INITIALIZE_TRAMPOLINE): Use alpha_initialize_trampoline.
(TRANSFER_FROM_TRAMPOLINE): Remove undef.
* alpha/win-nt.h: Likewise.
* alpha/vxworks.h: Likewise.
* alpha/linux.h: Revert gcc2 merge lossage.
Wed Jul 1 10:56:55 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* c-decl.c (grokdeclarator): Don't warn about implicit int in

View file

@ -2825,46 +2825,57 @@ print_operand (file, x, code)
/* Emit RTL insns to initialize the variable parts of a trampoline at
TRAMP. FNADDR is an RTX for the address of the function's pure
code. CXT is an RTX for the static chain value for the function.
The three offset parameters are for the individual template's
layout. A JMPOFS < 0 indicates that the trampoline does not
contain instructions at all.
We assume here that a function will be called many more times than
its address is taken (e.g., it might be passed to qsort), so we
take the trouble to initialize the "hint" field in the JMP insn.
Note that the hint field is PC (new) + 4 * bits 13:0. */
void
alpha_initialize_trampoline (tramp, fnaddr, cxt)
rtx tramp;
rtx fnaddr;
rtx cxt;
alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
rtx tramp, fnaddr, cxt;
int fnofs, cxtofs, jmpofs;
{
rtx temp, temp1, addr;
/* Store function address and CXT. */
addr = memory_address (Pmode, plus_constant (tramp, 16));
emit_move_insn (gen_rtx (MEM, Pmode, addr), fnaddr);
addr = memory_address (Pmode, plus_constant (tramp, 24));
emit_move_insn (gen_rtx (MEM, Pmode, addr), cxt);
addr = memory_address (ptr_mode, plus_constant (tramp, fnofs));
emit_move_insn (gen_rtx (MEM, ptr_mode, addr), fnaddr);
addr = memory_address (ptr_mode, plus_constant (tramp, cxtofs));
emit_move_insn (gen_rtx (MEM, ptr_mode, addr), cxt);
/* Compute hint value. */
temp = force_operand (plus_constant (tramp, 12), NULL_RTX);
temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1, OPTAB_WIDEN);
temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
build_int_2 (2, 0), NULL_RTX, 1);
temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
/* This has been disabled since the hint only has a 32k range, and in
no existing OS is the stack within 32k of the text segment. */
if (0 && jmpofs >= 0)
{
/* Compute hint value. */
temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
OPTAB_WIDEN);
temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
build_int_2 (2, 0), NULL_RTX, 1);
temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
/* Merge in the hint. */
addr = memory_address (SImode, plus_constant (tramp, 8));
temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1, OPTAB_WIDEN);
emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
/* Merge in the hint. */
addr = memory_address (SImode, plus_constant (tramp, jmpofs));
temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
OPTAB_WIDEN);
emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
}
#ifdef TRANSFER_FROM_TRAMPOLINE
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
0, VOIDmode, 1, addr, Pmode);
#endif
emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
gen_rtvec (1, const0_rtx), 0));
if (jmpofs >= 0)
emit_insn (gen_imb ());
}
/* Do what is necessary for `va_start'. The argument is ignored;

View file

@ -1182,13 +1182,13 @@ extern void output_end_prologue ();
aligned to FUNCTION_BOUNDARY, which is 64 bits. */
#define TRAMPOLINE_TEMPLATE(FILE) \
{ \
do { \
fprintf (FILE, "\tldq $1,24($27)\n"); \
fprintf (FILE, "\tldq $27,16($27)\n"); \
fprintf (FILE, "\tjmp $31,($27),0\n"); \
fprintf (FILE, "\tnop\n"); \
fprintf (FILE, "\t.quad 0,0\n"); \
}
} while (0)
/* Section in which to place the trampoline. On Alpha, instructions
may only be placed in a text segment. */
@ -1201,31 +1201,10 @@ extern void output_end_prologue ();
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. We assume
here that a function will be called many more times than its address
is taken (e.g., it might be passed to qsort), so we take the trouble
to initialize the "hint" field in the JMP insn. Note that the hint
field is PC (new) + 4 * bits 13:0. */
CXT is an RTX for the static chain value for the function. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT)
/* Attempt to turn on access permissions for the stack. */
#define TRANSFER_FROM_TRAMPOLINE \
void \
__enable_execute_stack (addr) \
void *addr; \
{ \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
\
/* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \
if (mprotect (page, end - page, 7) < 0) \
perror ("mprotect of trampoline code"); \
}
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8)
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame.
@ -1240,7 +1219,6 @@ extern struct rtx_def *alpha_return_addr ();
#define INIT_EXPANDERS alpha_init_expanders ()
extern void alpha_init_expanders ();
/* Addressing modes, and classification of registers for them. */

View file

@ -3970,7 +3970,7 @@
;; Technically the type for call_pal is jsr, but we use that for determining
;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
;; characteristics.
(define_insn ""
(define_insn "imb"
[(unspec_volatile [(const_int 0)] 0)]
""
"call_pal 0x86"

View file

@ -1,7 +1,7 @@
/* Definitions of target machine for GNU compiler, for Alpha Linux-based GNU
systems using ECOFF.
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Bob Manson.
Contributed by Richard Henderson.
This file is part of GNU CC.
@ -43,5 +43,3 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Don't care about faults in the prologue. */
#undef TARGET_CAN_FAULT_IN_PROLOGUE
#define TARGET_CAN_FAULT_IN_PROLOGUE 1
#undef ASM_FINAL_SPEC

View file

@ -108,3 +108,20 @@ Boston, MA 02111-1307, USA. */
#ifndef CROSS_COMPILE
#define HAVE_STAMP_H 1
#endif
/* Attempt to turn on access permissions for the stack. */
#define TRANSFER_FROM_TRAMPOLINE \
void \
__enable_execute_stack (addr) \
void *addr; \
{ \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
\
/* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \
if (mprotect (page, end - page, 7) < 0) \
perror ("mprotect of trampoline code"); \
}

View file

@ -405,19 +405,8 @@ do { \
CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
emit_move_insn (gen_rtx (MEM, Pmode, \
memory_address (Pmode, \
plus_constant ((TRAMP), 16))), \
(FNADDR)); \
emit_move_insn (gen_rtx (MEM, Pmode, \
memory_address (Pmode, \
plus_constant ((TRAMP), 24))), \
(CXT)); \
}
#undef TRANSFER_FROM_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, -1)
/* A C statement (sans semicolon) to output an element in the table of
global constructors. */

View file

@ -53,5 +53,3 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
#undef TRANSFER_FROM_TRAMPOLINE

View file

@ -101,37 +101,11 @@ Boston, MA 02111-1307, USA. */
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function.
This differs from the standard version in that:
We are not passed the current address in any register, and so have to
load it ourselves.
We do not initialize the "hint" field because it only has an 8k
range and so the target is in range of something on the stack.
Omitting the hint saves a bogus branch-prediction cache line load.
Always have an executable stack -- no need for a system call.
*/
CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
rtx _addr, _val; \
\
_addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
_val = force_reg(Pmode, (FNADDR)); \
emit_move_insn (gen_rtx (MEM, SImode, _addr), \
gen_rtx (SUBREG, SImode, _val, 0)); \
_addr = memory_address (Pmode, plus_constant ((TRAMP), 20)); \
_val = force_reg(Pmode, (CXT)); \
emit_move_insn (gen_rtx (MEM, SImode, _addr), \
gen_rtx (SUBREG, SImode, _val, 0)); \
\
emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \
gen_rtvec (1, const0_rtx), 0)); \
}
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 20, 12)
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */