Commit c714f03d by Richard Henderson Committed by Richard Henderson

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
parent 03369c93
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> 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 * c-decl.c (grokdeclarator): Don't warn about implicit int in
......
...@@ -2825,46 +2825,57 @@ print_operand (file, x, code) ...@@ -2825,46 +2825,57 @@ print_operand (file, x, code)
/* Emit RTL insns to initialize the variable parts of a trampoline at /* 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 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. 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 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 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. take the trouble to initialize the "hint" field in the JMP insn.
Note that the hint field is PC (new) + 4 * bits 13:0. */ Note that the hint field is PC (new) + 4 * bits 13:0. */
void void
alpha_initialize_trampoline (tramp, fnaddr, cxt) alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
rtx tramp; rtx tramp, fnaddr, cxt;
rtx fnaddr; int fnofs, cxtofs, jmpofs;
rtx cxt;
{ {
rtx temp, temp1, addr; rtx temp, temp1, addr;
/* Store function address and CXT. */ /* Store function address and CXT. */
addr = memory_address (Pmode, plus_constant (tramp, 16)); addr = memory_address (ptr_mode, plus_constant (tramp, fnofs));
emit_move_insn (gen_rtx (MEM, Pmode, addr), fnaddr); emit_move_insn (gen_rtx (MEM, ptr_mode, addr), fnaddr);
addr = memory_address (Pmode, plus_constant (tramp, 24)); addr = memory_address (ptr_mode, plus_constant (tramp, cxtofs));
emit_move_insn (gen_rtx (MEM, Pmode, addr), cxt); emit_move_insn (gen_rtx (MEM, ptr_mode, addr), cxt);
/* Compute hint value. */ /* This has been disabled since the hint only has a 32k range, and in
temp = force_operand (plus_constant (tramp, 12), NULL_RTX); no existing OS is the stack within 32k of the text segment. */
temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1, OPTAB_WIDEN); if (0 && jmpofs >= 0)
temp = expand_shift (RSHIFT_EXPR, Pmode, temp, {
build_int_2 (2, 0), NULL_RTX, 1); /* Compute hint value. */
temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0); temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
/* Merge in the hint. */ OPTAB_WIDEN);
addr = memory_address (SImode, plus_constant (tramp, 8)); temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr)); build_int_2 (2, 0), NULL_RTX, 1);
temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX); temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
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 #ifdef TRANSFER_FROM_TRAMPOLINE
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"), emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
0, VOIDmode, 1, addr, Pmode); 0, VOIDmode, 1, addr, Pmode);
#endif #endif
emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, if (jmpofs >= 0)
gen_rtvec (1, const0_rtx), 0)); emit_insn (gen_imb ());
} }
/* Do what is necessary for `va_start'. The argument is ignored; /* Do what is necessary for `va_start'. The argument is ignored;
......
...@@ -1182,13 +1182,13 @@ extern void output_end_prologue (); ...@@ -1182,13 +1182,13 @@ extern void output_end_prologue ();
aligned to FUNCTION_BOUNDARY, which is 64 bits. */ aligned to FUNCTION_BOUNDARY, which is 64 bits. */
#define TRAMPOLINE_TEMPLATE(FILE) \ #define TRAMPOLINE_TEMPLATE(FILE) \
{ \ do { \
fprintf (FILE, "\tldq $1,24($27)\n"); \ fprintf (FILE, "\tldq $1,24($27)\n"); \
fprintf (FILE, "\tldq $27,16($27)\n"); \ fprintf (FILE, "\tldq $27,16($27)\n"); \
fprintf (FILE, "\tjmp $31,($27),0\n"); \ fprintf (FILE, "\tjmp $31,($27),0\n"); \
fprintf (FILE, "\tnop\n"); \ fprintf (FILE, "\tnop\n"); \
fprintf (FILE, "\t.quad 0,0\n"); \ fprintf (FILE, "\t.quad 0,0\n"); \
} } while (0)
/* Section in which to place the trampoline. On Alpha, instructions /* Section in which to place the trampoline. On Alpha, instructions
may only be placed in a text segment. */ may only be placed in a text segment. */
...@@ -1201,31 +1201,10 @@ extern void output_end_prologue (); ...@@ -1201,31 +1201,10 @@ extern void output_end_prologue ();
/* Emit RTL insns to initialize the variable parts of a trampoline. /* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code. 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 CXT is an RTX for the static chain value for the function. */
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. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT) alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8)
/* 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"); \
}
/* A C expression whose value is RTL representing the value of the return /* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame. address for the frame COUNT steps up from the current frame.
...@@ -1240,7 +1219,6 @@ extern struct rtx_def *alpha_return_addr (); ...@@ -1240,7 +1219,6 @@ extern struct rtx_def *alpha_return_addr ();
#define INIT_EXPANDERS alpha_init_expanders () #define INIT_EXPANDERS alpha_init_expanders ()
extern void alpha_init_expanders (); extern void alpha_init_expanders ();
/* Addressing modes, and classification of registers for them. */ /* Addressing modes, and classification of registers for them. */
......
...@@ -3970,7 +3970,7 @@ ...@@ -3970,7 +3970,7 @@
;; Technically the type for call_pal is jsr, but we use that for determining ;; 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 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
;; characteristics. ;; characteristics.
(define_insn "" (define_insn "imb"
[(unspec_volatile [(const_int 0)] 0)] [(unspec_volatile [(const_int 0)] 0)]
"" ""
"call_pal 0x86" "call_pal 0x86"
......
/* Definitions of target machine for GNU compiler, for Alpha Linux-based GNU /* Definitions of target machine for GNU compiler,
systems using ECOFF. for Alpha Linux-based GNU systems.
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Bob Manson. Contributed by Richard Henderson.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -43,5 +43,3 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -43,5 +43,3 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Don't care about faults in the prologue. */ /* Don't care about faults in the prologue. */
#undef TARGET_CAN_FAULT_IN_PROLOGUE #undef TARGET_CAN_FAULT_IN_PROLOGUE
#define TARGET_CAN_FAULT_IN_PROLOGUE 1 #define TARGET_CAN_FAULT_IN_PROLOGUE 1
#undef ASM_FINAL_SPEC
...@@ -108,3 +108,20 @@ Boston, MA 02111-1307, USA. */ ...@@ -108,3 +108,20 @@ Boston, MA 02111-1307, USA. */
#ifndef CROSS_COMPILE #ifndef CROSS_COMPILE
#define HAVE_STAMP_H 1 #define HAVE_STAMP_H 1
#endif #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"); \
}
...@@ -405,19 +405,8 @@ do { \ ...@@ -405,19 +405,8 @@ do { \
CXT is an RTX for the static chain value for the function. */ CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE #undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \ alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, -1)
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
/* A C statement (sans semicolon) to output an element in the table of /* A C statement (sans semicolon) to output an element in the table of
global constructors. */ global constructors. */
......
...@@ -53,5 +53,3 @@ Boston, MA 02111-1307, USA. */ ...@@ -53,5 +53,3 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC #undef ENDFILE_SPEC
#define ENDFILE_SPEC "" #define ENDFILE_SPEC ""
#undef TRANSFER_FROM_TRAMPOLINE
...@@ -101,37 +101,11 @@ Boston, MA 02111-1307, USA. */ ...@@ -101,37 +101,11 @@ Boston, MA 02111-1307, USA. */
/* Emit RTL insns to initialize the variable parts of a trampoline. /* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code. 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. 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.
*/
#undef INITIALIZE_TRAMPOLINE #undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \ alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 20, 12)
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)); \
}
/* Output code to add DELTA to the first argument, and then jump to FUNCTION. /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */ Used for C++ multiple inheritance. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment