summaryrefslogtreecommitdiffstats
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-19 11:19:30 +0000
committerbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>1999-02-19 11:19:30 +0000
commitf0c211a3522fdd4483b0c67aeea8b8a17ab53167 (patch)
treebbb286d2229f9d7d1a2903893d12e929efbe9d22 /gcc/expr.c
parentca8c4cdab0cbde9ab5e1a6e55fc51204dae60922 (diff)
downloadppe42-gcc-f0c211a3522fdd4483b0c67aeea8b8a17ab53167.tar.gz
ppe42-gcc-f0c211a3522fdd4483b0c67aeea8b8a17ab53167.zip
h
* tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes, * expr.c (expand_expr): Support new tree nodes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25308 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 63d9155d8ac..660bba6e319 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6720,7 +6720,6 @@ expand_expr (exp, target, tmode, modifier)
case CLEANUP_POINT_EXPR:
{
- extern int temp_slot_level;
/* Start a new binding layer that will keep track of all cleanup
actions to be performed. */
expand_start_bindings (0);
@@ -8088,6 +8087,47 @@ expand_expr (exp, target, tmode, modifier)
return op0;
}
+ case TRY_FINALLY_EXPR:
+ {
+ tree try_block = TREE_OPERAND (exp, 0);
+ tree finally_block = TREE_OPERAND (exp, 1);
+ rtx finally_label = gen_label_rtx ();
+ rtx done_label = gen_label_rtx ();
+ rtx return_link = gen_reg_rtx (Pmode);
+ tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
+ (tree) finally_label, (tree) return_link);
+ TREE_SIDE_EFFECTS (cleanup) = 1;
+
+ /* Start a new binding layer that will keep track of all cleanup
+ actions to be performed. */
+ expand_start_bindings (0);
+
+ target_temp_slot_level = temp_slot_level;
+
+ expand_decl_cleanup (NULL_TREE, cleanup);
+ op0 = expand_expr (try_block, target, tmode, modifier);
+
+ preserve_temp_slots (op0);
+ expand_end_bindings (NULL_TREE, 0, 0);
+ emit_jump (done_label);
+ emit_label (finally_label);
+ expand_expr (finally_block, const0_rtx, VOIDmode, 0);
+ emit_indirect_jump (return_link);
+ emit_label (done_label);
+ return op0;
+ }
+
+ case GOTO_SUBROUTINE_EXPR:
+ {
+ rtx subr = (rtx) TREE_OPERAND (exp, 0);
+ rtx return_link = *(rtx *) &TREE_OPERAND (exp, 1);
+ rtx return_address = gen_label_rtx ();
+ emit_move_insn (return_link, gen_rtx_LABEL_REF (Pmode, return_address));
+ emit_jump (subr);
+ emit_label (return_address);
+ return const0_rtx;
+ }
+
case POPDCC_EXPR:
{
rtx dcc = get_dynamic_cleanup_chain ();
OpenPOWER on IntegriCloud