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:
parent
03369c9399
commit
c714f03d30
9 changed files with 77 additions and 98 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"); \
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -53,5 +53,3 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC ""
|
||||
|
||||
#undef TRANSFER_FROM_TRAMPOLINE
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue