1 /* Convert language-specific tree expression to rtl instructions,
3 Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
32 /* Hook used by expand_expr to expand language-specific tree codes. */
35 cplus_expand_expr (exp, target, tmode, modifier)
38 enum machine_mode tmode;
39 enum expand_modifier modifier;
41 tree type = TREE_TYPE (exp);
42 register enum machine_mode mode = TYPE_MODE (type);
43 register enum tree_code code = TREE_CODE (exp);
44 rtx original_target = target;
45 int ignore = target == const0_rtx;
48 target = 0, original_target = 0;
50 /* No sense saving up arithmetic to be done
51 if it's all in the wrong mode to form part of an address.
52 And force_operand won't know whether to sign-extend or zero-extend. */
54 if (mode != Pmode && modifier == EXPAND_SUM)
55 modifier = EXPAND_NORMAL;
61 /* Something needs to be initialized, but we didn't know
62 where that thing was when building the tree. For example,
63 it could be the return value of a function, or a parameter
64 to a function which lays down in the stack, or a temporary
65 variable which must be passed by reference.
67 Cleanups are handled in a language-specific way: they
68 might be run by the called function (true in GNU C++
69 for parameters with cleanups), or they might be
70 run by the caller, after the call (true in GNU C++
71 for other cleanup needs). */
73 tree func = TREE_OPERAND (exp, 0);
74 tree args = TREE_OPERAND (exp, 1);
75 tree type = TREE_TYPE (exp), slot;
76 tree fn_type = TREE_TYPE (TREE_TYPE (func));
77 tree return_type = TREE_TYPE (fn_type);
79 rtx call_target, return_target;
80 int pcc_struct_return = 0;
82 /* The expression `init' wants to initialize what
83 `target' represents. SLOT holds the slot for TARGET. */
84 slot = TREE_OPERAND (exp, 2);
88 /* Should always be called with a target in BLKmode case. */
89 my_friendly_assert (mode != BLKmode, 205);
90 my_friendly_assert (DECL_RTL (slot) != 0, 206);
92 target = gen_reg_rtx (mode);
95 /* The target the initializer will initialize (CALL_TARGET)
96 must now be directed to initialize the target we are
97 supposed to initialize (TARGET). The semantics for
98 choosing what CALL_TARGET is is language-specific,
99 as is building the call which will perform the
100 initialization. It is left here to show the choices that
103 if (TREE_CODE (func) == ADDR_EXPR
104 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
105 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
107 type = TYPE_POINTER_TO (type);
108 /* Don't clobber a value that might be part of a default
110 if (TREE_PERMANENT (args))
111 args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
114 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
117 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
124 #ifdef PCC_STATIC_STRUCT_RETURN
125 pcc_struct_return = 1;
128 call_target = target;
133 preserve_temp_slots (call_target);
135 /* Make this a valid memory address now. The code below assumes
136 that it can compare rtx and make assumptions based on the
137 result. The assumptions are true only if the address was
138 valid to begin with. */
139 call_target = validize_mem (call_target);
142 preserve_temp_slots (DECL_RTL (slot));
143 call_exp = build (CALL_EXPR, type, func, args, 0);
144 TREE_SIDE_EFFECTS (call_exp) = 1;
145 return_target = expand_expr (call_exp, call_target, mode, 0);
147 if (call_target == 0)
149 if (pcc_struct_return)
151 tree init = build (RTL_EXPR, type, 0, return_target);
152 TREE_ADDRESSABLE (init) = 1;
153 expand_aggr_init (slot, init, 0);
154 if (TYPE_NEEDS_DESTRUCTOR (type))
156 init = build (RTL_EXPR, build_reference_type (type), 0,
157 XEXP (return_target, 0));
158 init = maybe_build_cleanup (convert_from_reference (init));
159 if (init != NULL_TREE)
160 expand_expr (init, 0, 0, 0);
162 call_target = return_target = DECL_RTL (slot);
165 call_target = return_target;
168 if (call_target != return_target)
170 my_friendly_assert (! TYPE_NEEDS_CONSTRUCTING (type), 317);
171 if (GET_MODE (return_target) == BLKmode)
172 emit_block_move (call_target, return_target, expr_size (exp),
173 TYPE_ALIGN (type) / BITS_PER_UNIT);
175 emit_move_insn (call_target, return_target);
178 if (TREE_CODE (return_type) == REFERENCE_TYPE)
182 if (GET_CODE (call_target) == REG
183 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
184 my_friendly_abort (39);
186 type = TREE_TYPE (exp);
188 init = build (RTL_EXPR, return_type, 0, call_target);
189 /* We got back a reference to the type we want. Now initialize
191 expand_aggr_init (slot, init, 0);
194 if (DECL_RTL (slot) != target)
195 emit_move_insn (DECL_RTL (slot), target);
196 return DECL_RTL (slot);
202 return expand_expr (default_conversion (resolve_offset_ref (exp)),
203 target, tmode, EXPAND_NORMAL);
205 /* This is old crusty code, and does not handle all that the
206 resolve_offset_ref function does. (mrs) */
207 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
208 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
209 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
210 target, tmode, EXPAND_NORMAL);
217 my_friendly_abort (40);
225 lang_expand_expr = cplus_expand_expr;
228 /* If DECL had its rtl moved from where callers expect it
229 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
230 which may be a pseudo instead of a hard register. */
233 fixup_result_decl (decl, result)
239 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
241 rtx real_decl_result;
243 #ifdef FUNCTION_OUTGOING_VALUE
245 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
248 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
250 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
251 result = real_decl_result;
253 emit_move_insn (result, DECL_RTL (decl));
254 emit_insn (gen_rtx (USE, VOIDmode, result));
258 /* Return nonzero iff DECL is memory-based. The DECL_RTL of
259 certain const variables might be a CONST_INT, or a REG
260 in some cases. We cannot use `memory_operand' as a test
261 here because on most RISC machines, a variable's address
262 is not, by itself, a legitimate address. */
264 decl_in_memory_p (decl)
267 return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM;