summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-05 17:18:42 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-04-05 17:18:42 +0000
commit0d6407f74b4eaef54baea40c30eed2629c0a68ee (patch)
treebf9672e66fd1e53dd0aef46ae1f998d9353b68a1 /gcc
parentee58269bfa2884dfcb683621a66c4fc742311b4d (diff)
downloadppe42-gcc-0d6407f74b4eaef54baea40c30eed2629c0a68ee.tar.gz
ppe42-gcc-0d6407f74b4eaef54baea40c30eed2629c0a68ee.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41123 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c60
2 files changed, 67 insertions, 0 deletions
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 <jh@suse.cz>
+
+ * 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 <jh@suse.cz>
* 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)
OpenPOWER on IntegriCloud