(ASM_SPEC): New macro.

(TRAMPOLINE_{TEMPLATE,SIZE}, INITIALIZE_TRAMPOLINE): Make major
changes to fix numerous bugs.

From-SVN: r2874
This commit is contained in:
Richard Kenner 1992-12-15 17:41:33 -05:00
parent 9353d0a3fb
commit 7981384fa7
1 changed files with 47 additions and 15 deletions

View File

@ -41,6 +41,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
/* No point in running CPP on our assembler output. */
#define ASM_SPEC "-nocpp"
/* Right now Alpha OSF/1 doesn't seem to have debugging or profiled
libraries. */
@ -808,31 +811,31 @@ extern char *alpha_function_name;
of a trampoline, leaving space for the variable parts.
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine. We
use $28 (at) as a temporary. Note that $27 has been set to the
address of the trampoline, so we can use it for addressability
of the two data items. Trampolines are always aligned to
FUNCTION_BOUNDARY, which is 64 bits. */
into the trampoline and should branch to the specified routine.
Note that $27 has been set to the address of the trampoline, so we can
use it for addressability of the two data items. Trampolines are always
aligned to FUNCTION_BOUNDARY, which is 64 bits. */
#define TRAMPOLINE_TEMPLATE(FILE) \
{ \
fprintf (FILE, "\tbis $27,$27,$28\n"); \
fprintf (FILE, "\tldq $1,24($27)\n"); \
fprintf (FILE, "\tldq $27,16($27)\n"); \
fprintf (FILE, "\tldq $1,20($28)\n"); \
fprintf (FILE, "\tjmp $31,0($27),0\n"); \
fprintf (FILE, "\tjmp $31,($27),0\n"); \
fprintf (FILE, "\tnop\n"); \
fprintf (FILE, "\t.quad 0,0\n"); \
}
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE 24
#define TRAMPOLINE_SIZE 32
/* 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. */
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) \
{ \
@ -840,20 +843,49 @@ extern char *alpha_function_name;
\
_addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (FNADDR)); \
_addr = memory_address (Pmode, plus_constant ((TRAMP), 20)); \
_addr = memory_address (Pmode, plus_constant ((TRAMP), 24)); \
emit_move_insn (gen_rtx (MEM, Pmode, _addr), (CXT)); \
\
_temp = expand_shift (RSHIFT_EXPR, Pmode, (FNADDR), \
_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 (_temp, GEN_INT (0x1fff), 0); \
_temp = expand_and (gen_lowpart (SImode, _temp), \
GEN_INT (0x3fff), 0); \
\
_addr = memory_address (SImode, plus_constant ((TRAMP), 12)); \
_addr = memory_address (SImode, plus_constant ((TRAMP), 8)); \
_temp1 = force_reg (SImode, gen_rtx (MEM, SImode, _addr)); \
_temp1 = expand_and (_temp, GEN_INT (0xfffe000), NULL_RTX); \
_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); \
\
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \
"__enable_execute_stack"), \
0, VOIDmode, 1,_addr, Pmode); \
\
emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \
gen_rtvec (1, const0_rtx), 0)); \
}
/* 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"); \
}
/* Addressing modes, and classification of registers for them. */