This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
x86_64 merger part 32 - trampolines
- To: patches at x86-64 dot org, rth at cygnus dot com, gcc-patches at gcc dot gnu dot org
- Subject: x86_64 merger part 32 - trampolines
- From: Jan Hubicka <jh at suse dot cz>
- Date: Wed, 4 Apr 2001 11:39:43 +0200
Wed Apr 4 11:36:00 CEST 2001 Jan Hubicka
* i386.c (x86_initialize_trampoline): New global function.
* i386.h (TRAMPOLINE_SIZE): Size is 23 for x86_64.
(INITIALIZE_TRAMPOLINE): Move offline.
* i386-protos.h (x86_initialize_trampoline): Declare.
*** ../i386.c Wed Apr 4 10:39:38 2001
--- i386.c Wed Apr 4 11:33:49 2001
*************** ix86_local_alignment (type, align)
*** 8930,8935 ****
--- 8930,8994 ----
}
return align;
}
+
+ /* 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. */
+ void
+ x86_initialize_trampoline (tramp, fnaddr, cxt)
+ rtx tramp, fnaddr, cxt;
+ {
+ if (!TARGET_64BIT)
+ {
+ /* Compute offset from the end of the jmp to the target function. */
+ rtx disp = expand_binop (SImode, sub_optab, fnaddr,
+ plus_constant (tramp, 10),
+ NULL_RTX, 1, OPTAB_DIRECT);
+ emit_move_insn (gen_rtx_MEM (QImode, tramp), GEN_INT (0xb9));
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
+ emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 5)),
+ GEN_INT (0xe9));
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 6)), disp);
+ }
+ else
+ {
+ int offset = 0;
+ /* Try to load address using shorter movl instead of movabs.
+ We may want to support movq for kernel mode, but kernel does not use
+ trampolines at the moment. */
+ if (x86_64_zero_extended_value (fnaddr))
+ {
+ fnaddr = copy_to_mode_reg (DImode, fnaddr);
+ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
+ GEN_INT (0xbb41));
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, offset + 2)),
+ gen_lowpart (SImode, fnaddr));
+ offset += 6;
+ }
+ else
+ {
+ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
+ GEN_INT (0xbb49));
+ emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
+ fnaddr);
+ offset += 10;
+ }
+ /* Load static chain using movabs to r10. */
+ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
+ GEN_INT (0xba49));
+ emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
+ cxt);
+ offset += 10;
+ /* Jump to the r11 */
+ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
+ GEN_INT (0xff49));
+ emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, offset+2)),
+ GEN_INT (0xe3));
+ offset += 3;
+ if (offset > TRAMPOLINE_SIZE)
+ abort();
+ }
+ }
#define def_builtin(NAME, TYPE, CODE) \
builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL_PTR)
*** ../i386.h Wed Mar 28 20:08:32 2001
--- i386.h Wed Apr 4 11:35:22 2001
*************** pop{l} %0" \
*** 1704,1726 ****
/* Length in units of the trampoline for entering a nested function. */
! #define TRAMPOLINE_SIZE 10
/* 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. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
! { \
! /* Compute offset from the end of the jmp to the target function. */ \
! rtx disp = expand_binop (SImode, sub_optab, FNADDR, \
! plus_constant (TRAMP, 10), \
! NULL_RTX, 1, OPTAB_DIRECT); \
! emit_move_insn (gen_rtx_MEM (QImode, TRAMP), GEN_INT (0xb9)); \
! emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 1)), CXT); \
! emit_move_insn (gen_rtx_MEM (QImode, plus_constant (TRAMP, 5)), GEN_INT (0xe9));\
! emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), disp); \
! }
/* Definitions for register eliminations.
--- 1704,1717 ----
/* Length in units of the trampoline for entering a nested function. */
! #define TRAMPOLINE_SIZE (TARGET_64BIT ? 23 : 10)
/* 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. */
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
! x86_initialize_trampoline (TRAMP, FNADDR, CXT)
/* Definitions for register eliminations.
*** ../i386-protos.h Sun Mar 25 13:54:06 2001
--- i386-protos.h Wed Apr 4 11:34:31 2001
*************** extern void ix86_expand_branch PARAMS ((
*** 118,123 ****
--- 118,124 ----
extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
extern int ix86_expand_int_movcc PARAMS ((rtx[]));
extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
+ extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern void ix86_split_long_move PARAMS ((rtx[]));
extern void ix86_split_ashldi PARAMS ((rtx *, rtx));
extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));