aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1996-03-20 08:13:06 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1996-03-20 08:13:06 -0500
commit7565a035be546e2a97a4377a92fe89ed15e3b1de (patch)
tree4f0b2a5e5a036f62abaea592fe21453f862d5c72 /gcc
parentc4124c29e0b3803ff78cd69644f8ef259bc99f7b (diff)
downloadgcc-7565a035be546e2a97a4377a92fe89ed15e3b1de.zip
gcc-7565a035be546e2a97a4377a92fe89ed15e3b1de.tar.gz
gcc-7565a035be546e2a97a4377a92fe89ed15e3b1de.tar.bz2
(expand_builtin, case BUILT_IN_SETJMP): Call "setjmp" pattern, if any.
Call dummy function pointed to by static chain pointer. (expand_builtin, case BUILT_IN_LONJMP): Ignore second expression. Set address of __dummy into static chain pointer. Copy the label to return to into a pseudo earlier. From-SVN: r11576
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 33bfb6a..bcfcf97 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8526,6 +8526,11 @@ expand_builtin (exp, target, subtarget, mode, ignore)
rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
enum machine_mode sa_mode = Pmode;
rtx stack_save;
+ int old_inhibit_defer_pop = inhibit_defer_pop;
+ int return_pops = RETURN_POPS_ARGS (get_identifier ("__dummy"),
+ get_identifier ("__dummy"), 0);
+ rtx next_arg_reg;
+ CUMULATIVE_ARGS args_so_far;
int i;
if (target == 0 || GET_CODE (target) != REG
@@ -8558,6 +8563,11 @@ expand_builtin (exp, target, subtarget, mode, ignore)
2 * GET_MODE_SIZE (Pmode)));
emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
+#ifdef HAVE_setjmp
+ if (HAVE_setjmp)
+ emit_insn (gen_setjmp ());
+#endif
+
/* Set TARGET to zero and branch around the other case. */
emit_move_insn (target, const0_rtx);
emit_jump_insn (gen_jump (lab2));
@@ -8605,18 +8615,44 @@ expand_builtin (exp, target, subtarget, mode, ignore)
}
#endif
- /* The result to return is in the static chain pointer. */
- if (GET_MODE (static_chain_rtx) == GET_MODE (target))
- emit_move_insn (target, static_chain_rtx);
+ /* The static chain pointer contains the address of dummy function.
+ We need to call it here to handle some PIC cases of restoring
+ a global pointer. Then return 1. */
+ op0 = copy_to_mode_reg (Pmode, static_chain_rtx);
+
+ /* We can't actually call emit_library_call here, so do everything
+ it does, which isn't much for a libfunc with no args. */
+ op0 = memory_address (FUNCTION_MODE, op0);
+
+ INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE,
+ gen_rtx (SYMBOL_REF, Pmode, "__dummy"));
+ next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
+
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#ifdef HAVE_call_pop
+ if (HAVE_call_pop)
+ emit_call_insn (gen_call_pop (gen_rtx (MEM, FUNCTION_MODE, op0),
+ const0_rtx, next_arg_reg,
+ GEN_INT (return_pops)));
+ else
+#endif
+#endif
+
+#ifdef HAVE_call
+ if (HAVE_call)
+ emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, op0),
+ const0_rtx, next_arg_reg, const0_rtx));
else
- convert_move (target, static_chain_rtx, 0);
+#endif
+ abort ();
+ emit_move_insn (target, const1_rtx);
emit_label (lab2);
return target;
}
/* __builtin_longjmp is passed a pointer to an array of five words
- and a value to return. It's similar to the C library longjmp
+ and a value, which is a dummy. It's similar to the C library longjmp
function but works with __builtin_setjmp above. */
case BUILT_IN_LONGJMP:
if (arglist == 0 || TREE_CHAIN (arglist) == 0
@@ -8641,8 +8677,13 @@ expand_builtin (exp, target, subtarget, mode, ignore)
rtx stack = gen_rtx (MEM, sa_mode,
plus_constant (buf_addr,
2 * GET_MODE_SIZE (Pmode)));
- rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), NULL_RTX,
- VOIDmode, 0);
+ rtx value = gen_rtx (SYMBOL_REF, Pmode, "__dummy");
+
+ /* Expand the second expression just for side-effects. */
+ expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
+ const0_rtx, VOIDmode, 0);
+
+ assemble_external_libcall (value);
/* Pick up FP, label, and SP from the block and jump. This code is
from expand_goto in stmt.c; see there for detailed comments. */
@@ -8652,15 +8693,17 @@ expand_builtin (exp, target, subtarget, mode, ignore)
else
#endif
{
+ lab = copy_to_reg (lab);
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
- /* Put in the static chain register the return value. */
+ /* Put in the static chain register the address of the dummy
+ function. */
emit_move_insn (static_chain_rtx, value);
emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
- emit_indirect_jump (copy_to_reg (lab));
+ emit_indirect_jump (lab);
}
return const0_rtx;