expr.c revision 18334
1/* Convert language-specific tree expression to rtl instructions, 2 for GNU compiler. 3 Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 4 5This file is part of GNU CC. 6 7GNU CC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU CC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU CC; see the file COPYING. If not, write to 19the Free Software Foundation, 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22 23#include "config.h" 24#include "rtl.h" 25#include "tree.h" 26#include "flags.h" 27#include "expr.h" 28#include "cp-tree.h" 29 30#undef NULL 31#define NULL 0 32 33/* Hook used by expand_expr to expand language-specific tree codes. */ 34 35rtx 36cplus_expand_expr (exp, target, tmode, modifier) 37 tree exp; 38 rtx target; 39 enum machine_mode tmode; 40 enum expand_modifier modifier; 41{ 42 tree type = TREE_TYPE (exp); 43 register enum machine_mode mode = TYPE_MODE (type); 44 register enum tree_code code = TREE_CODE (exp); 45 rtx original_target = target; 46 int ignore = target == const0_rtx; 47 48 if (ignore) 49 target = 0, original_target = 0; 50 51 /* No sense saving up arithmetic to be done 52 if it's all in the wrong mode to form part of an address. 53 And force_operand won't know whether to sign-extend or zero-extend. */ 54 55 if (mode != Pmode && modifier == EXPAND_SUM) 56 modifier = EXPAND_NORMAL; 57 58 switch (code) 59 { 60 case NEW_EXPR: 61 { 62 /* Something needs to be initialized, but we didn't know 63 where that thing was when building the tree. For example, 64 it could be the return value of a function, or a parameter 65 to a function which lays down in the stack, or a temporary 66 variable which must be passed by reference. 67 68 Cleanups are handled in a language-specific way: they 69 might be run by the called function (true in GNU C++ 70 for parameters with cleanups), or they might be 71 run by the caller, after the call (true in GNU C++ 72 for other cleanup needs). */ 73 74 tree func = TREE_OPERAND (exp, 0); 75 tree args = TREE_OPERAND (exp, 1); 76 tree type = TREE_TYPE (exp), slot; 77 tree fn_type = TREE_TYPE (TREE_TYPE (func)); 78 tree return_type = TREE_TYPE (fn_type); 79 tree call_exp; 80 rtx call_target, return_target; 81 int pcc_struct_return = 0; 82 83 /* The expression `init' wants to initialize what 84 `target' represents. SLOT holds the slot for TARGET. */ 85 slot = TREE_OPERAND (exp, 2); 86 87 if (target == 0) 88 { 89 /* Should always be called with a target in BLKmode case. */ 90 my_friendly_assert (mode != BLKmode, 205); 91 my_friendly_assert (DECL_RTL (slot) != 0, 206); 92 93 target = gen_reg_rtx (mode); 94 } 95 96 /* The target the initializer will initialize (CALL_TARGET) 97 must now be directed to initialize the target we are 98 supposed to initialize (TARGET). The semantics for 99 choosing what CALL_TARGET is is language-specific, 100 as is building the call which will perform the 101 initialization. It is left here to show the choices that 102 exist for C++. */ 103 104 if (TREE_CODE (func) == ADDR_EXPR 105 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL 106 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) 107 { 108 type = build_pointer_type (type); 109 /* Don't clobber a value that might be part of a default 110 parameter value. */ 111 mark_addressable (slot); 112 if (TREE_PERMANENT (args)) 113 args = tree_cons (0, build1 (ADDR_EXPR, type, slot), 114 TREE_CHAIN (args)); 115 else 116 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot); 117 call_target = 0; 118 } 119 else if (TREE_CODE (return_type) == REFERENCE_TYPE) 120 { 121 type = return_type; 122 call_target = 0; 123 } 124 else 125 { 126#ifdef PCC_STATIC_STRUCT_RETURN 127 pcc_struct_return = 1; 128 call_target = 0; 129#else 130 call_target = target; 131#endif 132 } 133 if (call_target) 134 { 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); 140 } 141 142 call_exp = build (CALL_EXPR, type, func, args, 0); 143 TREE_SIDE_EFFECTS (call_exp) = 1; 144 return_target = expand_call (call_exp, call_target, ignore); 145 if (call_target == 0) 146 { 147 if (pcc_struct_return) 148 { 149 extern int flag_access_control; 150 int old_ac = flag_access_control; 151 152 tree init = build_decl (VAR_DECL, 0, type); 153 TREE_ADDRESSABLE (init) = 1; 154 DECL_RTL (init) = return_target; 155 156 flag_access_control = 0; 157 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); 158 flag_access_control = old_ac; 159 160 if (TYPE_NEEDS_DESTRUCTOR (type)) 161 { 162 init = build_decl (VAR_DECL, 0, 163 build_reference_type (type)); 164 DECL_RTL (init) = XEXP (return_target, 0); 165 166 init = maybe_build_cleanup (convert_from_reference (init)); 167 if (init != NULL_TREE) 168 expand_expr (init, 0, 0, 0); 169 } 170 call_target = return_target = DECL_RTL (slot); 171 } 172 else 173 call_target = return_target; 174 } 175 176 if (call_target != return_target) 177 { 178 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317); 179 if (GET_MODE (return_target) == BLKmode) 180 emit_block_move (call_target, return_target, expr_size (exp), 181 TYPE_ALIGN (type) / BITS_PER_UNIT); 182 else 183 emit_move_insn (call_target, return_target); 184 } 185 186 if (TREE_CODE (return_type) == REFERENCE_TYPE) 187 { 188 tree init; 189 190 if (GET_CODE (call_target) == REG 191 && REGNO (call_target) < FIRST_PSEUDO_REGISTER) 192 my_friendly_abort (39); 193 194 type = TREE_TYPE (exp); 195 196 init = build (RTL_EXPR, return_type, 0, call_target); 197 /* We got back a reference to the type we want. Now initialize 198 target with that. */ 199 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); 200 } 201 202 if (DECL_RTL (slot) != target) 203 emit_move_insn (DECL_RTL (slot), target); 204 return DECL_RTL (slot); 205 } 206 207 case OFFSET_REF: 208 { 209#if 1 210 return expand_expr (default_conversion (resolve_offset_ref (exp)), 211 target, tmode, EXPAND_NORMAL); 212#else 213 /* This is old crusty code, and does not handle all that the 214 resolve_offset_ref function does. (mrs) */ 215 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0); 216 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0); 217 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset), 218 target, tmode, EXPAND_NORMAL); 219#endif 220 } 221 222 case THUNK_DECL: 223 return DECL_RTL (exp); 224 225 case THROW_EXPR: 226 expand_throw (TREE_OPERAND (exp, 0)); 227 return NULL; 228 229 case UNSAVE_EXPR: 230 { 231 rtx temp; 232 temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); 233 TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0)); 234 return temp; 235 } 236 237 default: 238 break; 239 } 240 my_friendly_abort (40); 241 /* NOTREACHED */ 242 return NULL; 243} 244 245void 246init_cplus_expand () 247{ 248 lang_expand_expr = cplus_expand_expr; 249} 250 251/* If DECL had its rtl moved from where callers expect it 252 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL, 253 which may be a pseudo instead of a hard register. */ 254 255void 256fixup_result_decl (decl, result) 257 tree decl; 258 rtx result; 259{ 260 if (REG_P (result)) 261 { 262 if (REGNO (result) >= FIRST_PSEUDO_REGISTER) 263 { 264 rtx real_decl_result; 265 266#ifdef FUNCTION_OUTGOING_VALUE 267 real_decl_result 268 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl); 269#else 270 real_decl_result 271 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl); 272#endif 273 REG_FUNCTION_VALUE_P (real_decl_result) = 1; 274 result = real_decl_result; 275 } 276 store_expr (decl, result, 0); 277 emit_insn (gen_rtx (USE, VOIDmode, result)); 278 } 279} 280 281/* Return nonzero iff DECL is memory-based. The DECL_RTL of 282 certain const variables might be a CONST_INT, or a REG 283 in some cases. We cannot use `memory_operand' as a test 284 here because on most RISC machines, a variable's address 285 is not, by itself, a legitimate address. */ 286 287int 288decl_in_memory_p (decl) 289 tree decl; 290{ 291 return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM; 292} 293 294/* Expand this initialization inline and see if it's simple enough that 295 it can be done at compile-time. */ 296 297static tree 298extract_aggr_init (decl, init) 299 tree decl, init; 300{ 301 return 0; 302} 303 304static tree 305extract_scalar_init (decl, init) 306 tree decl, init; 307{ 308 rtx value, insns, insn; 309 extern struct obstack temporary_obstack; 310 tree t = NULL_TREE; 311 312 push_obstacks (&temporary_obstack, &temporary_obstack); 313 start_sequence (); 314 value = expand_expr (init, NULL_RTX, VOIDmode, 0); 315 insns = get_insns (); 316 end_sequence (); 317 reg_scan (insns, max_reg_num (), 0); 318 jump_optimize (insns, 0, 0, 1); 319 pop_obstacks (); 320 321 for (insn = insns; insn; insn = NEXT_INSN (insn)) 322 { 323 rtx r, to; 324 325 if (GET_CODE (insn) == NOTE) 326 continue; 327 else if (GET_CODE (insn) != INSN) 328 return 0; 329 330 r = PATTERN (insn); 331 if (GET_CODE (r) != SET) 332 return 0; 333 334 to = XEXP (r, 0); 335 336 if (! (to == value || 337 (GET_CODE (to) == SUBREG && XEXP (to, 0) == value))) 338 return 0; 339 340 r = XEXP (r, 1); 341 342 switch (GET_CODE (r)) 343 { 344 case CONST_INT: 345 t = build_int_2 (XEXP (r, 0), 0); 346 break; 347 default: 348 return 0; 349 } 350 } 351 352 return t; 353} 354 355int 356extract_init (decl, init) 357 tree decl, init; 358{ 359 return 0; 360 361 if (IS_AGGR_TYPE (TREE_TYPE (decl)) 362 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) 363 init = extract_aggr_init (decl, init); 364 else 365 init = extract_scalar_init (decl, init); 366 367 if (init == NULL_TREE) 368 return 0; 369 370 DECL_INITIAL (decl) = init; 371 return 1; 372} 373