diff options
author | bothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-19 11:19:30 +0000 |
---|---|---|
committer | bothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-19 11:19:30 +0000 |
commit | f0c211a3522fdd4483b0c67aeea8b8a17ab53167 (patch) | |
tree | bbb286d2229f9d7d1a2903893d12e929efbe9d22 /gcc/expr.c | |
parent | ca8c4cdab0cbde9ab5e1a6e55fc51204dae60922 (diff) | |
download | ppe42-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.c | 42 |
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 (); |