From 0ed08620808411f590329745e901c998a0d7f408 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 5 Apr 2001 19:18:42 +0200 Subject: [PATCH] i386.c (x86_initialize_trampoline): New global function. * 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. From-SVN: r41123 --- gcc/ChangeLog | 7 +++++ gcc/config/i386/i386.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1584195ca88..f40281a92e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Thu Apr 5 19:13:33 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. + Thu Apr 5 19:02:15 CEST 2001 Jan Hubicka * i386.md (movdi_1_rex64): Allow SSE->SSE reg move. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 0c79e70e6e7..a3bbc7827e9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8936,6 +8936,66 @@ ix86_local_alignment (type, align) } 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 (trunc_int_for_mode (0xb9, QImode))); + 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 (trunc_int_for_mode (0xe9, QImode))); + 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 (trunc_int_for_mode (0xbb41, HImode))); + 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 (trunc_int_for_mode (0xbb49, HImode))); + 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 (trunc_int_for_mode (0xba49, HImode))); + 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 (trunc_int_for_mode (0xff49, HImode))); + emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, offset+2)), + GEN_INT (trunc_int_for_mode (0xe3, HImode))); + offset += 3; + if (offset > TRAMPOLINE_SIZE) + abort(); + } +} #define def_builtin(NAME, TYPE, CODE) \ builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL_PTR) -- 2.30.2