Branch data Line data Source code
1 : : /* Convert tree expression to rtl instructions, for GNU compiler.
2 : : Copyright (C) 1988-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "backend.h"
24 : : #include "target.h"
25 : : #include "rtl.h"
26 : : #include "tree.h"
27 : : #include "gimple.h"
28 : : #include "predict.h"
29 : : #include "memmodel.h"
30 : : #include "tm_p.h"
31 : : #include "ssa.h"
32 : : #include "optabs.h"
33 : : #include "expmed.h"
34 : : #include "regs.h"
35 : : #include "emit-rtl.h"
36 : : #include "recog.h"
37 : : #include "cgraph.h"
38 : : #include "diagnostic.h"
39 : : #include "alias.h"
40 : : #include "fold-const.h"
41 : : #include "stor-layout.h"
42 : : #include "attribs.h"
43 : : #include "varasm.h"
44 : : #include "except.h"
45 : : #include "insn-attr.h"
46 : : #include "dojump.h"
47 : : #include "explow.h"
48 : : #include "calls.h"
49 : : #include "stmt.h"
50 : : /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
51 : : #include "expr.h"
52 : : #include "optabs-tree.h"
53 : : #include "libfuncs.h"
54 : : #include "reload.h"
55 : : #include "langhooks.h"
56 : : #include "common/common-target.h"
57 : : #include "tree-dfa.h"
58 : : #include "tree-ssa-live.h"
59 : : #include "tree-outof-ssa.h"
60 : : #include "tree-ssa-address.h"
61 : : #include "builtins.h"
62 : : #include "ccmp.h"
63 : : #include "gimple-iterator.h"
64 : : #include "gimple-fold.h"
65 : : #include "rtx-vector-builder.h"
66 : : #include "tree-pretty-print.h"
67 : : #include "flags.h"
68 : : #include "internal-fn.h"
69 : :
70 : :
71 : : /* If this is nonzero, we do not bother generating VOLATILE
72 : : around volatile memory references, and we are willing to
73 : : output indirect addresses. If cse is to follow, we reject
74 : : indirect addresses so a useful potential cse is generated;
75 : : if it is used only once, instruction combination will produce
76 : : the same indirect address eventually. */
77 : : int cse_not_expected;
78 : :
79 : : static bool block_move_libcall_safe_for_call_parm (void);
80 : : static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
81 : : HOST_WIDE_INT, unsigned HOST_WIDE_INT,
82 : : unsigned HOST_WIDE_INT,
83 : : unsigned HOST_WIDE_INT, bool);
84 : : static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned, int);
85 : : static void emit_block_move_via_sized_loop (rtx, rtx, rtx, unsigned, unsigned);
86 : : static void emit_block_move_via_oriented_loop (rtx, rtx, rtx, unsigned, unsigned);
87 : : static rtx emit_block_cmp_via_loop (rtx, rtx, rtx, tree, rtx, bool,
88 : : unsigned, unsigned);
89 : : static rtx_insn *compress_float_constant (rtx, rtx);
90 : : static rtx get_subtarget (rtx);
91 : : static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
92 : : machine_mode, tree, alias_set_type, bool, bool);
93 : :
94 : : static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
95 : :
96 : : static bool is_aligning_offset (const_tree, const_tree);
97 : : static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
98 : : static rtx do_store_flag (const_sepops, rtx, machine_mode);
99 : : #ifdef PUSH_ROUNDING
100 : : static void emit_single_push_insn (machine_mode, rtx, tree);
101 : : #endif
102 : : static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
103 : : profile_probability);
104 : : static rtx const_vector_from_tree (tree);
105 : : static tree tree_expr_size (const_tree);
106 : : static void convert_mode_scalar (rtx, rtx, int);
107 : :
108 : :
109 : : /* This is run to set up which modes can be used
110 : : directly in memory and to initialize the block move optab. It is run
111 : : at the beginning of compilation and when the target is reinitialized. */
112 : :
113 : : void
114 : 211512 : init_expr_target (void)
115 : : {
116 : 211512 : rtx pat;
117 : 211512 : int num_clobbers;
118 : 211512 : rtx mem, mem1;
119 : 211512 : rtx reg;
120 : :
121 : : /* Try indexing by frame ptr and try by stack ptr.
122 : : It is known that on the Convex the stack ptr isn't a valid index.
123 : : With luck, one or the other is valid on any machine. */
124 : 211512 : mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
125 : 211512 : mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
126 : :
127 : : /* A scratch register we can modify in-place below to avoid
128 : : useless RTL allocations. */
129 : 211512 : reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
130 : :
131 : 211512 : rtx_insn *insn = as_a<rtx_insn *> (rtx_alloc (INSN));
132 : 211512 : pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
133 : 211512 : PATTERN (insn) = pat;
134 : :
135 : 27708072 : for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
136 : 27496560 : mode = (machine_mode) ((int) mode + 1))
137 : : {
138 : 27496560 : int regno;
139 : :
140 : 27496560 : direct_load[(int) mode] = direct_store[(int) mode] = 0;
141 : 27496560 : PUT_MODE (mem, mode);
142 : 27496560 : PUT_MODE (mem1, mode);
143 : :
144 : : /* See if there is some register that can be used in this mode and
145 : : directly loaded or stored from memory. */
146 : :
147 : 27496560 : if (mode != VOIDmode && mode != BLKmode)
148 : 1884485534 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER
149 : 1911559070 : && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
150 : : regno++)
151 : : {
152 : 1884485534 : if (!targetm.hard_regno_mode_ok (regno, mode))
153 : 1768735041 : continue;
154 : :
155 : 115750493 : set_mode_and_regno (reg, mode, regno);
156 : :
157 : 115750493 : SET_SRC (pat) = mem;
158 : 115750493 : SET_DEST (pat) = reg;
159 : 115750493 : if (recog (pat, insn, &num_clobbers) >= 0)
160 : 7113454 : direct_load[(int) mode] = 1;
161 : :
162 : 115750493 : SET_SRC (pat) = mem1;
163 : 115750493 : SET_DEST (pat) = reg;
164 : 115750493 : if (recog (pat, insn, &num_clobbers) >= 0)
165 : 7113454 : direct_load[(int) mode] = 1;
166 : :
167 : 115750493 : SET_SRC (pat) = reg;
168 : 115750493 : SET_DEST (pat) = mem;
169 : 115750493 : if (recog (pat, insn, &num_clobbers) >= 0)
170 : 7113454 : direct_store[(int) mode] = 1;
171 : :
172 : 115750493 : SET_SRC (pat) = reg;
173 : 115750493 : SET_DEST (pat) = mem1;
174 : 115750493 : if (recog (pat, insn, &num_clobbers) >= 0)
175 : 7113454 : direct_store[(int) mode] = 1;
176 : : }
177 : : }
178 : :
179 : 217162 : mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
180 : :
181 : 211512 : opt_scalar_float_mode mode_iter;
182 : 1480584 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
183 : : {
184 : 1269072 : scalar_float_mode mode = mode_iter.require ();
185 : 1269072 : scalar_float_mode srcmode;
186 : 4441752 : FOR_EACH_MODE_UNTIL (srcmode, mode)
187 : : {
188 : 3172680 : enum insn_code ic;
189 : :
190 : 3172680 : ic = can_extend_p (mode, srcmode, 0);
191 : 3172680 : if (ic == CODE_FOR_nothing)
192 : 2533741 : continue;
193 : :
194 : 638939 : PUT_MODE (mem, srcmode);
195 : :
196 : 638939 : if (insn_operand_matches (ic, 1, mem))
197 : 636862 : float_extend_from_mem[mode][srcmode] = true;
198 : : }
199 : : }
200 : 211512 : }
201 : :
202 : : /* This is run at the start of compiling a function. */
203 : :
204 : : void
205 : 1667664 : init_expr (void)
206 : : {
207 : 1667664 : memset (&crtl->expr, 0, sizeof (crtl->expr));
208 : 1667664 : }
209 : :
210 : : /* Copy data from FROM to TO, where the machine modes are not the same.
211 : : Both modes may be integer, or both may be floating, or both may be
212 : : fixed-point.
213 : : UNSIGNEDP should be nonzero if FROM is an unsigned type.
214 : : This causes zero-extension instead of sign-extension. */
215 : :
216 : : void
217 : 2026593 : convert_move (rtx to, rtx from, int unsignedp)
218 : : {
219 : 2026593 : machine_mode to_mode = GET_MODE (to);
220 : 2026593 : machine_mode from_mode = GET_MODE (from);
221 : :
222 : 2026593 : gcc_assert (to_mode != BLKmode);
223 : 2026593 : gcc_assert (from_mode != BLKmode);
224 : :
225 : : /* If the source and destination are already the same, then there's
226 : : nothing to do. */
227 : 2026593 : if (to == from)
228 : 2026593 : return;
229 : :
230 : : /* If FROM is a SUBREG that indicates that we have already done at least
231 : : the required extension, strip it. We don't handle such SUBREGs as
232 : : TO here. */
233 : :
234 : 2026593 : scalar_int_mode to_int_mode;
235 : 2026593 : if (GET_CODE (from) == SUBREG
236 : 110142 : && SUBREG_PROMOTED_VAR_P (from)
237 : 2026593 : && is_a <scalar_int_mode> (to_mode, &to_int_mode)
238 : 2026593 : && (GET_MODE_PRECISION (subreg_promoted_mode (from))
239 : 0 : >= GET_MODE_PRECISION (to_int_mode))
240 : 2026593 : && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
241 : : {
242 : 0 : scalar_int_mode int_orig_mode;
243 : 0 : scalar_int_mode int_inner_mode;
244 : 0 : machine_mode orig_mode = GET_MODE (from);
245 : :
246 : 0 : from = gen_lowpart (to_int_mode, SUBREG_REG (from));
247 : 0 : from_mode = to_int_mode;
248 : :
249 : : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
250 : : the original mode, but narrower than the inner mode. */
251 : 0 : if (GET_CODE (from) == SUBREG
252 : 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
253 : 0 : && GET_MODE_PRECISION (to_int_mode)
254 : 0 : > GET_MODE_PRECISION (int_orig_mode)
255 : 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
256 : : &int_inner_mode)
257 : 0 : && GET_MODE_PRECISION (int_inner_mode)
258 : 0 : > GET_MODE_PRECISION (to_int_mode))
259 : : {
260 : 0 : SUBREG_PROMOTED_VAR_P (from) = 1;
261 : 0 : SUBREG_PROMOTED_SET (from, unsignedp);
262 : : }
263 : : }
264 : :
265 : 2026593 : gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
266 : :
267 : 2026593 : if (to_mode == from_mode
268 : 1974441 : || (from_mode == VOIDmode && CONSTANT_P (from)))
269 : : {
270 : 52417 : emit_move_insn (to, from);
271 : 52417 : return;
272 : : }
273 : :
274 : 1974176 : if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
275 : : {
276 : 28092 : if (GET_MODE_UNIT_PRECISION (to_mode)
277 : 14046 : > GET_MODE_UNIT_PRECISION (from_mode))
278 : : {
279 : 5296 : optab op = unsignedp ? zext_optab : sext_optab;
280 : 5296 : insn_code icode = convert_optab_handler (op, to_mode, from_mode);
281 : 5296 : if (icode != CODE_FOR_nothing)
282 : : {
283 : 476 : emit_unop_insn (icode, to, from,
284 : : unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
285 : 476 : return;
286 : : }
287 : : }
288 : :
289 : 27140 : if (GET_MODE_UNIT_PRECISION (to_mode)
290 : 13570 : < GET_MODE_UNIT_PRECISION (from_mode))
291 : : {
292 : 1836 : insn_code icode = convert_optab_handler (trunc_optab,
293 : : to_mode, from_mode);
294 : 1836 : if (icode != CODE_FOR_nothing)
295 : : {
296 : 811 : emit_unop_insn (icode, to, from, TRUNCATE);
297 : 811 : return;
298 : : }
299 : : }
300 : :
301 : 38277 : gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
302 : : GET_MODE_BITSIZE (to_mode)));
303 : :
304 : 12759 : if (VECTOR_MODE_P (to_mode))
305 : 12759 : from = force_subreg (to_mode, from, GET_MODE (from), 0);
306 : : else
307 : 0 : to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
308 : :
309 : 12759 : emit_move_insn (to, from);
310 : 12759 : return;
311 : : }
312 : :
313 : 1960130 : if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
314 : : {
315 : 0 : convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
316 : 0 : convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
317 : 0 : return;
318 : : }
319 : :
320 : 1960130 : convert_mode_scalar (to, from, unsignedp);
321 : : }
322 : :
323 : : /* Like convert_move, but deals only with scalar modes. */
324 : :
325 : : static void
326 : 1960174 : convert_mode_scalar (rtx to, rtx from, int unsignedp)
327 : : {
328 : : /* Both modes should be scalar types. */
329 : 1960179 : scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
330 : 1960179 : scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
331 : 1960179 : bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
332 : 1960179 : bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
333 : 1960179 : enum insn_code code;
334 : 1960179 : rtx libcall;
335 : :
336 : 1960179 : gcc_assert (to_real == from_real);
337 : :
338 : : /* rtx code for making an equivalent value. */
339 : 3062110 : enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
340 : 1960179 : : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
341 : :
342 : 1960179 : auto acceptable_same_precision_modes
343 : 580 : = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
344 : : {
345 : 580 : if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
346 : : return true;
347 : :
348 : : /* arm_bfloat_half_format <-> ieee_half_format */
349 : 2 : if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
350 : 1 : && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
351 : 2 : || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
352 : 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
353 : : return true;
354 : :
355 : : /* ibm_extended_format <-> ieee_quad_format */
356 : 0 : if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
357 : 0 : && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
358 : 0 : || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
359 : 0 : && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
360 : 0 : return true;
361 : :
362 : : return false;
363 : : };
364 : :
365 : 1960179 : if (to_real)
366 : : {
367 : 185229 : rtx value;
368 : 185229 : rtx_insn *insns;
369 : 185229 : convert_optab tab;
370 : :
371 : 185229 : gcc_assert ((GET_MODE_PRECISION (from_mode)
372 : : != GET_MODE_PRECISION (to_mode))
373 : : || acceptable_same_precision_modes (from_mode, to_mode));
374 : :
375 : 185229 : if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
376 : : {
377 : 580 : if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
378 : 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
379 : 580 : || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
380 : 0 : && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
381 : : /* libgcc implements just __trunchfbf2, not __extendhfbf2;
382 : : and __trunctfkf2, not __extendtfkf2. */
383 : : tab = trunc_optab;
384 : : else
385 : : /* Conversion between decimal float and binary float, same
386 : : size. */
387 : 579 : tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
388 : : }
389 : 184649 : else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
390 : : tab = sext_optab;
391 : : else
392 : 19243 : tab = trunc_optab;
393 : :
394 : : /* Try converting directly if the insn is supported. */
395 : :
396 : 185229 : code = convert_optab_handler (tab, to_mode, from_mode);
397 : 185229 : if (code != CODE_FOR_nothing)
398 : : {
399 : 160833 : emit_unop_insn (code, to, from,
400 : : tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
401 : 160833 : return;
402 : : }
403 : :
404 : : #ifdef HAVE_SFmode
405 : 24396 : if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
406 : 24396 : && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
407 : : {
408 : 2739 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
409 : : {
410 : : /* To cut down on libgcc size, implement
411 : : BFmode -> {DF,XF,TF}mode conversions by
412 : : BFmode -> SFmode -> {DF,XF,TF}mode conversions. */
413 : 4 : rtx temp = gen_reg_rtx (SFmode);
414 : 4 : convert_mode_scalar (temp, from, unsignedp);
415 : 4 : convert_mode_scalar (to, temp, unsignedp);
416 : 4 : return;
417 : : }
418 : 2735 : if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
419 : : {
420 : : /* Similarly, implement BFmode -> HFmode as
421 : : BFmode -> SFmode -> HFmode conversion where SFmode
422 : : has superset of BFmode values. We don't need
423 : : to handle sNaNs by raising exception and turning
424 : : it into qNaN though, as that can be done in the
425 : : SFmode -> HFmode conversion too. */
426 : 1 : rtx temp = gen_reg_rtx (SFmode);
427 : 1 : int save_flag_finite_math_only = flag_finite_math_only;
428 : 1 : flag_finite_math_only = true;
429 : 1 : convert_mode_scalar (temp, from, unsignedp);
430 : 1 : flag_finite_math_only = save_flag_finite_math_only;
431 : 1 : convert_mode_scalar (to, temp, unsignedp);
432 : 1 : return;
433 : : }
434 : 2734 : if (to_mode == SFmode
435 : 2734 : && !HONOR_NANS (from_mode)
436 : 40 : && !HONOR_NANS (to_mode)
437 : 2774 : && optimize_insn_for_speed_p ())
438 : : {
439 : : /* If we don't expect sNaNs, for BFmode -> SFmode we can just
440 : : shift the bits up. */
441 : 39 : machine_mode fromi_mode, toi_mode;
442 : 78 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
443 : 39 : 0).exists (&fromi_mode)
444 : 39 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
445 : 0 : 0).exists (&toi_mode))
446 : : {
447 : 39 : start_sequence ();
448 : 39 : rtx fromi = force_lowpart_subreg (fromi_mode, from,
449 : : from_mode);
450 : 39 : rtx tof = NULL_RTX;
451 : 39 : if (fromi)
452 : : {
453 : 39 : rtx toi;
454 : 39 : if (GET_MODE (fromi) == VOIDmode)
455 : 0 : toi = simplify_unary_operation (ZERO_EXTEND, toi_mode,
456 : : fromi, fromi_mode);
457 : : else
458 : : {
459 : 39 : toi = gen_reg_rtx (toi_mode);
460 : 39 : convert_mode_scalar (toi, fromi, 1);
461 : : }
462 : 39 : toi
463 : 78 : = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
464 : 39 : GET_MODE_PRECISION (to_mode)
465 : 39 : - GET_MODE_PRECISION (from_mode),
466 : : NULL_RTX, 1);
467 : 39 : if (toi)
468 : : {
469 : 39 : tof = force_lowpart_subreg (to_mode, toi, toi_mode);
470 : 39 : if (tof)
471 : 39 : emit_move_insn (to, tof);
472 : : }
473 : : }
474 : 39 : insns = end_sequence ();
475 : 39 : if (tof)
476 : : {
477 : 39 : emit_insn (insns);
478 : 39 : return;
479 : : }
480 : : }
481 : : }
482 : : }
483 : 24352 : if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
484 : 5009 : && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
485 : 1804 : && !HONOR_NANS (from_mode)
486 : 0 : && !HONOR_NANS (to_mode)
487 : 0 : && !flag_rounding_math
488 : 24352 : && optimize_insn_for_speed_p ())
489 : : {
490 : : /* If we don't expect qNaNs nor sNaNs and can assume rounding
491 : : to nearest, we can expand the conversion inline as
492 : : (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16. */
493 : 0 : machine_mode fromi_mode, toi_mode;
494 : 0 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
495 : 0 : 0).exists (&fromi_mode)
496 : 0 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
497 : 0 : 0).exists (&toi_mode))
498 : : {
499 : 0 : start_sequence ();
500 : 0 : rtx fromi = force_lowpart_subreg (fromi_mode, from, from_mode);
501 : 0 : rtx tof = NULL_RTX;
502 : 0 : do
503 : : {
504 : 0 : if (!fromi)
505 : : break;
506 : 0 : int shift = (GET_MODE_PRECISION (from_mode)
507 : 0 : - GET_MODE_PRECISION (to_mode));
508 : 0 : rtx temp1
509 : 0 : = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
510 : : shift, NULL_RTX, 1);
511 : 0 : if (!temp1)
512 : : break;
513 : 0 : rtx temp2
514 : 0 : = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
515 : : NULL_RTX, 1, OPTAB_DIRECT);
516 : 0 : if (!temp2)
517 : : break;
518 : 0 : rtx temp3
519 : 0 : = expand_binop (fromi_mode, add_optab, fromi,
520 : : gen_int_mode ((HOST_WIDE_INT_1U
521 : 0 : << (shift - 1)) - 1,
522 : : fromi_mode), NULL_RTX,
523 : : 1, OPTAB_DIRECT);
524 : 0 : if (!temp3)
525 : : break;
526 : 0 : rtx temp4
527 : 0 : = expand_binop (fromi_mode, add_optab, temp3, temp2,
528 : : NULL_RTX, 1, OPTAB_DIRECT);
529 : 0 : if (!temp4)
530 : : break;
531 : 0 : rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
532 : : temp4, shift, NULL_RTX, 1);
533 : 0 : if (!temp5)
534 : : break;
535 : 0 : rtx temp6 = force_lowpart_subreg (toi_mode, temp5,
536 : : fromi_mode);
537 : 0 : if (!temp6)
538 : : break;
539 : 0 : tof = force_lowpart_subreg (to_mode, temp6, toi_mode);
540 : 0 : if (tof)
541 : 0 : emit_move_insn (to, tof);
542 : : }
543 : : while (0);
544 : 0 : insns = end_sequence ();
545 : 0 : if (tof)
546 : : {
547 : 0 : emit_insn (insns);
548 : 0 : return;
549 : : }
550 : : }
551 : : }
552 : : #endif
553 : :
554 : : /* Otherwise use a libcall. */
555 : 24352 : libcall = convert_optab_libfunc (tab, to_mode, from_mode);
556 : :
557 : : /* Is this conversion implemented yet? */
558 : 24352 : gcc_assert (libcall);
559 : :
560 : 24352 : start_sequence ();
561 : 24352 : value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
562 : : from, from_mode);
563 : 24352 : insns = end_sequence ();
564 : 24352 : emit_libcall_block (insns, to, value,
565 : 7423 : tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
566 : : from)
567 : 16929 : : gen_rtx_FLOAT_EXTEND (to_mode, from));
568 : 24352 : return;
569 : : }
570 : :
571 : : /* Handle pointer conversion. */ /* SPEE 900220. */
572 : : /* If the target has a converter from FROM_MODE to TO_MODE, use it. */
573 : 1774950 : {
574 : 1774950 : convert_optab ctab;
575 : :
576 : 1774950 : if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
577 : : ctab = trunc_optab;
578 : 1578465 : else if (unsignedp)
579 : : ctab = zext_optab;
580 : : else
581 : 831098 : ctab = sext_optab;
582 : :
583 : 1774950 : if (convert_optab_handler (ctab, to_mode, from_mode)
584 : : != CODE_FOR_nothing)
585 : : {
586 : 1572914 : emit_unop_insn (convert_optab_handler (ctab, to_mode, from_mode),
587 : : to, from, UNKNOWN);
588 : 1572914 : return;
589 : : }
590 : : }
591 : :
592 : : /* Targets are expected to provide conversion insns between PxImode and
593 : : xImode for all MODE_PARTIAL_INT modes they use, but no others. */
594 : 202036 : if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
595 : : {
596 : 0 : scalar_int_mode full_mode
597 : 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (to_mode)).require ();
598 : :
599 : 0 : gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
600 : : != CODE_FOR_nothing);
601 : :
602 : 0 : if (full_mode != from_mode)
603 : 0 : from = convert_to_mode (full_mode, from, unsignedp);
604 : 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, full_mode),
605 : : to, from, UNKNOWN);
606 : 0 : return;
607 : : }
608 : 202036 : if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
609 : : {
610 : 0 : rtx new_from;
611 : 0 : scalar_int_mode full_mode
612 : 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (from_mode)).require ();
613 : 0 : convert_optab ctab = unsignedp ? zext_optab : sext_optab;
614 : 0 : enum insn_code icode;
615 : :
616 : 0 : icode = convert_optab_handler (ctab, full_mode, from_mode);
617 : 0 : gcc_assert (icode != CODE_FOR_nothing);
618 : :
619 : 0 : if (to_mode == full_mode)
620 : : {
621 : 0 : emit_unop_insn (icode, to, from, UNKNOWN);
622 : 0 : return;
623 : : }
624 : :
625 : 0 : new_from = gen_reg_rtx (full_mode);
626 : 0 : emit_unop_insn (icode, new_from, from, UNKNOWN);
627 : :
628 : : /* else proceed to integer conversions below. */
629 : 0 : from_mode = full_mode;
630 : 0 : from = new_from;
631 : : }
632 : :
633 : : /* Make sure both are fixed-point modes or both are not. */
634 : 202036 : gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
635 : : ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
636 : 202036 : if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
637 : : {
638 : : /* If we widen from_mode to to_mode and they are in the same class,
639 : : we won't saturate the result.
640 : : Otherwise, always saturate the result to play safe. */
641 : 0 : if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
642 : 0 : && GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
643 : 0 : expand_fixed_convert (to, from, 0, 0);
644 : : else
645 : 0 : expand_fixed_convert (to, from, 0, 1);
646 : 0 : return;
647 : : }
648 : :
649 : : /* Now both modes are integers. */
650 : :
651 : : /* Handle expanding beyond a word. */
652 : 202036 : if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)
653 : 204919 : && GET_MODE_PRECISION (to_mode) > BITS_PER_WORD)
654 : : {
655 : 5551 : rtx_insn *insns;
656 : 5551 : rtx lowpart;
657 : 5551 : rtx fill_value;
658 : 5551 : rtx lowfrom;
659 : 5551 : int i;
660 : 5551 : scalar_mode lowpart_mode;
661 : 11102 : int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
662 : :
663 : : /* Try converting directly if the insn is supported. */
664 : 5551 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
665 : : != CODE_FOR_nothing)
666 : : {
667 : : /* If FROM is a SUBREG, put it into a register. Do this
668 : : so that we always generate the same set of insns for
669 : : better cse'ing; if an intermediate assignment occurred,
670 : : we won't be doing the operation directly on the SUBREG. */
671 : 0 : if (optimize > 0 && GET_CODE (from) == SUBREG)
672 : 0 : from = force_reg (from_mode, from);
673 : 0 : emit_unop_insn (code, to, from, equiv_code);
674 : 0 : return;
675 : : }
676 : : /* Next, try converting via full word. */
677 : 5551 : else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD
678 : 5551 : && ((code = can_extend_p (to_mode, word_mode, unsignedp))
679 : : != CODE_FOR_nothing))
680 : : {
681 : 5551 : rtx word_to = gen_reg_rtx (word_mode);
682 : 5551 : if (REG_P (to))
683 : : {
684 : 5479 : if (reg_overlap_mentioned_p (to, from))
685 : 0 : from = force_reg (from_mode, from);
686 : 5479 : emit_clobber (to);
687 : : }
688 : 5551 : convert_move (word_to, from, unsignedp);
689 : 5551 : emit_unop_insn (code, to, word_to, equiv_code);
690 : 5551 : return;
691 : : }
692 : :
693 : : /* No special multiword conversion insn; do it by hand. */
694 : 0 : start_sequence ();
695 : :
696 : : /* Since we will turn this into a no conflict block, we must ensure
697 : : the source does not overlap the target so force it into an isolated
698 : : register when maybe so. Likewise for any MEM input, since the
699 : : conversion sequence might require several references to it and we
700 : : must ensure we're getting the same value every time. */
701 : :
702 : 0 : if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
703 : 0 : from = force_reg (from_mode, from);
704 : :
705 : : /* Get a copy of FROM widened to a word, if necessary. */
706 : 0 : if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD)
707 : 0 : lowpart_mode = word_mode;
708 : : else
709 : : lowpart_mode = from_mode;
710 : :
711 : 0 : lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
712 : :
713 : 0 : lowpart = gen_lowpart (lowpart_mode, to);
714 : 0 : emit_move_insn (lowpart, lowfrom);
715 : :
716 : : /* Compute the value to put in each remaining word. */
717 : 0 : if (unsignedp)
718 : 0 : fill_value = const0_rtx;
719 : : else
720 : 0 : fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
721 : : LT, lowfrom, const0_rtx,
722 : : lowpart_mode, 0, -1);
723 : :
724 : : /* Fill the remaining words. */
725 : 0 : for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
726 : : {
727 : 0 : int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
728 : 0 : rtx subword = operand_subword (to, index, 1, to_mode);
729 : :
730 : 0 : gcc_assert (subword);
731 : :
732 : 0 : if (fill_value != subword)
733 : 0 : emit_move_insn (subword, fill_value);
734 : : }
735 : :
736 : 0 : insns = end_sequence ();
737 : :
738 : 0 : emit_insn (insns);
739 : 0 : return;
740 : : }
741 : :
742 : : /* Truncating multi-word to a word or less. */
743 : 196485 : if (GET_MODE_PRECISION (from_mode) > BITS_PER_WORD
744 : 196485 : && GET_MODE_PRECISION (to_mode) <= BITS_PER_WORD)
745 : : {
746 : 71736 : if (!((MEM_P (from)
747 : 536 : && ! MEM_VOLATILE_P (from)
748 : 536 : && direct_load[(int) to_mode]
749 : 536 : && ! mode_dependent_address_p (XEXP (from, 0),
750 : 536 : MEM_ADDR_SPACE (from)))
751 : 40502 : || REG_P (from)
752 : : || GET_CODE (from) == SUBREG))
753 : 0 : from = force_reg (from_mode, from);
754 : 41038 : convert_move (to, gen_lowpart (word_mode, from), 0);
755 : 41038 : return;
756 : : }
757 : :
758 : : /* Now follow all the conversions between integers
759 : : no more than a word long. */
760 : :
761 : : /* For truncation, usually we can just refer to FROM in a narrower mode. */
762 : 310894 : if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
763 : 155447 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
764 : : {
765 : 167689 : if (!((MEM_P (from)
766 : 13399 : && ! MEM_VOLATILE_P (from)
767 : 13340 : && direct_load[(int) to_mode]
768 : 13340 : && ! mode_dependent_address_p (XEXP (from, 0),
769 : 13340 : MEM_ADDR_SPACE (from)))
770 : 142107 : || REG_P (from)
771 : : || GET_CODE (from) == SUBREG))
772 : 917 : from = force_reg (from_mode, from);
773 : 130782 : if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
774 : 155448 : && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
775 : 0 : from = copy_to_reg (from);
776 : 155447 : emit_move_insn (to, gen_lowpart (to_mode, from));
777 : 155447 : return;
778 : : }
779 : :
780 : : /* Handle extension. */
781 : 0 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode))
782 : : {
783 : : /* Convert directly if that works. */
784 : 0 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
785 : : != CODE_FOR_nothing)
786 : : {
787 : 0 : emit_unop_insn (code, to, from, equiv_code);
788 : 0 : return;
789 : : }
790 : : else
791 : : {
792 : 0 : rtx tmp;
793 : 0 : int shift_amount;
794 : :
795 : : /* Search for a mode to convert via. */
796 : 0 : opt_scalar_mode intermediate_iter;
797 : 0 : FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
798 : : {
799 : 0 : scalar_mode intermediate = intermediate_iter.require ();
800 : 0 : if (((can_extend_p (to_mode, intermediate, unsignedp)
801 : : != CODE_FOR_nothing)
802 : 0 : || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
803 : 0 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
804 : : intermediate)))
805 : 0 : && (can_extend_p (intermediate, from_mode, unsignedp)
806 : : != CODE_FOR_nothing))
807 : : {
808 : 0 : convert_move (to, convert_to_mode (intermediate, from,
809 : : unsignedp), unsignedp);
810 : 0 : return;
811 : : }
812 : : }
813 : :
814 : : /* No suitable intermediate mode.
815 : : Generate what we need with shifts. */
816 : 0 : shift_amount = (GET_MODE_PRECISION (to_mode)
817 : 0 : - GET_MODE_PRECISION (from_mode));
818 : 0 : from = gen_lowpart (to_mode, force_reg (from_mode, from));
819 : 0 : tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
820 : : to, unsignedp);
821 : 0 : tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
822 : : to, unsignedp);
823 : 0 : if (tmp != to)
824 : 0 : emit_move_insn (to, tmp);
825 : 0 : return;
826 : : }
827 : : }
828 : :
829 : : /* Support special truncate insns for certain modes. */
830 : 0 : if (convert_optab_handler (trunc_optab, to_mode,
831 : : from_mode) != CODE_FOR_nothing)
832 : : {
833 : 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, from_mode),
834 : : to, from, UNKNOWN);
835 : 0 : return;
836 : : }
837 : :
838 : : /* Handle truncation of volatile memrefs, and so on;
839 : : the things that couldn't be truncated directly,
840 : : and for which there was no special instruction.
841 : :
842 : : ??? Code above formerly short-circuited this, for most integer
843 : : mode pairs, with a force_reg in from_mode followed by a recursive
844 : : call to this routine. Appears always to have been wrong. */
845 : 0 : if (GET_MODE_PRECISION (to_mode) < GET_MODE_PRECISION (from_mode))
846 : : {
847 : 0 : rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
848 : 0 : emit_move_insn (to, temp);
849 : 0 : return;
850 : : }
851 : :
852 : : /* Mode combination is not recognized. */
853 : 0 : gcc_unreachable ();
854 : : }
855 : :
856 : : /* Return an rtx for a value that would result
857 : : from converting X to mode MODE.
858 : : Both X and MODE may be floating, or both integer.
859 : : UNSIGNEDP is nonzero if X is an unsigned value.
860 : : This can be done by referring to a part of X in place
861 : : or by copying to a new temporary with conversion. */
862 : :
863 : : rtx
864 : 1826284 : convert_to_mode (machine_mode mode, rtx x, int unsignedp)
865 : : {
866 : 1826284 : return convert_modes (mode, VOIDmode, x, unsignedp);
867 : : }
868 : :
869 : : /* Return an rtx for a value that would result
870 : : from converting X from mode OLDMODE to mode MODE.
871 : : Both modes may be floating, or both integer.
872 : : UNSIGNEDP is nonzero if X is an unsigned value.
873 : :
874 : : This can be done by referring to a part of X in place
875 : : or by copying to a new temporary with conversion.
876 : :
877 : : You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode. */
878 : :
879 : : rtx
880 : 4704370 : convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
881 : : {
882 : 4704370 : rtx temp;
883 : 4704370 : scalar_int_mode int_mode;
884 : :
885 : : /* If FROM is a SUBREG that indicates that we have already done at least
886 : : the required extension, strip it. */
887 : :
888 : 4704370 : if (GET_CODE (x) == SUBREG
889 : 75533 : && SUBREG_PROMOTED_VAR_P (x)
890 : 4704370 : && is_a <scalar_int_mode> (mode, &int_mode)
891 : 4704370 : && (GET_MODE_PRECISION (subreg_promoted_mode (x))
892 : 3 : >= GET_MODE_PRECISION (int_mode))
893 : 4704373 : && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
894 : : {
895 : 3 : scalar_int_mode int_orig_mode;
896 : 3 : scalar_int_mode int_inner_mode;
897 : 3 : machine_mode orig_mode = GET_MODE (x);
898 : 3 : x = gen_lowpart (int_mode, SUBREG_REG (x));
899 : :
900 : : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
901 : : the original mode, but narrower than the inner mode. */
902 : 3 : if (GET_CODE (x) == SUBREG
903 : 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
904 : 0 : && GET_MODE_PRECISION (int_mode)
905 : 0 : > GET_MODE_PRECISION (int_orig_mode)
906 : 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
907 : : &int_inner_mode)
908 : 3 : && GET_MODE_PRECISION (int_inner_mode)
909 : 0 : > GET_MODE_PRECISION (int_mode))
910 : : {
911 : 0 : SUBREG_PROMOTED_VAR_P (x) = 1;
912 : 0 : SUBREG_PROMOTED_SET (x, unsignedp);
913 : : }
914 : : }
915 : :
916 : 4704370 : if (GET_MODE (x) != VOIDmode)
917 : 2400454 : oldmode = GET_MODE (x);
918 : :
919 : 4704370 : if (mode == oldmode)
920 : : return x;
921 : :
922 : 3689639 : if (CONST_SCALAR_INT_P (x)
923 : 3689639 : && is_a <scalar_int_mode> (mode, &int_mode))
924 : : {
925 : : /* If the caller did not tell us the old mode, then there is not
926 : : much to do with respect to canonicalization. We have to
927 : : assume that all the bits are significant. */
928 : 1981758 : if (!is_a <scalar_int_mode> (oldmode))
929 : 1661473 : oldmode = MAX_MODE_INT;
930 : 1981758 : wide_int w = wide_int::from (rtx_mode_t (x, oldmode),
931 : 1981758 : GET_MODE_PRECISION (int_mode),
932 : 2863959 : unsignedp ? UNSIGNED : SIGNED);
933 : 1981758 : return immed_wide_int_const (w, int_mode);
934 : 1981758 : }
935 : :
936 : : /* We can do this with a gen_lowpart if both desired and current modes
937 : : are integer, and this is either a constant integer, a register, or a
938 : : non-volatile MEM. */
939 : 1707881 : scalar_int_mode int_oldmode;
940 : 1707881 : if (is_int_mode (mode, &int_mode)
941 : 1615611 : && is_int_mode (oldmode, &int_oldmode)
942 : 1615611 : && GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (int_oldmode)
943 : 475356 : && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
944 : 11172 : || CONST_POLY_INT_P (x)
945 : 464184 : || (REG_P (x)
946 : 426875 : && (!HARD_REGISTER_P (x)
947 : 979 : || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
948 : 426875 : && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
949 : 438047 : return gen_lowpart (int_mode, x);
950 : :
951 : : /* Converting from integer constant into mode is always equivalent to an
952 : : subreg operation. */
953 : 1269834 : if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
954 : : {
955 : 0 : gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
956 : : GET_MODE_BITSIZE (oldmode)));
957 : 0 : return force_subreg (mode, x, oldmode, 0);
958 : : }
959 : :
960 : 1269834 : temp = gen_reg_rtx (mode);
961 : 1269834 : convert_move (temp, x, unsignedp);
962 : 1269834 : return temp;
963 : : }
964 : :
965 : : /* Variant of convert_modes for ABI parameter passing/return.
966 : : Return an rtx for a value that would result from converting X from
967 : : a floating point mode FMODE to wider integer mode MODE. */
968 : :
969 : : rtx
970 : 0 : convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
971 : : {
972 : 0 : gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
973 : 0 : scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
974 : 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
975 : 0 : return convert_modes (mode, tmp_mode, tmp, 1);
976 : : }
977 : :
978 : : /* Variant of convert_modes for ABI parameter passing/return.
979 : : Return an rtx for a value that would result from converting X from
980 : : an integer mode IMODE to a narrower floating point mode MODE. */
981 : :
982 : : rtx
983 : 0 : convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
984 : : {
985 : 0 : gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
986 : 0 : scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
987 : 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
988 : 0 : return gen_lowpart_SUBREG (mode, tmp);
989 : : }
990 : :
991 : : /* Return the largest alignment we can use for doing a move (or store)
992 : : of MAX_PIECES. ALIGN is the largest alignment we could use. */
993 : :
994 : : static unsigned int
995 : 2641548 : alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
996 : : {
997 : 2641548 : scalar_int_mode tmode
998 : 2641548 : = int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
999 : :
1000 : 2641548 : if (align >= GET_MODE_ALIGNMENT (tmode))
1001 : 2061255 : align = GET_MODE_ALIGNMENT (tmode);
1002 : : else
1003 : : {
1004 : 580293 : scalar_int_mode xmode = NARROWEST_INT_MODE;
1005 : 580293 : opt_scalar_int_mode mode_iter;
1006 : 3490682 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
1007 : : {
1008 : 3486511 : tmode = mode_iter.require ();
1009 : 3486511 : if (GET_MODE_SIZE (tmode) > max_pieces
1010 : 3486511 : || targetm.slow_unaligned_access (tmode, align))
1011 : : break;
1012 : 2910389 : xmode = tmode;
1013 : : }
1014 : :
1015 : 580293 : align = MAX (align, GET_MODE_ALIGNMENT (xmode));
1016 : : }
1017 : :
1018 : 2641548 : return align;
1019 : : }
1020 : :
1021 : : /* Return true if we know how to implement OP using vectors of bytes. */
1022 : : static bool
1023 : 5635711 : can_use_qi_vectors (by_pieces_operation op)
1024 : : {
1025 : 5635711 : return (op == COMPARE_BY_PIECES
1026 : 0 : || op == SET_BY_PIECES
1027 : 0 : || op == CLEAR_BY_PIECES);
1028 : : }
1029 : :
1030 : : /* Return true if optabs exists for the mode and certain by pieces
1031 : : operations. */
1032 : : static bool
1033 : 24925868 : by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
1034 : : {
1035 : 24925868 : if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
1036 : : return false;
1037 : :
1038 : 24025490 : if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
1039 : 517754 : && VECTOR_MODE_P (mode)
1040 : 24380249 : && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
1041 : : return false;
1042 : :
1043 : 23982474 : if (op == COMPARE_BY_PIECES
1044 : 23982474 : && !can_compare_p (EQ, mode, ccp_jump))
1045 : : return false;
1046 : :
1047 : : return true;
1048 : : }
1049 : :
1050 : : /* Return the widest mode that can be used to perform part of an
1051 : : operation OP on SIZE bytes. Try to use QI vector modes where
1052 : : possible. */
1053 : : static fixed_size_mode
1054 : 5128850 : widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
1055 : : {
1056 : 5128850 : fixed_size_mode result = NARROWEST_INT_MODE;
1057 : :
1058 : 5128850 : gcc_checking_assert (size > 1);
1059 : :
1060 : : /* Use QI vector only if size is wider than a WORD. */
1061 : 5128850 : if (can_use_qi_vectors (op))
1062 : : {
1063 : 492060 : machine_mode mode;
1064 : 492060 : fixed_size_mode candidate;
1065 : 7933122 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1066 : 7933122 : if (is_a<fixed_size_mode> (mode, &candidate)
1067 : 8947918 : && GET_MODE_SIZE (candidate) > UNITS_PER_WORD
1068 : 8498788 : && GET_MODE_INNER (candidate) == QImode)
1069 : : {
1070 : 3755964 : if (GET_MODE_SIZE (candidate) >= size)
1071 : : break;
1072 : 1385922 : if (by_pieces_mode_supported_p (candidate, op))
1073 : 7441062 : result = candidate;
1074 : : }
1075 : :
1076 : 492060 : if (result != NARROWEST_INT_MODE)
1077 : 299907 : return result;
1078 : : }
1079 : :
1080 : 4828943 : opt_scalar_int_mode tmode;
1081 : 4828943 : scalar_int_mode mode;
1082 : 38631544 : FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
1083 : : {
1084 : 33802601 : mode = tmode.require ();
1085 : 33802601 : if (GET_MODE_SIZE (mode) < size
1086 : 33802601 : && by_pieces_mode_supported_p (mode, op))
1087 : 23503048 : result = mode;
1088 : : }
1089 : :
1090 : 4828943 : return result;
1091 : : }
1092 : :
1093 : : /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
1094 : : and should be performed piecewise. */
1095 : :
1096 : : static bool
1097 : 958383 : can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
1098 : : enum by_pieces_operation op)
1099 : : {
1100 : 958383 : return targetm.use_by_pieces_infrastructure_p (len, align, op,
1101 : 958383 : optimize_insn_for_speed_p ());
1102 : : }
1103 : :
1104 : : /* Determine whether the LEN bytes can be moved by using several move
1105 : : instructions. Return nonzero if a call to move_by_pieces should
1106 : : succeed. */
1107 : :
1108 : : bool
1109 : 921007 : can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
1110 : : {
1111 : 921007 : return can_do_by_pieces (len, align, MOVE_BY_PIECES);
1112 : : }
1113 : :
1114 : : /* Return number of insns required to perform operation OP by pieces
1115 : : for L bytes. ALIGN (in bits) is maximum alignment we can assume. */
1116 : :
1117 : : unsigned HOST_WIDE_INT
1118 : 1867878 : by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
1119 : : unsigned int max_size, by_pieces_operation op)
1120 : : {
1121 : 1867878 : unsigned HOST_WIDE_INT n_insns = 0;
1122 : 1867878 : fixed_size_mode mode;
1123 : :
1124 : 1867878 : if (targetm.overlap_op_by_pieces_p ())
1125 : : {
1126 : : /* NB: Round up L and ALIGN to the widest integer mode for
1127 : : MAX_SIZE. */
1128 : 1867878 : mode = widest_fixed_size_mode_for_size (max_size, op);
1129 : 1867878 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1130 : 3735756 : unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
1131 : 1867878 : if (up > l)
1132 : : l = up;
1133 : 1867878 : align = GET_MODE_ALIGNMENT (mode);
1134 : : }
1135 : :
1136 : 1867878 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1137 : :
1138 : 5614793 : while (max_size > 1 && l > 0)
1139 : : {
1140 : 1879037 : mode = widest_fixed_size_mode_for_size (max_size, op);
1141 : 1879037 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1142 : :
1143 : 1879037 : unsigned int modesize = GET_MODE_SIZE (mode);
1144 : :
1145 : 1879037 : if (align >= GET_MODE_ALIGNMENT (mode))
1146 : : {
1147 : 1879037 : unsigned HOST_WIDE_INT n_pieces = l / modesize;
1148 : 1879037 : l %= modesize;
1149 : 1879037 : switch (op)
1150 : : {
1151 : 1841661 : default:
1152 : 1841661 : n_insns += n_pieces;
1153 : 1841661 : break;
1154 : :
1155 : 37376 : case COMPARE_BY_PIECES:
1156 : 37376 : int batch = targetm.compare_by_pieces_branch_ratio (mode);
1157 : 37376 : int batch_ops = 4 * batch - 1;
1158 : 37376 : unsigned HOST_WIDE_INT full = n_pieces / batch;
1159 : 37376 : n_insns += full * batch_ops;
1160 : 37376 : if (n_pieces % batch != 0)
1161 : 0 : n_insns++;
1162 : : break;
1163 : :
1164 : : }
1165 : : }
1166 : : max_size = modesize;
1167 : : }
1168 : :
1169 : 1867878 : gcc_assert (!l);
1170 : 1867878 : return n_insns;
1171 : : }
1172 : :
1173 : : /* Used when performing piecewise block operations, holds information
1174 : : about one of the memory objects involved. The member functions
1175 : : can be used to generate code for loading from the object and
1176 : : updating the address when iterating. */
1177 : :
1178 : : class pieces_addr
1179 : : {
1180 : : /* The object being referenced, a MEM. Can be NULL_RTX to indicate
1181 : : stack pushes. */
1182 : : rtx m_obj;
1183 : : /* The address of the object. Can differ from that seen in the
1184 : : MEM rtx if we copied the address to a register. */
1185 : : rtx m_addr;
1186 : : /* Nonzero if the address on the object has an autoincrement already,
1187 : : signifies whether that was an increment or decrement. */
1188 : : signed char m_addr_inc;
1189 : : /* Nonzero if we intend to use autoinc without the address already
1190 : : having autoinc form. We will insert add insns around each memory
1191 : : reference, expecting later passes to form autoinc addressing modes.
1192 : : The only supported options are predecrement and postincrement. */
1193 : : signed char m_explicit_inc;
1194 : : /* True if we have either of the two possible cases of using
1195 : : autoincrement. */
1196 : : bool m_auto;
1197 : : /* True if this is an address to be used for load operations rather
1198 : : than stores. */
1199 : : bool m_is_load;
1200 : :
1201 : : /* Optionally, a function to obtain constants for any given offset into
1202 : : the objects, and data associated with it. */
1203 : : by_pieces_constfn m_constfn;
1204 : : void *m_cfndata;
1205 : : public:
1206 : : pieces_addr (rtx, bool, by_pieces_constfn, void *);
1207 : : rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
1208 : : void increment_address (HOST_WIDE_INT);
1209 : : void maybe_predec (HOST_WIDE_INT);
1210 : : void maybe_postinc (HOST_WIDE_INT);
1211 : : void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
1212 : 722990 : int get_addr_inc ()
1213 : : {
1214 : 722990 : return m_addr_inc;
1215 : : }
1216 : : };
1217 : :
1218 : : /* Initialize a pieces_addr structure from an object OBJ. IS_LOAD is
1219 : : true if the operation to be performed on this object is a load
1220 : : rather than a store. For stores, OBJ can be NULL, in which case we
1221 : : assume the operation is a stack push. For loads, the optional
1222 : : CONSTFN and its associated CFNDATA can be used in place of the
1223 : : memory load. */
1224 : :
1225 : 1445980 : pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
1226 : 1445980 : void *cfndata)
1227 : 1445980 : : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
1228 : : {
1229 : 1445980 : m_addr_inc = 0;
1230 : 1445980 : m_auto = false;
1231 : 1445980 : if (obj)
1232 : : {
1233 : 1345748 : rtx addr = XEXP (obj, 0);
1234 : 1345748 : rtx_code code = GET_CODE (addr);
1235 : 1345748 : m_addr = addr;
1236 : 1345748 : bool dec = code == PRE_DEC || code == POST_DEC;
1237 : 1345748 : bool inc = code == PRE_INC || code == POST_INC;
1238 : 1345748 : m_auto = inc || dec;
1239 : 1345748 : if (m_auto)
1240 : 0 : m_addr_inc = dec ? -1 : 1;
1241 : :
1242 : : /* While we have always looked for these codes here, the code
1243 : : implementing the memory operation has never handled them.
1244 : : Support could be added later if necessary or beneficial. */
1245 : 1345748 : gcc_assert (code != PRE_INC && code != POST_DEC);
1246 : : }
1247 : : else
1248 : : {
1249 : 100232 : m_addr = NULL_RTX;
1250 : 100232 : if (!is_load)
1251 : : {
1252 : 45 : m_auto = true;
1253 : 45 : if (STACK_GROWS_DOWNWARD)
1254 : 45 : m_addr_inc = -1;
1255 : : else
1256 : : m_addr_inc = 1;
1257 : : }
1258 : : else
1259 : 100187 : gcc_assert (constfn != NULL);
1260 : : }
1261 : 1445980 : m_explicit_inc = 0;
1262 : 1445980 : if (constfn)
1263 : 122451 : gcc_assert (is_load);
1264 : 1445980 : }
1265 : :
1266 : : /* Decide whether to use autoinc for an address involved in a memory op.
1267 : : MODE is the mode of the accesses, REVERSE is true if we've decided to
1268 : : perform the operation starting from the end, and LEN is the length of
1269 : : the operation. Don't override an earlier decision to set m_auto. */
1270 : :
1271 : : void
1272 : 374034 : pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
1273 : : HOST_WIDE_INT len)
1274 : : {
1275 : 374034 : if (m_auto || m_obj == NULL_RTX)
1276 : : return;
1277 : :
1278 : 349347 : bool use_predec = (m_is_load
1279 : : ? USE_LOAD_PRE_DECREMENT (mode)
1280 : : : USE_STORE_PRE_DECREMENT (mode));
1281 : 349347 : bool use_postinc = (m_is_load
1282 : : ? USE_LOAD_POST_INCREMENT (mode)
1283 : : : USE_STORE_POST_INCREMENT (mode));
1284 : 349347 : machine_mode addr_mode = get_address_mode (m_obj);
1285 : :
1286 : 349347 : if (use_predec && reverse)
1287 : : {
1288 : : m_addr = copy_to_mode_reg (addr_mode,
1289 : : plus_constant (addr_mode,
1290 : : m_addr, len));
1291 : : m_auto = true;
1292 : : m_explicit_inc = -1;
1293 : : }
1294 : 349347 : else if (use_postinc && !reverse)
1295 : : {
1296 : : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1297 : : m_auto = true;
1298 : : m_explicit_inc = 1;
1299 : : }
1300 : 349347 : else if (CONSTANT_P (m_addr))
1301 : 70542 : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1302 : : }
1303 : :
1304 : : /* Adjust the address to refer to the data at OFFSET in MODE. If we
1305 : : are using autoincrement for this address, we don't add the offset,
1306 : : but we still modify the MEM's properties. */
1307 : :
1308 : : rtx
1309 : 4030655 : pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
1310 : : by_pieces_prev *prev)
1311 : : {
1312 : 4030655 : if (m_constfn)
1313 : : /* Pass the previous data to m_constfn. */
1314 : 290007 : return m_constfn (m_cfndata, prev, offset, mode);
1315 : 3740648 : if (m_obj == NULL_RTX)
1316 : : return NULL_RTX;
1317 : 3740601 : if (m_auto)
1318 : 0 : return adjust_automodify_address (m_obj, mode, m_addr, offset);
1319 : : else
1320 : 3740601 : return adjust_address (m_obj, mode, offset);
1321 : : }
1322 : :
1323 : : /* Emit an add instruction to increment the address by SIZE. */
1324 : :
1325 : : void
1326 : 0 : pieces_addr::increment_address (HOST_WIDE_INT size)
1327 : : {
1328 : 0 : rtx amount = gen_int_mode (size, GET_MODE (m_addr));
1329 : 0 : emit_insn (gen_add2_insn (m_addr, amount));
1330 : 0 : }
1331 : :
1332 : : /* If we are supposed to decrement the address after each access, emit code
1333 : : to do so now. Increment by SIZE (which has should have the correct sign
1334 : : already). */
1335 : :
1336 : : void
1337 : 4030182 : pieces_addr::maybe_predec (HOST_WIDE_INT size)
1338 : : {
1339 : 4030182 : if (m_explicit_inc >= 0)
1340 : 4030182 : return;
1341 : 0 : gcc_assert (HAVE_PRE_DECREMENT);
1342 : : increment_address (size);
1343 : : }
1344 : :
1345 : : /* If we are supposed to decrement the address after each access, emit code
1346 : : to do so now. Increment by SIZE. */
1347 : :
1348 : : void
1349 : 4030205 : pieces_addr::maybe_postinc (HOST_WIDE_INT size)
1350 : : {
1351 : 4030205 : if (m_explicit_inc <= 0)
1352 : 4030205 : return;
1353 : 0 : gcc_assert (HAVE_POST_INCREMENT);
1354 : : increment_address (size);
1355 : : }
1356 : :
1357 : : /* This structure is used by do_op_by_pieces to describe the operation
1358 : : to be performed. */
1359 : :
1360 : : class op_by_pieces_d
1361 : : {
1362 : : private:
1363 : : fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
1364 : : fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
1365 : :
1366 : : protected:
1367 : : pieces_addr m_to, m_from;
1368 : : /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
1369 : : use it to check the valid mode size. */
1370 : : const unsigned HOST_WIDE_INT m_len;
1371 : : HOST_WIDE_INT m_offset;
1372 : : unsigned int m_align;
1373 : : unsigned int m_max_size;
1374 : : bool m_reverse;
1375 : : /* True if this is a stack push. */
1376 : : bool m_push;
1377 : : /* True if targetm.overlap_op_by_pieces_p () returns true. */
1378 : : bool m_overlap_op_by_pieces;
1379 : : /* The type of operation that we're performing. */
1380 : : by_pieces_operation m_op;
1381 : :
1382 : : /* Virtual functions, overriden by derived classes for the specific
1383 : : operation. */
1384 : : virtual void generate (rtx, rtx, machine_mode) = 0;
1385 : : virtual bool prepare_mode (machine_mode, unsigned int) = 0;
1386 : 1168408 : virtual void finish_mode (machine_mode)
1387 : : {
1388 : 1168408 : }
1389 : :
1390 : : public:
1391 : : op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
1392 : : void *, unsigned HOST_WIDE_INT, unsigned int, bool,
1393 : : by_pieces_operation);
1394 : : void run ();
1395 : : };
1396 : :
1397 : : /* The constructor for an op_by_pieces_d structure. We require two
1398 : : objects named TO and FROM, which are identified as loads or stores
1399 : : by TO_LOAD and FROM_LOAD. If FROM is a load, the optional FROM_CFN
1400 : : and its associated FROM_CFN_DATA can be used to replace loads with
1401 : : constant values. MAX_PIECES describes the maximum number of bytes
1402 : : at a time which can be moved efficiently. LEN describes the length
1403 : : of the operation. */
1404 : :
1405 : 722990 : op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
1406 : : bool to_load, rtx from, bool from_load,
1407 : : by_pieces_constfn from_cfn,
1408 : : void *from_cfn_data,
1409 : : unsigned HOST_WIDE_INT len,
1410 : : unsigned int align, bool push,
1411 : 722990 : by_pieces_operation op)
1412 : 722990 : : m_to (to, to_load, NULL, NULL),
1413 : 722990 : m_from (from, from_load, from_cfn, from_cfn_data),
1414 : 722990 : m_len (len), m_max_size (max_pieces + 1),
1415 : 722990 : m_push (push), m_op (op)
1416 : : {
1417 : 722990 : int toi = m_to.get_addr_inc ();
1418 : 722990 : int fromi = m_from.get_addr_inc ();
1419 : 722990 : if (toi >= 0 && fromi >= 0)
1420 : 722945 : m_reverse = false;
1421 : 45 : else if (toi <= 0 && fromi <= 0)
1422 : 45 : m_reverse = true;
1423 : : else
1424 : 0 : gcc_unreachable ();
1425 : :
1426 : 722990 : m_offset = m_reverse ? len : 0;
1427 : 2691541 : align = MIN (to ? MEM_ALIGN (to) : align,
1428 : : from ? MEM_ALIGN (from) : align);
1429 : :
1430 : : /* If copying requires more than two move insns,
1431 : : copy addresses to registers (to make displacements shorter)
1432 : : and use post-increment if available. */
1433 : 722990 : if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
1434 : : {
1435 : : /* Find the mode of the largest comparison. */
1436 : 187017 : fixed_size_mode mode
1437 : 187017 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1438 : :
1439 : 187017 : m_from.decide_autoinc (mode, m_reverse, len);
1440 : 187017 : m_to.decide_autoinc (mode, m_reverse, len);
1441 : : }
1442 : :
1443 : 722990 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1444 : 722990 : m_align = align;
1445 : :
1446 : 722990 : m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
1447 : 722990 : }
1448 : :
1449 : : /* This function returns the largest usable integer mode for LEN bytes
1450 : : whose size is no bigger than size of MODE. */
1451 : :
1452 : : fixed_size_mode
1453 : 1229851 : op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
1454 : : {
1455 : 1511558 : unsigned int size;
1456 : 1793265 : do
1457 : : {
1458 : 1511558 : size = GET_MODE_SIZE (mode);
1459 : 1511558 : if (len >= size && prepare_mode (mode, m_align))
1460 : : break;
1461 : : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1462 : 281707 : mode = widest_fixed_size_mode_for_size (size, m_op);
1463 : : }
1464 : : while (1);
1465 : 1229851 : return mode;
1466 : : }
1467 : :
1468 : : /* Return the smallest integer or QI vector mode that is not narrower
1469 : : than SIZE bytes. */
1470 : :
1471 : : fixed_size_mode
1472 : 506861 : op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
1473 : : {
1474 : : /* Use QI vector only for > size of WORD. */
1475 : 518149 : if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
1476 : : {
1477 : 6634 : machine_mode mode;
1478 : 6634 : fixed_size_mode candidate;
1479 : 90482 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1480 : 90482 : if (is_a<fixed_size_mode> (mode, &candidate)
1481 : 180964 : && GET_MODE_INNER (candidate) == QImode)
1482 : : {
1483 : : /* Don't return a mode wider than M_LEN. */
1484 : 83700 : if (GET_MODE_SIZE (candidate) > m_len)
1485 : : break;
1486 : :
1487 : 40209 : if (GET_MODE_SIZE (candidate) >= size
1488 : 40209 : && by_pieces_mode_supported_p (candidate, m_op))
1489 : 4993 : return candidate;
1490 : : }
1491 : : }
1492 : :
1493 : 501868 : return smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
1494 : : }
1495 : :
1496 : : /* This function contains the main loop used for expanding a block
1497 : : operation. First move what we can in the largest integer mode,
1498 : : then go to successively smaller modes. For every access, call
1499 : : GENFUN with the two operands and the EXTRA_DATA. */
1500 : :
1501 : : void
1502 : 722990 : op_by_pieces_d::run ()
1503 : : {
1504 : 722990 : if (m_len == 0)
1505 : : return;
1506 : :
1507 : 722990 : unsigned HOST_WIDE_INT length = m_len;
1508 : :
1509 : : /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1. */
1510 : 722990 : fixed_size_mode mode
1511 : 722990 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1512 : 722990 : mode = get_usable_mode (mode, length);
1513 : :
1514 : 722990 : by_pieces_prev to_prev = { nullptr, mode };
1515 : 722990 : by_pieces_prev from_prev = { nullptr, mode };
1516 : :
1517 : 1229851 : do
1518 : : {
1519 : 1229851 : unsigned int size = GET_MODE_SIZE (mode);
1520 : 1229851 : rtx to1 = NULL_RTX, from1;
1521 : :
1522 : 3244942 : while (length >= size)
1523 : : {
1524 : 2015091 : if (m_reverse)
1525 : 47 : m_offset -= size;
1526 : :
1527 : 2015091 : to1 = m_to.adjust (mode, m_offset, &to_prev);
1528 : 2015091 : to_prev.data = to1;
1529 : 2015091 : to_prev.mode = mode;
1530 : 2015091 : from1 = m_from.adjust (mode, m_offset, &from_prev);
1531 : 2015091 : from_prev.data = from1;
1532 : 2015091 : from_prev.mode = mode;
1533 : :
1534 : 2015091 : m_to.maybe_predec (-(HOST_WIDE_INT)size);
1535 : 2015091 : m_from.maybe_predec (-(HOST_WIDE_INT)size);
1536 : :
1537 : 2015091 : generate (to1, from1, mode);
1538 : :
1539 : 2015091 : m_to.maybe_postinc (size);
1540 : 2015091 : m_from.maybe_postinc (size);
1541 : :
1542 : 2015091 : if (!m_reverse)
1543 : 2015044 : m_offset += size;
1544 : :
1545 : 2015091 : length -= size;
1546 : : }
1547 : :
1548 : 1229851 : finish_mode (mode);
1549 : :
1550 : 1229851 : if (length == 0)
1551 : : return;
1552 : :
1553 : 506861 : if (!m_push && m_overlap_op_by_pieces)
1554 : : {
1555 : : /* NB: Generate overlapping operations if it is not a stack
1556 : : push since stack push must not overlap. Get the smallest
1557 : : fixed size mode for M_LEN bytes. */
1558 : 506861 : mode = smallest_fixed_size_mode_for_size (length);
1559 : 1013722 : mode = get_usable_mode (mode, GET_MODE_SIZE (mode));
1560 : 506861 : int gap = GET_MODE_SIZE (mode) - length;
1561 : 506861 : if (gap > 0)
1562 : : {
1563 : : /* If size of MODE > M_LEN, generate the last operation
1564 : : in MODE for the remaining bytes with ovelapping memory
1565 : : from the previois operation. */
1566 : 44529 : if (m_reverse)
1567 : 0 : m_offset += gap;
1568 : : else
1569 : 44529 : m_offset -= gap;
1570 : 44529 : length += gap;
1571 : : }
1572 : : }
1573 : : else
1574 : : {
1575 : : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1576 : 0 : mode = widest_fixed_size_mode_for_size (size, m_op);
1577 : 0 : mode = get_usable_mode (mode, length);
1578 : : }
1579 : : }
1580 : : while (1);
1581 : : }
1582 : :
1583 : : /* Derived class from op_by_pieces_d, providing support for block move
1584 : : operations. */
1585 : :
1586 : : #ifdef PUSH_ROUNDING
1587 : : #define PUSHG_P(to) ((to) == nullptr)
1588 : : #else
1589 : : #define PUSHG_P(to) false
1590 : : #endif
1591 : :
1592 : : class move_by_pieces_d : public op_by_pieces_d
1593 : : {
1594 : : insn_gen_fn m_gen_fun;
1595 : : void generate (rtx, rtx, machine_mode) final override;
1596 : : bool prepare_mode (machine_mode, unsigned int) final override;
1597 : :
1598 : : public:
1599 : 588558 : move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1600 : : unsigned int align)
1601 : 588558 : : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
1602 : 1177116 : NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
1603 : : {
1604 : 588558 : }
1605 : : rtx finish_retmode (memop_ret);
1606 : : };
1607 : :
1608 : : /* Return true if MODE can be used for a set of copies, given an
1609 : : alignment ALIGN. Prepare whatever data is necessary for later
1610 : : calls to generate. */
1611 : :
1612 : : bool
1613 : 999052 : move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1614 : : {
1615 : 999052 : insn_code icode = optab_handler (mov_optab, mode);
1616 : 999052 : m_gen_fun = GEN_FCN (icode);
1617 : 999052 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1618 : : }
1619 : :
1620 : : /* A callback used when iterating for a compare_by_pieces_operation.
1621 : : OP0 and OP1 are the values that have been loaded and should be
1622 : : compared in MODE. If OP0 is NULL, this means we should generate a
1623 : : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1624 : : gen function that should be used to generate the mode. */
1625 : :
1626 : : void
1627 : 1705340 : move_by_pieces_d::generate (rtx op0, rtx op1,
1628 : : machine_mode mode ATTRIBUTE_UNUSED)
1629 : : {
1630 : : #ifdef PUSH_ROUNDING
1631 : 1705340 : if (op0 == NULL_RTX)
1632 : : {
1633 : 47 : emit_single_push_insn (mode, op1, NULL);
1634 : 47 : return;
1635 : : }
1636 : : #endif
1637 : 1705293 : emit_insn (m_gen_fun (op0, op1));
1638 : : }
1639 : :
1640 : : /* Perform the final adjustment at the end of a string to obtain the
1641 : : correct return value for the block operation.
1642 : : Return value is based on RETMODE argument. */
1643 : :
1644 : : rtx
1645 : 0 : move_by_pieces_d::finish_retmode (memop_ret retmode)
1646 : : {
1647 : 0 : gcc_assert (!m_reverse);
1648 : 0 : if (retmode == RETURN_END_MINUS_ONE)
1649 : : {
1650 : 0 : m_to.maybe_postinc (-1);
1651 : 0 : --m_offset;
1652 : : }
1653 : 0 : return m_to.adjust (QImode, m_offset);
1654 : : }
1655 : :
1656 : : /* Generate several move instructions to copy LEN bytes from block FROM to
1657 : : block TO. (These are MEM rtx's with BLKmode).
1658 : :
1659 : : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1660 : : used to push FROM to the stack.
1661 : :
1662 : : ALIGN is maximum stack alignment we can assume.
1663 : :
1664 : : Return value is based on RETMODE argument. */
1665 : :
1666 : : rtx
1667 : 588558 : move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1668 : : unsigned int align, memop_ret retmode)
1669 : : {
1670 : : #ifndef PUSH_ROUNDING
1671 : : if (to == NULL)
1672 : : gcc_unreachable ();
1673 : : #endif
1674 : :
1675 : 588558 : move_by_pieces_d data (to, from, len, align);
1676 : :
1677 : 588558 : data.run ();
1678 : :
1679 : 588558 : if (retmode != RETURN_BEGIN)
1680 : 0 : return data.finish_retmode (retmode);
1681 : : else
1682 : : return to;
1683 : : }
1684 : :
1685 : : /* Derived class from op_by_pieces_d, providing support for block move
1686 : : operations. */
1687 : :
1688 : : class store_by_pieces_d : public op_by_pieces_d
1689 : : {
1690 : : insn_gen_fn m_gen_fun;
1691 : :
1692 : : void generate (rtx, rtx, machine_mode) final override;
1693 : : bool prepare_mode (machine_mode, unsigned int) final override;
1694 : :
1695 : : public:
1696 : 100187 : store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
1697 : : unsigned HOST_WIDE_INT len, unsigned int align,
1698 : : by_pieces_operation op)
1699 : 100187 : : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
1700 : 200374 : cfn_data, len, align, false, op)
1701 : : {
1702 : 100187 : }
1703 : : rtx finish_retmode (memop_ret);
1704 : : };
1705 : :
1706 : : /* Return true if MODE can be used for a set of stores, given an
1707 : : alignment ALIGN. Prepare whatever data is necessary for later
1708 : : calls to generate. */
1709 : :
1710 : : bool
1711 : 169356 : store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1712 : : {
1713 : 169356 : insn_code icode = optab_handler (mov_optab, mode);
1714 : 169356 : m_gen_fun = GEN_FCN (icode);
1715 : 169356 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1716 : : }
1717 : :
1718 : : /* A callback used when iterating for a store_by_pieces_operation.
1719 : : OP0 and OP1 are the values that have been loaded and should be
1720 : : compared in MODE. If OP0 is NULL, this means we should generate a
1721 : : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1722 : : gen function that should be used to generate the mode. */
1723 : :
1724 : : void
1725 : 245418 : store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
1726 : : {
1727 : 245418 : emit_insn (m_gen_fun (op0, op1));
1728 : 245418 : }
1729 : :
1730 : : /* Perform the final adjustment at the end of a string to obtain the
1731 : : correct return value for the block operation.
1732 : : Return value is based on RETMODE argument. */
1733 : :
1734 : : rtx
1735 : 473 : store_by_pieces_d::finish_retmode (memop_ret retmode)
1736 : : {
1737 : 473 : gcc_assert (!m_reverse);
1738 : 473 : if (retmode == RETURN_END_MINUS_ONE)
1739 : : {
1740 : 23 : m_to.maybe_postinc (-1);
1741 : 23 : --m_offset;
1742 : : }
1743 : 473 : return m_to.adjust (QImode, m_offset);
1744 : : }
1745 : :
1746 : : /* Determine whether the LEN bytes generated by CONSTFUN can be
1747 : : stored to memory using several move instructions. CONSTFUNDATA is
1748 : : a pointer which will be passed as argument in every CONSTFUN call.
1749 : : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1750 : : a memset operation and false if it's a copy of a constant string.
1751 : : Return true if a call to store_by_pieces should succeed. */
1752 : :
1753 : : bool
1754 : 66762 : can_store_by_pieces (unsigned HOST_WIDE_INT len,
1755 : : by_pieces_constfn constfun,
1756 : : void *constfundata, unsigned int align, bool memsetp)
1757 : : {
1758 : 66762 : unsigned HOST_WIDE_INT l;
1759 : 66762 : unsigned int max_size;
1760 : 66762 : HOST_WIDE_INT offset = 0;
1761 : 66762 : enum insn_code icode;
1762 : 66762 : int reverse;
1763 : : /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */
1764 : 66762 : rtx cst ATTRIBUTE_UNUSED;
1765 : :
1766 : 66762 : if (len == 0)
1767 : : return true;
1768 : :
1769 : 111638 : if (!targetm.use_by_pieces_infrastructure_p (len, align,
1770 : : memsetp
1771 : : ? SET_BY_PIECES
1772 : : : STORE_BY_PIECES,
1773 : 66718 : optimize_insn_for_speed_p ()))
1774 : : return false;
1775 : :
1776 : 50680 : align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
1777 : :
1778 : : /* We would first store what we can in the largest integer mode, then go to
1779 : : successively smaller modes. */
1780 : :
1781 : 50680 : for (reverse = 0;
1782 : 101360 : reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
1783 : : reverse++)
1784 : : {
1785 : 50680 : l = len;
1786 : 50680 : max_size = STORE_MAX_PIECES + 1;
1787 : 240901 : while (max_size > 1 && l > 0)
1788 : : {
1789 : 190221 : auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
1790 : 190221 : auto mode = widest_fixed_size_mode_for_size (max_size, op);
1791 : :
1792 : 190221 : icode = optab_handler (mov_optab, mode);
1793 : 190221 : if (icode != CODE_FOR_nothing
1794 : 190221 : && align >= GET_MODE_ALIGNMENT (mode))
1795 : : {
1796 : 190221 : unsigned int size = GET_MODE_SIZE (mode);
1797 : :
1798 : 329211 : while (l >= size)
1799 : : {
1800 : 138990 : if (reverse)
1801 : : offset -= size;
1802 : :
1803 : 138990 : cst = (*constfun) (constfundata, nullptr, offset, mode);
1804 : : /* All CONST_VECTORs can be loaded for memset since
1805 : : vec_duplicate_optab is a precondition to pick a
1806 : : vector mode for the memset expander. */
1807 : 265612 : if (!((memsetp && VECTOR_MODE_P (mode))
1808 : 126622 : || targetm.legitimate_constant_p (mode, cst)))
1809 : 16038 : return false;
1810 : :
1811 : 138990 : if (!reverse)
1812 : 138990 : offset += size;
1813 : :
1814 : 138990 : l -= size;
1815 : : }
1816 : : }
1817 : :
1818 : 380442 : max_size = GET_MODE_SIZE (mode);
1819 : : }
1820 : :
1821 : : /* The code above should have handled everything. */
1822 : 50680 : gcc_assert (!l);
1823 : : }
1824 : :
1825 : : return true;
1826 : : }
1827 : :
1828 : : /* Generate several move instructions to store LEN bytes generated by
1829 : : CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
1830 : : pointer which will be passed as argument in every CONSTFUN call.
1831 : : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1832 : : a memset operation and false if it's a copy of a constant string.
1833 : : Return value is based on RETMODE argument. */
1834 : :
1835 : : rtx
1836 : 48194 : store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
1837 : : by_pieces_constfn constfun,
1838 : : void *constfundata, unsigned int align, bool memsetp,
1839 : : memop_ret retmode)
1840 : : {
1841 : 48194 : if (len == 0)
1842 : : {
1843 : 43 : gcc_assert (retmode != RETURN_END_MINUS_ONE);
1844 : : return to;
1845 : : }
1846 : :
1847 : 89272 : gcc_assert (targetm.use_by_pieces_infrastructure_p
1848 : : (len, align,
1849 : : memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
1850 : : optimize_insn_for_speed_p ()));
1851 : :
1852 : 48151 : store_by_pieces_d data (to, constfun, constfundata, len, align,
1853 : 48151 : memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
1854 : 48151 : data.run ();
1855 : :
1856 : 48151 : if (retmode != RETURN_BEGIN)
1857 : 473 : return data.finish_retmode (retmode);
1858 : : else
1859 : : return to;
1860 : : }
1861 : :
1862 : : void
1863 : 52036 : clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
1864 : : {
1865 : 52036 : if (len == 0)
1866 : 0 : return;
1867 : :
1868 : : /* Use builtin_memset_read_str to support vector mode broadcast. */
1869 : 52036 : char c = 0;
1870 : 52036 : store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
1871 : 52036 : CLEAR_BY_PIECES);
1872 : 52036 : data.run ();
1873 : : }
1874 : :
1875 : : /* Context used by compare_by_pieces_genfn. It stores the fail label
1876 : : to jump to in case of miscomparison, and for branch ratios greater than 1,
1877 : : it stores an accumulator and the current and maximum counts before
1878 : : emitting another branch. */
1879 : :
1880 : : class compare_by_pieces_d : public op_by_pieces_d
1881 : : {
1882 : : rtx_code_label *m_fail_label;
1883 : : rtx m_accumulator;
1884 : : int m_count, m_batch;
1885 : :
1886 : : void generate (rtx, rtx, machine_mode) final override;
1887 : : bool prepare_mode (machine_mode, unsigned int) final override;
1888 : : void finish_mode (machine_mode) final override;
1889 : :
1890 : : public:
1891 : 34245 : compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
1892 : : void *op1_cfn_data, HOST_WIDE_INT len, int align,
1893 : : rtx_code_label *fail_label)
1894 : 34245 : : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
1895 : 68490 : op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
1896 : : {
1897 : 34245 : m_fail_label = fail_label;
1898 : 34245 : }
1899 : : };
1900 : :
1901 : : /* A callback used when iterating for a compare_by_pieces_operation.
1902 : : OP0 and OP1 are the values that have been loaded and should be
1903 : : compared in MODE. DATA holds a pointer to the compare_by_pieces_data
1904 : : context structure. */
1905 : :
1906 : : void
1907 : 64333 : compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
1908 : : {
1909 : 64333 : if (m_batch > 1)
1910 : : {
1911 : 0 : rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
1912 : : true, OPTAB_LIB_WIDEN);
1913 : 0 : if (m_count != 0)
1914 : 0 : temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
1915 : : true, OPTAB_LIB_WIDEN);
1916 : 0 : m_accumulator = temp;
1917 : :
1918 : 0 : if (++m_count < m_batch)
1919 : : return;
1920 : :
1921 : 0 : m_count = 0;
1922 : 0 : op0 = m_accumulator;
1923 : 0 : op1 = const0_rtx;
1924 : 0 : m_accumulator = NULL_RTX;
1925 : : }
1926 : 64333 : do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
1927 : : m_fail_label, profile_probability::uninitialized ());
1928 : : }
1929 : :
1930 : : /* Return true if MODE can be used for a set of moves and comparisons,
1931 : : given an alignment ALIGN. Prepare whatever data is necessary for
1932 : : later calls to generate. */
1933 : :
1934 : : bool
1935 : 61443 : compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1936 : : {
1937 : 61443 : insn_code icode = optab_handler (mov_optab, mode);
1938 : 61443 : if (icode == CODE_FOR_nothing
1939 : 61443 : || align < GET_MODE_ALIGNMENT (mode)
1940 : 122886 : || !can_compare_p (EQ, mode, ccp_jump))
1941 : 0 : return false;
1942 : 61443 : m_batch = targetm.compare_by_pieces_branch_ratio (mode);
1943 : 61443 : if (m_batch < 0)
1944 : : return false;
1945 : 61443 : m_accumulator = NULL_RTX;
1946 : 61443 : m_count = 0;
1947 : 61443 : return true;
1948 : : }
1949 : :
1950 : : /* Called after expanding a series of comparisons in MODE. If we have
1951 : : accumulated results for which we haven't emitted a branch yet, do
1952 : : so now. */
1953 : :
1954 : : void
1955 : 61443 : compare_by_pieces_d::finish_mode (machine_mode mode)
1956 : : {
1957 : 61443 : if (m_accumulator != NULL_RTX)
1958 : 0 : do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
1959 : : NULL_RTX, NULL, m_fail_label,
1960 : : profile_probability::uninitialized ());
1961 : 61443 : }
1962 : :
1963 : : /* Generate several move instructions to compare LEN bytes from blocks
1964 : : ARG0 and ARG1. (These are MEM rtx's with BLKmode).
1965 : :
1966 : : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1967 : : used to push FROM to the stack.
1968 : :
1969 : : ALIGN is maximum stack alignment we can assume.
1970 : :
1971 : : Optionally, the caller can pass a constfn and associated data in A1_CFN
1972 : : and A1_CFN_DATA. describing that the second operand being compared is a
1973 : : known constant and how to obtain its data. */
1974 : :
1975 : : static rtx
1976 : 34245 : compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
1977 : : rtx target, unsigned int align,
1978 : : by_pieces_constfn a1_cfn, void *a1_cfn_data)
1979 : : {
1980 : 34245 : rtx_code_label *fail_label = gen_label_rtx ();
1981 : 34245 : rtx_code_label *end_label = gen_label_rtx ();
1982 : :
1983 : 34245 : if (target == NULL_RTX
1984 : 34245 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
1985 : 1 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
1986 : :
1987 : 34245 : compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
1988 : 34245 : fail_label);
1989 : :
1990 : 34245 : data.run ();
1991 : :
1992 : 34245 : emit_move_insn (target, const0_rtx);
1993 : 34245 : emit_jump (end_label);
1994 : 34245 : emit_barrier ();
1995 : 34245 : emit_label (fail_label);
1996 : 34245 : emit_move_insn (target, const1_rtx);
1997 : 34245 : emit_label (end_label);
1998 : :
1999 : 34245 : return target;
2000 : : }
2001 : :
2002 : : /* Emit code to move a block Y to a block X. This may be done with
2003 : : string-move instructions, with multiple scalar move instructions,
2004 : : or with a library call.
2005 : :
2006 : : Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
2007 : : SIZE is an rtx that says how long they are.
2008 : : ALIGN is the maximum alignment we can assume they have.
2009 : : METHOD describes what kind of copy this is, and what mechanisms may be used.
2010 : : MIN_SIZE is the minimal size of block to move
2011 : : MAX_SIZE is the maximal size of block to move, if it cannot be represented
2012 : : in unsigned HOST_WIDE_INT, than it is mask of all ones.
2013 : : CTZ_SIZE is the trailing-zeros count of SIZE; even a nonconstant SIZE is
2014 : : known to be a multiple of 1<<CTZ_SIZE.
2015 : :
2016 : : Return the address of the new block, if memcpy is called and returns it,
2017 : : 0 otherwise. */
2018 : :
2019 : : rtx
2020 : 678394 : emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
2021 : : unsigned int expected_align, HOST_WIDE_INT expected_size,
2022 : : unsigned HOST_WIDE_INT min_size,
2023 : : unsigned HOST_WIDE_INT max_size,
2024 : : unsigned HOST_WIDE_INT probable_max_size,
2025 : : bool bail_out_libcall, bool *is_move_done,
2026 : : bool might_overlap, unsigned ctz_size)
2027 : : {
2028 : 678394 : int may_use_call;
2029 : 678394 : rtx retval = 0;
2030 : 678394 : unsigned int align;
2031 : :
2032 : 678394 : if (is_move_done)
2033 : 80495 : *is_move_done = true;
2034 : :
2035 : 678394 : gcc_assert (size);
2036 : 678394 : if (CONST_INT_P (size) && INTVAL (size) == 0)
2037 : : return 0;
2038 : :
2039 : 678117 : switch (method)
2040 : : {
2041 : : case BLOCK_OP_NORMAL:
2042 : : case BLOCK_OP_TAILCALL:
2043 : : may_use_call = 1;
2044 : : break;
2045 : :
2046 : 266694 : case BLOCK_OP_CALL_PARM:
2047 : 266694 : may_use_call = block_move_libcall_safe_for_call_parm ();
2048 : :
2049 : : /* Make inhibit_defer_pop nonzero around the library call
2050 : : to force it to pop the arguments right away. */
2051 : 266694 : NO_DEFER_POP;
2052 : 266694 : break;
2053 : :
2054 : 353 : case BLOCK_OP_NO_LIBCALL:
2055 : 353 : may_use_call = 0;
2056 : 353 : break;
2057 : :
2058 : 1061 : case BLOCK_OP_NO_LIBCALL_RET:
2059 : 1061 : may_use_call = -1;
2060 : 1061 : break;
2061 : :
2062 : 0 : default:
2063 : 0 : gcc_unreachable ();
2064 : : }
2065 : :
2066 : 678117 : gcc_assert (MEM_P (x) && MEM_P (y));
2067 : 678200 : align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2068 : 678117 : gcc_assert (align >= BITS_PER_UNIT);
2069 : :
2070 : : /* Make sure we've got BLKmode addresses; store_one_arg can decide that
2071 : : block copy is more efficient for other large modes, e.g. DCmode. */
2072 : 678117 : x = adjust_address (x, BLKmode, 0);
2073 : 678117 : y = adjust_address (y, BLKmode, 0);
2074 : :
2075 : : /* If source and destination are the same, no need to copy anything. */
2076 : 678117 : if (rtx_equal_p (x, y)
2077 : 10 : && !MEM_VOLATILE_P (x)
2078 : 678127 : && !MEM_VOLATILE_P (y))
2079 : : return 0;
2080 : :
2081 : : /* Set MEM_SIZE as appropriate for this block copy. The main place this
2082 : : can be incorrect is coming from __builtin_memcpy. */
2083 : 678107 : poly_int64 const_size;
2084 : 678107 : if (poly_int_rtx_p (size, &const_size))
2085 : : {
2086 : 613791 : x = shallow_copy_rtx (x);
2087 : 613791 : y = shallow_copy_rtx (y);
2088 : 613791 : set_mem_size (x, const_size);
2089 : 613791 : set_mem_size (y, const_size);
2090 : : }
2091 : :
2092 : 678107 : bool pieces_ok = CONST_INT_P (size)
2093 : 678107 : && can_move_by_pieces (INTVAL (size), align);
2094 : 678107 : bool pattern_ok = false;
2095 : :
2096 : 678107 : if (!pieces_ok || might_overlap)
2097 : : {
2098 : 89594 : pattern_ok
2099 : 89594 : = emit_block_move_via_pattern (x, y, size, align,
2100 : : expected_align, expected_size,
2101 : : min_size, max_size, probable_max_size,
2102 : : might_overlap);
2103 : 89594 : if (!pattern_ok && might_overlap)
2104 : : {
2105 : : /* Do not try any of the other methods below as they are not safe
2106 : : for overlapping moves. */
2107 : 15488 : *is_move_done = false;
2108 : 15488 : return retval;
2109 : : }
2110 : : }
2111 : :
2112 : 74106 : bool dynamic_direction = false;
2113 : 74106 : if (!pattern_ok && !pieces_ok && may_use_call
2114 : 78934 : && (flag_inline_stringops & (might_overlap ? ILSOP_MEMMOVE : ILSOP_MEMCPY)))
2115 : : {
2116 : 662619 : may_use_call = 0;
2117 : 662619 : dynamic_direction = might_overlap;
2118 : : }
2119 : :
2120 : 662619 : if (pattern_ok)
2121 : : ;
2122 : 627980 : else if (pieces_ok)
2123 : 588513 : move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
2124 : 39467 : else if (may_use_call && !might_overlap
2125 : 39419 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2126 : 78886 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
2127 : : {
2128 : 39419 : if (bail_out_libcall)
2129 : : {
2130 : 253 : if (is_move_done)
2131 : 253 : *is_move_done = false;
2132 : 253 : return retval;
2133 : : }
2134 : :
2135 : 39166 : if (may_use_call < 0)
2136 : 0 : return pc_rtx;
2137 : :
2138 : 39166 : retval = emit_block_copy_via_libcall (x, y, size,
2139 : : method == BLOCK_OP_TAILCALL);
2140 : : }
2141 : 48 : else if (dynamic_direction)
2142 : 0 : emit_block_move_via_oriented_loop (x, y, size, align, ctz_size);
2143 : 48 : else if (might_overlap)
2144 : 0 : *is_move_done = false;
2145 : : else
2146 : 48 : emit_block_move_via_sized_loop (x, y, size, align, ctz_size);
2147 : :
2148 : 662366 : if (method == BLOCK_OP_CALL_PARM)
2149 : 266686 : OK_DEFER_POP;
2150 : :
2151 : : return retval;
2152 : : }
2153 : :
2154 : : rtx
2155 : 597899 : emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method,
2156 : : unsigned int ctz_size)
2157 : : {
2158 : 597899 : unsigned HOST_WIDE_INT max, min = 0;
2159 : 597899 : if (GET_CODE (size) == CONST_INT)
2160 : 597679 : min = max = UINTVAL (size);
2161 : : else
2162 : 220 : max = GET_MODE_MASK (GET_MODE (size));
2163 : 597899 : return emit_block_move_hints (x, y, size, method, 0, -1,
2164 : : min, max, max,
2165 : 597899 : false, NULL, false, ctz_size);
2166 : : }
2167 : :
2168 : : /* A subroutine of emit_block_move. Returns true if calling the
2169 : : block move libcall will not clobber any parameters which may have
2170 : : already been placed on the stack. */
2171 : :
2172 : : static bool
2173 : 266694 : block_move_libcall_safe_for_call_parm (void)
2174 : : {
2175 : 266694 : tree fn;
2176 : :
2177 : : /* If arguments are pushed on the stack, then they're safe. */
2178 : 266694 : if (targetm.calls.push_argument (0))
2179 : : return true;
2180 : :
2181 : : /* If registers go on the stack anyway, any argument is sure to clobber
2182 : : an outgoing argument. */
2183 : : #if defined (REG_PARM_STACK_SPACE)
2184 : 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2185 : : /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
2186 : : depend on its argument. */
2187 : 3 : (void) fn;
2188 : 3 : if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
2189 : 3 : && REG_PARM_STACK_SPACE (fn) != 0)
2190 : : return false;
2191 : : #endif
2192 : :
2193 : : /* If any argument goes in memory, then it might clobber an outgoing
2194 : : argument. */
2195 : 3 : {
2196 : 3 : CUMULATIVE_ARGS args_so_far_v;
2197 : 3 : cumulative_args_t args_so_far;
2198 : 3 : tree arg;
2199 : :
2200 : 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2201 : 3 : INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
2202 : 3 : args_so_far = pack_cumulative_args (&args_so_far_v);
2203 : :
2204 : 3 : arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2205 : 12 : for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
2206 : : {
2207 : 9 : machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
2208 : 9 : function_arg_info arg_info (mode, /*named=*/true);
2209 : 9 : rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
2210 : 9 : if (!tmp || !REG_P (tmp))
2211 : 0 : return false;
2212 : 9 : if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
2213 : : return false;
2214 : 9 : targetm.calls.function_arg_advance (args_so_far, arg_info);
2215 : : }
2216 : : }
2217 : 3 : return true;
2218 : : }
2219 : :
2220 : : /* A subroutine of emit_block_move. Expand a cpymem or movmem pattern;
2221 : : return true if successful.
2222 : :
2223 : : X is the destination of the copy or move.
2224 : : Y is the source of the copy or move.
2225 : : SIZE is the size of the block to be moved.
2226 : :
2227 : : MIGHT_OVERLAP indicates this originated with expansion of a
2228 : : builtin_memmove() and the source and destination blocks may
2229 : : overlap.
2230 : : */
2231 : :
2232 : : static bool
2233 : 89594 : emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
2234 : : unsigned int expected_align,
2235 : : HOST_WIDE_INT expected_size,
2236 : : unsigned HOST_WIDE_INT min_size,
2237 : : unsigned HOST_WIDE_INT max_size,
2238 : : unsigned HOST_WIDE_INT probable_max_size,
2239 : : bool might_overlap)
2240 : : {
2241 : 89594 : if (expected_align < align)
2242 : : expected_align = align;
2243 : 89594 : if (expected_size != -1)
2244 : : {
2245 : 12 : if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
2246 : 0 : expected_size = probable_max_size;
2247 : 12 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
2248 : 0 : expected_size = min_size;
2249 : : }
2250 : :
2251 : : /* Since this is a move insn, we don't care about volatility. */
2252 : 89594 : temporary_volatile_ok v (true);
2253 : :
2254 : : /* Try the most limited insn first, because there's no point
2255 : : including more than one in the machine description unless
2256 : : the more limited one has some advantage. */
2257 : :
2258 : 89594 : opt_scalar_int_mode mode_iter;
2259 : 545639 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
2260 : : {
2261 : 490684 : scalar_int_mode mode = mode_iter.require ();
2262 : 490684 : enum insn_code code;
2263 : 490684 : if (might_overlap)
2264 : 108416 : code = direct_optab_handler (movmem_optab, mode);
2265 : : else
2266 : 382268 : code = direct_optab_handler (cpymem_optab, mode);
2267 : :
2268 : 490684 : if (code != CODE_FOR_nothing
2269 : : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
2270 : : here because if SIZE is less than the mode mask, as it is
2271 : : returned by the macro, it will definitely be less than the
2272 : : actual mode mask. Since SIZE is within the Pmode address
2273 : : space, we limit MODE to Pmode. */
2274 : 490684 : && ((CONST_INT_P (size)
2275 : 23738 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
2276 : 23738 : <= (GET_MODE_MASK (mode) >> 1)))
2277 : 90452 : || max_size <= (GET_MODE_MASK (mode) >> 1)
2278 : 117404 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
2279 : : {
2280 : 76006 : class expand_operand ops[9];
2281 : 76006 : unsigned int nops;
2282 : :
2283 : : /* ??? When called via emit_block_move_for_call, it'd be
2284 : : nice if there were some way to inform the backend, so
2285 : : that it doesn't fail the expansion because it thinks
2286 : : emitting the libcall would be more efficient. */
2287 : 76006 : nops = insn_data[(int) code].n_generator_args;
2288 : 76006 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
2289 : :
2290 : 76006 : create_fixed_operand (&ops[0], x);
2291 : 76006 : create_fixed_operand (&ops[1], y);
2292 : : /* The check above guarantees that this size conversion is valid. */
2293 : 76006 : create_convert_operand_to (&ops[2], size, mode, true);
2294 : 76006 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
2295 : 76006 : if (nops >= 6)
2296 : : {
2297 : 76006 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
2298 : 76006 : create_integer_operand (&ops[5], expected_size);
2299 : : }
2300 : 76006 : if (nops >= 8)
2301 : : {
2302 : 76006 : create_integer_operand (&ops[6], min_size);
2303 : : /* If we cannot represent the maximal size,
2304 : : make parameter NULL. */
2305 : 76006 : if ((HOST_WIDE_INT) max_size != -1)
2306 : 63257 : create_integer_operand (&ops[7], max_size);
2307 : : else
2308 : 12749 : create_fixed_operand (&ops[7], NULL);
2309 : : }
2310 : 76006 : if (nops == 9)
2311 : : {
2312 : : /* If we cannot represent the maximal size,
2313 : : make parameter NULL. */
2314 : 76006 : if ((HOST_WIDE_INT) probable_max_size != -1)
2315 : 64686 : create_integer_operand (&ops[8], probable_max_size);
2316 : : else
2317 : 11320 : create_fixed_operand (&ops[8], NULL);
2318 : : }
2319 : 76006 : if (maybe_expand_insn (code, nops, ops))
2320 : 34639 : return true;
2321 : : }
2322 : : }
2323 : :
2324 : : return false;
2325 : 89594 : }
2326 : :
2327 : : /* Like emit_block_move_via_loop, but choose a suitable INCR based on
2328 : : ALIGN and CTZ_SIZE. */
2329 : :
2330 : : static void
2331 : 48 : emit_block_move_via_sized_loop (rtx x, rtx y, rtx size,
2332 : : unsigned int align,
2333 : : unsigned int ctz_size)
2334 : : {
2335 : 48 : int incr = align / BITS_PER_UNIT;
2336 : :
2337 : 48 : if (CONST_INT_P (size))
2338 : 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2339 : :
2340 : 48 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2341 : 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2342 : :
2343 : 48 : while (incr > 1 && !can_move_by_pieces (incr, align))
2344 : 0 : incr >>= 1;
2345 : :
2346 : 48 : gcc_checking_assert (incr);
2347 : :
2348 : 48 : return emit_block_move_via_loop (x, y, size, align, incr);
2349 : : }
2350 : :
2351 : : /* Like emit_block_move_via_sized_loop, but besides choosing INCR so
2352 : : as to ensure safe moves even in case of overlap, output dynamic
2353 : : tests to choose between two loops, one moving downwards, another
2354 : : moving upwards. */
2355 : :
2356 : : static void
2357 : 0 : emit_block_move_via_oriented_loop (rtx x, rtx y, rtx size,
2358 : : unsigned int align,
2359 : : unsigned int ctz_size)
2360 : : {
2361 : 0 : int incr = align / BITS_PER_UNIT;
2362 : :
2363 : 0 : if (CONST_INT_P (size))
2364 : 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2365 : :
2366 : 0 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2367 : 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2368 : :
2369 : 0 : while (incr > 1 && !int_mode_for_size (incr, 0).exists ())
2370 : 0 : incr >>= 1;
2371 : :
2372 : 0 : gcc_checking_assert (incr);
2373 : :
2374 : 0 : rtx_code_label *upw_label, *end_label;
2375 : 0 : upw_label = gen_label_rtx ();
2376 : 0 : end_label = gen_label_rtx ();
2377 : :
2378 : 0 : rtx x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2379 : 0 : rtx y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2380 : 0 : do_pending_stack_adjust ();
2381 : :
2382 : 0 : machine_mode mode = GET_MODE (x_addr);
2383 : 0 : if (mode != GET_MODE (y_addr))
2384 : : {
2385 : 0 : scalar_int_mode xmode
2386 : 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (mode)).require ();
2387 : 0 : scalar_int_mode ymode
2388 : 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE
2389 : 0 : (GET_MODE (y_addr))).require ();
2390 : 0 : if (GET_MODE_BITSIZE (xmode) < GET_MODE_BITSIZE (ymode))
2391 : : mode = ymode;
2392 : : else
2393 : 0 : mode = xmode;
2394 : :
2395 : : #ifndef POINTERS_EXTEND_UNSIGNED
2396 : : const int POINTERS_EXTEND_UNSIGNED = 1;
2397 : : #endif
2398 : 0 : x_addr = convert_modes (mode, GET_MODE (x_addr), x_addr,
2399 : : POINTERS_EXTEND_UNSIGNED);
2400 : 0 : y_addr = convert_modes (mode, GET_MODE (y_addr), y_addr,
2401 : : POINTERS_EXTEND_UNSIGNED);
2402 : : }
2403 : :
2404 : : /* Test for overlap: if (x >= y || x + size <= y) goto upw_label. */
2405 : 0 : emit_cmp_and_jump_insns (x_addr, y_addr, GEU, NULL_RTX, mode,
2406 : : true, upw_label,
2407 : 0 : profile_probability::guessed_always ()
2408 : : .apply_scale (5, 10));
2409 : 0 : rtx tmp = convert_modes (GET_MODE (x_addr), GET_MODE (size), size, true);
2410 : 0 : tmp = simplify_gen_binary (PLUS, GET_MODE (x_addr), x_addr, tmp);
2411 : :
2412 : 0 : emit_cmp_and_jump_insns (tmp, y_addr, LEU, NULL_RTX, mode,
2413 : : true, upw_label,
2414 : 0 : profile_probability::guessed_always ()
2415 : : .apply_scale (8, 10));
2416 : :
2417 : 0 : emit_block_move_via_loop (x, y, size, align, -incr);
2418 : :
2419 : 0 : emit_jump (end_label);
2420 : 0 : emit_label (upw_label);
2421 : :
2422 : 0 : emit_block_move_via_loop (x, y, size, align, incr);
2423 : :
2424 : 0 : emit_label (end_label);
2425 : 0 : }
2426 : :
2427 : : /* A subroutine of emit_block_move. Copy the data via an explicit
2428 : : loop. This is used only when libcalls are forbidden, or when
2429 : : inlining is required. INCR is the block size to be copied in each
2430 : : loop iteration. If it is negative, the absolute value is used, and
2431 : : the block is copied backwards. INCR must be a power of two, an
2432 : : exact divisor for SIZE and ALIGN, and imply a mode that can be
2433 : : safely copied per iteration assuming no overlap. */
2434 : :
2435 : : static void
2436 : 48 : emit_block_move_via_loop (rtx x, rtx y, rtx size,
2437 : : unsigned int align, int incr)
2438 : : {
2439 : 48 : rtx_code_label *cmp_label, *top_label;
2440 : 48 : rtx iter, x_addr, y_addr, tmp;
2441 : 48 : machine_mode x_addr_mode = get_address_mode (x);
2442 : 48 : machine_mode y_addr_mode = get_address_mode (y);
2443 : 48 : machine_mode iter_mode;
2444 : :
2445 : 48 : iter_mode = GET_MODE (size);
2446 : 48 : if (iter_mode == VOIDmode)
2447 : 0 : iter_mode = word_mode;
2448 : :
2449 : 48 : top_label = gen_label_rtx ();
2450 : 48 : cmp_label = gen_label_rtx ();
2451 : 48 : iter = gen_reg_rtx (iter_mode);
2452 : :
2453 : 48 : bool downwards = incr < 0;
2454 : 48 : rtx iter_init;
2455 : 48 : rtx_code iter_cond;
2456 : 48 : rtx iter_limit;
2457 : 48 : rtx iter_incr;
2458 : 48 : machine_mode move_mode;
2459 : 48 : if (downwards)
2460 : : {
2461 : 0 : incr = -incr;
2462 : 0 : iter_init = size;
2463 : 0 : iter_cond = GEU;
2464 : 0 : iter_limit = const0_rtx;
2465 : 0 : iter_incr = GEN_INT (incr);
2466 : : }
2467 : : else
2468 : : {
2469 : 48 : iter_init = const0_rtx;
2470 : 48 : iter_cond = LTU;
2471 : 48 : iter_limit = size;
2472 : 48 : iter_incr = GEN_INT (incr);
2473 : : }
2474 : 48 : emit_move_insn (iter, iter_init);
2475 : :
2476 : 48 : opt_scalar_int_mode int_move_mode
2477 : 48 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2478 : 48 : if (!int_move_mode.exists (&move_mode)
2479 : 96 : || GET_MODE_BITSIZE (int_move_mode.require ()) != incr * BITS_PER_UNIT)
2480 : : {
2481 : 0 : move_mode = BLKmode;
2482 : 0 : gcc_checking_assert (can_move_by_pieces (incr, align));
2483 : : }
2484 : :
2485 : 48 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2486 : 48 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2487 : 48 : do_pending_stack_adjust ();
2488 : :
2489 : 48 : emit_jump (cmp_label);
2490 : 48 : emit_label (top_label);
2491 : :
2492 : 48 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2493 : 48 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2494 : :
2495 : 48 : if (x_addr_mode != y_addr_mode)
2496 : 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2497 : 48 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2498 : :
2499 : 48 : x = change_address (x, move_mode, x_addr);
2500 : 48 : y = change_address (y, move_mode, y_addr);
2501 : :
2502 : 48 : if (move_mode == BLKmode)
2503 : : {
2504 : 0 : bool done;
2505 : 0 : emit_block_move_hints (x, y, iter_incr, BLOCK_OP_NO_LIBCALL,
2506 : : align, incr, incr, incr, incr,
2507 : : false, &done, false);
2508 : 0 : gcc_checking_assert (done);
2509 : : }
2510 : : else
2511 : 48 : emit_move_insn (x, y);
2512 : :
2513 : 48 : if (downwards)
2514 : 0 : emit_label (cmp_label);
2515 : :
2516 : 48 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2517 : : true, OPTAB_LIB_WIDEN);
2518 : 48 : if (tmp != iter)
2519 : 0 : emit_move_insn (iter, tmp);
2520 : :
2521 : 48 : if (!downwards)
2522 : 48 : emit_label (cmp_label);
2523 : :
2524 : 48 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2525 : : true, top_label,
2526 : 48 : profile_probability::guessed_always ()
2527 : : .apply_scale (9, 10));
2528 : 48 : }
2529 : :
2530 : : /* Expand a call to memcpy or memmove or memcmp, and return the result.
2531 : : TAILCALL is true if this is a tail call. */
2532 : :
2533 : : rtx
2534 : 39169 : emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
2535 : : rtx size, bool tailcall)
2536 : : {
2537 : 39169 : rtx dst_addr, src_addr;
2538 : 39169 : tree call_expr, dst_tree, src_tree, size_tree;
2539 : 39169 : machine_mode size_mode;
2540 : :
2541 : : /* Since dst and src are passed to a libcall, mark the corresponding
2542 : : tree EXPR as addressable. */
2543 : 39169 : tree dst_expr = MEM_EXPR (dst);
2544 : 39169 : tree src_expr = MEM_EXPR (src);
2545 : 39169 : if (dst_expr)
2546 : 38864 : mark_addressable (dst_expr);
2547 : 39169 : if (src_expr)
2548 : 39127 : mark_addressable (src_expr);
2549 : :
2550 : 39169 : dst_addr = copy_addr_to_reg (XEXP (dst, 0));
2551 : 39169 : dst_addr = convert_memory_address (ptr_mode, dst_addr);
2552 : 39169 : dst_tree = make_tree (ptr_type_node, dst_addr);
2553 : :
2554 : 39169 : src_addr = copy_addr_to_reg (XEXP (src, 0));
2555 : 39169 : src_addr = convert_memory_address (ptr_mode, src_addr);
2556 : 39169 : src_tree = make_tree (ptr_type_node, src_addr);
2557 : :
2558 : 39169 : size_mode = TYPE_MODE (sizetype);
2559 : 39169 : size = convert_to_mode (size_mode, size, 1);
2560 : 39169 : size = copy_to_mode_reg (size_mode, size);
2561 : 39169 : size_tree = make_tree (sizetype, size);
2562 : :
2563 : : /* It is incorrect to use the libcall calling conventions for calls to
2564 : : memcpy/memmove/memcmp because they can be provided by the user. */
2565 : 39169 : tree fn = builtin_decl_implicit (fncode);
2566 : 39169 : call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
2567 : 39169 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
2568 : :
2569 : 39169 : return expand_call (call_expr, NULL_RTX, false);
2570 : : }
2571 : :
2572 : : /* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
2573 : : ARG3_TYPE is the type of ARG3_RTX. Return the result rtx on success,
2574 : : otherwise return null. */
2575 : :
2576 : : rtx
2577 : 205182 : expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
2578 : : rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
2579 : : HOST_WIDE_INT align)
2580 : : {
2581 : 205182 : machine_mode insn_mode = insn_data[icode].operand[0].mode;
2582 : :
2583 : 205182 : if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
2584 : : target = NULL_RTX;
2585 : :
2586 : 205182 : class expand_operand ops[5];
2587 : 205182 : create_output_operand (&ops[0], target, insn_mode);
2588 : 205182 : create_fixed_operand (&ops[1], arg1_rtx);
2589 : 205182 : create_fixed_operand (&ops[2], arg2_rtx);
2590 : 205182 : create_convert_operand_from (&ops[3], arg3_rtx, TYPE_MODE (arg3_type),
2591 : 205182 : TYPE_UNSIGNED (arg3_type));
2592 : 205182 : create_integer_operand (&ops[4], align);
2593 : 205182 : if (maybe_expand_insn (icode, 5, ops))
2594 : 5777 : return ops[0].value;
2595 : : return NULL_RTX;
2596 : : }
2597 : :
2598 : : /* Expand a block compare between X and Y with length LEN using the
2599 : : cmpmem optab, placing the result in TARGET. LEN_TYPE is the type
2600 : : of the expression that was used to calculate the length. ALIGN
2601 : : gives the known minimum common alignment. */
2602 : :
2603 : : static rtx
2604 : 77283 : emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
2605 : : unsigned align)
2606 : : {
2607 : : /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
2608 : : implementing memcmp because it will stop if it encounters two
2609 : : zero bytes. */
2610 : 77283 : insn_code icode = direct_optab_handler (cmpmem_optab, SImode);
2611 : :
2612 : 77283 : if (icode == CODE_FOR_nothing)
2613 : : return NULL_RTX;
2614 : :
2615 : 77283 : return expand_cmpstrn_or_cmpmem (icode, target, x, y, len_type, len, align);
2616 : : }
2617 : :
2618 : : /* Emit code to compare a block Y to a block X. This may be done with
2619 : : string-compare instructions, with multiple scalar instructions,
2620 : : or with a library call.
2621 : :
2622 : : Both X and Y must be MEM rtx's. LEN is an rtx that says how long
2623 : : they are. LEN_TYPE is the type of the expression that was used to
2624 : : calculate it, and CTZ_LEN is the known trailing-zeros count of LEN,
2625 : : so LEN must be a multiple of 1<<CTZ_LEN even if it's not constant.
2626 : :
2627 : : If EQUALITY_ONLY is true, it means we don't have to return the tri-state
2628 : : value of a normal memcmp call, instead we can just compare for equality.
2629 : : If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
2630 : : returning NULL_RTX.
2631 : :
2632 : : Optionally, the caller can pass a constfn and associated data in Y_CFN
2633 : : and Y_CFN_DATA. describing that the second operand being compared is a
2634 : : known constant and how to obtain its data.
2635 : : Return the result of the comparison, or NULL_RTX if we failed to
2636 : : perform the operation. */
2637 : :
2638 : : rtx
2639 : 111533 : emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
2640 : : bool equality_only, by_pieces_constfn y_cfn,
2641 : : void *y_cfndata, unsigned ctz_len)
2642 : : {
2643 : 111533 : rtx result = 0;
2644 : :
2645 : 111533 : if (CONST_INT_P (len) && INTVAL (len) == 0)
2646 : 6 : return const0_rtx;
2647 : :
2648 : 111527 : gcc_assert (MEM_P (x) && MEM_P (y));
2649 : 111527 : unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2650 : 111527 : gcc_assert (align >= BITS_PER_UNIT);
2651 : :
2652 : 111527 : x = adjust_address (x, BLKmode, 0);
2653 : 111527 : y = adjust_address (y, BLKmode, 0);
2654 : :
2655 : 111527 : if (equality_only
2656 : 58268 : && CONST_INT_P (len)
2657 : 148857 : && can_do_by_pieces (INTVAL (len), align, COMPARE_BY_PIECES))
2658 : 34244 : result = compare_by_pieces (x, y, INTVAL (len), target, align,
2659 : : y_cfn, y_cfndata);
2660 : : else
2661 : 77283 : result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
2662 : :
2663 : 111527 : if (!result && (flag_inline_stringops & ILSOP_MEMCMP))
2664 : 361 : result = emit_block_cmp_via_loop (x, y, len, len_type,
2665 : : target, equality_only,
2666 : : align, ctz_len);
2667 : :
2668 : : return result;
2669 : : }
2670 : :
2671 : : /* Like emit_block_cmp_hints, but with known alignment and no support
2672 : : for constats. Always expand to a loop with iterations that compare
2673 : : blocks of the largest compare-by-pieces size that divides both len
2674 : : and align, and then, if !EQUALITY_ONLY, identify the word and then
2675 : : the unit that first differs to return the result. */
2676 : :
2677 : : rtx
2678 : 403 : emit_block_cmp_via_loop (rtx x, rtx y, rtx len, tree len_type, rtx target,
2679 : : bool equality_only, unsigned align, unsigned ctz_len)
2680 : : {
2681 : 403 : unsigned incr = align / BITS_PER_UNIT;
2682 : :
2683 : 403 : if (CONST_INT_P (len))
2684 : 319 : ctz_len = MAX (ctz_len, (unsigned) wi::ctz (UINTVAL (len)));
2685 : :
2686 : 403 : if (HOST_WIDE_INT_1U << ctz_len < (unsigned HOST_WIDE_INT) incr)
2687 : 148 : incr = HOST_WIDE_INT_1U << ctz_len;
2688 : :
2689 : : while (incr > 1
2690 : 407 : && !can_do_by_pieces (incr, align, COMPARE_BY_PIECES))
2691 : 4 : incr >>= 1;
2692 : :
2693 : 403 : rtx_code_label *cmp_label, *top_label, *ne_label, *res_label;
2694 : 403 : rtx iter, x_addr, y_addr, tmp;
2695 : 403 : machine_mode x_addr_mode = get_address_mode (x);
2696 : 403 : machine_mode y_addr_mode = get_address_mode (y);
2697 : 403 : machine_mode iter_mode;
2698 : :
2699 : 403 : iter_mode = GET_MODE (len);
2700 : 403 : if (iter_mode == VOIDmode)
2701 : 319 : iter_mode = word_mode;
2702 : :
2703 : 403 : rtx iter_init = const0_rtx;
2704 : 403 : rtx_code iter_cond = LTU;
2705 : 403 : rtx_code entry_cond = GEU;
2706 : 403 : rtx iter_limit = len;
2707 : 403 : rtx iter_incr = GEN_INT (incr);
2708 : 403 : machine_mode cmp_mode;
2709 : :
2710 : : /* We can drop the loop back edge if we know there's exactly one
2711 : : iteration. */
2712 : 403 : top_label = (!rtx_equal_p (len, iter_incr)
2713 : 403 : ? gen_label_rtx ()
2714 : : : NULL);
2715 : : /* We need not test before entering the loop if len is known
2716 : : nonzero. ??? This could be even stricter, testing whether a
2717 : : nonconstant LEN could possibly be zero. */
2718 : 403 : cmp_label = (!CONSTANT_P (len) || rtx_equal_p (len, iter_init)
2719 : 403 : ? gen_label_rtx ()
2720 : : : NULL);
2721 : 403 : ne_label = gen_label_rtx ();
2722 : 403 : res_label = gen_label_rtx ();
2723 : :
2724 : 403 : iter = gen_reg_rtx (iter_mode);
2725 : 403 : emit_move_insn (iter, iter_init);
2726 : :
2727 : 403 : opt_scalar_int_mode int_cmp_mode
2728 : 403 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2729 : 403 : if (!int_cmp_mode.exists (&cmp_mode)
2730 : 1206 : || GET_MODE_BITSIZE (int_cmp_mode.require ()) != incr * BITS_PER_UNIT
2731 : 402 : || !can_compare_p (NE, cmp_mode, ccp_jump))
2732 : : {
2733 : 1 : cmp_mode = BLKmode;
2734 : 1 : gcc_checking_assert (incr != 1);
2735 : : }
2736 : :
2737 : : /* Save the base addresses. */
2738 : 403 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2739 : 403 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2740 : 403 : do_pending_stack_adjust ();
2741 : :
2742 : 403 : if (cmp_label)
2743 : : {
2744 : 84 : if (top_label)
2745 : 84 : emit_jump (cmp_label);
2746 : : else
2747 : 0 : emit_cmp_and_jump_insns (iter, iter_limit, entry_cond,
2748 : : NULL_RTX, iter_mode,
2749 : : true, cmp_label,
2750 : 0 : profile_probability::guessed_always ()
2751 : : .apply_scale (1, 10));
2752 : : }
2753 : 403 : if (top_label)
2754 : 386 : emit_label (top_label);
2755 : :
2756 : : /* Offset the base addresses by ITER. */
2757 : 403 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2758 : 403 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2759 : :
2760 : 403 : if (x_addr_mode != y_addr_mode)
2761 : 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2762 : 403 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2763 : :
2764 : 403 : x = change_address (x, cmp_mode, x_addr);
2765 : 403 : y = change_address (y, cmp_mode, y_addr);
2766 : :
2767 : : /* Compare one block. */
2768 : 403 : rtx part_res;
2769 : 403 : if (cmp_mode == BLKmode)
2770 : 1 : part_res = compare_by_pieces (x, y, incr, target, align, 0, 0);
2771 : : else
2772 : 402 : part_res = expand_binop (cmp_mode, sub_optab, x, y, NULL_RTX,
2773 : : true, OPTAB_LIB_WIDEN);
2774 : :
2775 : : /* Stop if we found a difference. */
2776 : 806 : emit_cmp_and_jump_insns (part_res, GEN_INT (0), NE, NULL_RTX,
2777 : 403 : GET_MODE (part_res), true, ne_label,
2778 : 403 : profile_probability::guessed_always ()
2779 : : .apply_scale (1, 10));
2780 : :
2781 : : /* Increment ITER. */
2782 : 403 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2783 : : true, OPTAB_LIB_WIDEN);
2784 : 403 : if (tmp != iter)
2785 : 0 : emit_move_insn (iter, tmp);
2786 : :
2787 : 403 : if (cmp_label)
2788 : 84 : emit_label (cmp_label);
2789 : : /* Loop until we reach the limit. */
2790 : :
2791 : 403 : if (top_label)
2792 : 386 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2793 : : true, top_label,
2794 : 772 : profile_probability::guessed_always ()
2795 : : .apply_scale (9, 10));
2796 : :
2797 : : /* We got to the end without differences, so the result is zero. */
2798 : 403 : if (target == NULL_RTX
2799 : 403 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
2800 : 49 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
2801 : :
2802 : 403 : emit_move_insn (target, const0_rtx);
2803 : 403 : emit_jump (res_label);
2804 : :
2805 : 403 : emit_label (ne_label);
2806 : :
2807 : : /* Return nonzero, or pinpoint the difference to return the expected
2808 : : result for non-equality tests. */
2809 : 403 : if (equality_only)
2810 : 0 : emit_move_insn (target, const1_rtx);
2811 : : else
2812 : : {
2813 : 403 : if (incr > UNITS_PER_WORD)
2814 : : /* ??? Re-compare the block found to be different one word at a
2815 : : time. */
2816 : 5 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2817 : : target, equality_only,
2818 : : BITS_PER_WORD, 0);
2819 : 398 : else if (incr > 1)
2820 : : /* ??? Re-compare the block found to be different one byte at a
2821 : : time. We could do better using part_res, and being careful
2822 : : about endianness. */
2823 : 37 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2824 : : target, equality_only,
2825 : : BITS_PER_UNIT, 0);
2826 : 1083 : else if (known_gt (GET_MODE_BITSIZE (GET_MODE (target)),
2827 : : GET_MODE_BITSIZE (cmp_mode)))
2828 : 361 : part_res = expand_binop (GET_MODE (target), sub_optab, x, y, target,
2829 : : true, OPTAB_LIB_WIDEN);
2830 : : else
2831 : : {
2832 : : /* In the odd chance target is QImode, we can't count on
2833 : : widening subtract to capture the result of the unsigned
2834 : : compares. */
2835 : 0 : rtx_code_label *ltu_label;
2836 : 0 : ltu_label = gen_label_rtx ();
2837 : 0 : emit_cmp_and_jump_insns (x, y, LTU, NULL_RTX,
2838 : : cmp_mode, true, ltu_label,
2839 : 0 : profile_probability::guessed_always ()
2840 : : .apply_scale (5, 10));
2841 : :
2842 : 0 : emit_move_insn (target, const1_rtx);
2843 : 0 : emit_jump (res_label);
2844 : :
2845 : 0 : emit_label (ltu_label);
2846 : 0 : emit_move_insn (target, constm1_rtx);
2847 : 0 : part_res = target;
2848 : : }
2849 : :
2850 : 403 : if (target != part_res)
2851 : 0 : convert_move (target, part_res, false);
2852 : : }
2853 : :
2854 : 403 : emit_label (res_label);
2855 : :
2856 : 403 : return target;
2857 : : }
2858 : :
2859 : :
2860 : : /* Copy all or part of a value X into registers starting at REGNO.
2861 : : The number of registers to be filled is NREGS. */
2862 : :
2863 : : void
2864 : 418 : move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
2865 : : {
2866 : 418 : if (nregs == 0)
2867 : : return;
2868 : :
2869 : 404 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
2870 : 0 : x = validize_mem (force_const_mem (mode, x));
2871 : :
2872 : : /* See if the machine can do this with a load multiple insn. */
2873 : 404 : if (targetm.have_load_multiple ())
2874 : : {
2875 : 0 : rtx_insn *last = get_last_insn ();
2876 : 0 : rtx first = gen_rtx_REG (word_mode, regno);
2877 : 0 : if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
2878 : : GEN_INT (nregs)))
2879 : : {
2880 : 0 : emit_insn (pat);
2881 : 0 : return;
2882 : : }
2883 : : else
2884 : 0 : delete_insns_since (last);
2885 : : }
2886 : :
2887 : 808 : for (int i = 0; i < nregs; i++)
2888 : 404 : emit_move_insn (gen_rtx_REG (word_mode, regno + i),
2889 : 404 : operand_subword_force (x, i, mode));
2890 : : }
2891 : :
2892 : : /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
2893 : : The number of registers to be filled is NREGS. */
2894 : :
2895 : : void
2896 : 1172 : move_block_from_reg (int regno, rtx x, int nregs)
2897 : : {
2898 : 1172 : if (nregs == 0)
2899 : : return;
2900 : :
2901 : : /* See if the machine can do this with a store multiple insn. */
2902 : 1172 : if (targetm.have_store_multiple ())
2903 : : {
2904 : 0 : rtx_insn *last = get_last_insn ();
2905 : 0 : rtx first = gen_rtx_REG (word_mode, regno);
2906 : 0 : if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
2907 : : GEN_INT (nregs)))
2908 : : {
2909 : 0 : emit_insn (pat);
2910 : 0 : return;
2911 : : }
2912 : : else
2913 : 0 : delete_insns_since (last);
2914 : : }
2915 : :
2916 : 2344 : for (int i = 0; i < nregs; i++)
2917 : : {
2918 : 1172 : rtx tem = operand_subword (x, i, 1, BLKmode);
2919 : :
2920 : 1172 : gcc_assert (tem);
2921 : :
2922 : 1172 : emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
2923 : : }
2924 : : }
2925 : :
2926 : : /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
2927 : : ORIG, where ORIG is a non-consecutive group of registers represented by
2928 : : a PARALLEL. The clone is identical to the original except in that the
2929 : : original set of registers is replaced by a new set of pseudo registers.
2930 : : The new set has the same modes as the original set. */
2931 : :
2932 : : rtx
2933 : 2969 : gen_group_rtx (rtx orig)
2934 : : {
2935 : 2969 : int i, length;
2936 : 2969 : rtx *tmps;
2937 : :
2938 : 2969 : gcc_assert (GET_CODE (orig) == PARALLEL);
2939 : :
2940 : 2969 : length = XVECLEN (orig, 0);
2941 : 2969 : tmps = XALLOCAVEC (rtx, length);
2942 : :
2943 : : /* Skip a NULL entry in first slot. */
2944 : 2969 : i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
2945 : :
2946 : 2969 : if (i)
2947 : 0 : tmps[0] = 0;
2948 : :
2949 : 7241 : for (; i < length; i++)
2950 : : {
2951 : 4272 : machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
2952 : 4272 : rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
2953 : :
2954 : 4272 : tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
2955 : : }
2956 : :
2957 : 2969 : return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
2958 : : }
2959 : :
2960 : : /* A subroutine of emit_group_load. Arguments as for emit_group_load,
2961 : : except that values are placed in TMPS[i], and must later be moved
2962 : : into corresponding XEXP (XVECEXP (DST, 0, i), 0) element. */
2963 : :
2964 : : static void
2965 : 304146 : emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
2966 : : poly_int64 ssize)
2967 : : {
2968 : 304149 : rtx src;
2969 : 304149 : int start, i;
2970 : 304149 : machine_mode m = GET_MODE (orig_src);
2971 : :
2972 : 304149 : gcc_assert (GET_CODE (dst) == PARALLEL);
2973 : :
2974 : 304149 : if (m != VOIDmode
2975 : 285505 : && !SCALAR_INT_MODE_P (m)
2976 : 17467 : && !MEM_P (orig_src)
2977 : 4406 : && GET_CODE (orig_src) != CONCAT)
2978 : : {
2979 : 3 : scalar_int_mode imode;
2980 : 3 : if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode))
2981 : : {
2982 : 3 : src = gen_reg_rtx (imode);
2983 : 3 : emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
2984 : : }
2985 : : else
2986 : : {
2987 : 0 : src = assign_stack_temp (GET_MODE (orig_src), ssize);
2988 : 0 : emit_move_insn (src, orig_src);
2989 : : }
2990 : 3 : emit_group_load_1 (tmps, dst, src, type, ssize);
2991 : : return;
2992 : : }
2993 : :
2994 : : /* Check for a NULL entry, used to indicate that the parameter goes
2995 : : both on the stack and in registers. */
2996 : 304146 : if (XEXP (XVECEXP (dst, 0, 0), 0))
2997 : : start = 0;
2998 : : else
2999 : 0 : start = 1;
3000 : :
3001 : : /* Process the pieces. */
3002 : 901925 : for (i = start; i < XVECLEN (dst, 0); i++)
3003 : : {
3004 : 597779 : machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
3005 : 597779 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
3006 : 1195558 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3007 : 597779 : poly_int64 shift = 0;
3008 : :
3009 : : /* Handle trailing fragments that run over the size of the struct.
3010 : : It's the target's responsibility to make sure that the fragment
3011 : : cannot be strictly smaller in some cases and strictly larger
3012 : : in others. */
3013 : 597779 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3014 : 597779 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3015 : : {
3016 : : /* Arrange to shift the fragment to where it belongs.
3017 : : extract_bit_field loads to the lsb of the reg. */
3018 : : if (
3019 : : #ifdef BLOCK_REG_PADDING
3020 : : BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
3021 : : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3022 : : #else
3023 : : BYTES_BIG_ENDIAN
3024 : : #endif
3025 : : )
3026 : : shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3027 : 1778 : bytelen = ssize - bytepos;
3028 : 1778 : gcc_assert (maybe_gt (bytelen, 0));
3029 : : }
3030 : :
3031 : : /* If we won't be loading directly from memory, protect the real source
3032 : : from strange tricks we might play; but make sure that the source can
3033 : : be loaded directly into the destination. */
3034 : 597779 : src = orig_src;
3035 : 597779 : if (!MEM_P (orig_src)
3036 : 501987 : && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
3037 : 641796 : && !CONSTANT_P (orig_src))
3038 : : {
3039 : 6729 : gcc_assert (GET_MODE (orig_src) != VOIDmode);
3040 : 6729 : src = force_reg (GET_MODE (orig_src), orig_src);
3041 : : }
3042 : :
3043 : : /* Optimize the access just a bit. */
3044 : 597779 : if (MEM_P (src)
3045 : 95792 : && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
3046 : 0 : || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
3047 : 191584 : && multiple_p (bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
3048 : 693571 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3049 : : {
3050 : 94033 : tmps[i] = gen_reg_rtx (mode);
3051 : 94033 : emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
3052 : : }
3053 : 503746 : else if (COMPLEX_MODE_P (mode)
3054 : 0 : && GET_MODE (src) == mode
3055 : 503746 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3056 : : /* Let emit_move_complex do the bulk of the work. */
3057 : 0 : tmps[i] = src;
3058 : 503746 : else if (GET_CODE (src) == CONCAT)
3059 : : {
3060 : 13458 : poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
3061 : 13458 : poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
3062 : 6729 : unsigned int elt;
3063 : 6729 : poly_int64 subpos;
3064 : :
3065 : 6729 : if (can_div_trunc_p (bytepos, slen0, &elt, &subpos)
3066 : 6729 : && known_le (subpos + bytelen, slen0))
3067 : : {
3068 : : /* The following assumes that the concatenated objects all
3069 : : have the same size. In this case, a simple calculation
3070 : : can be used to determine the object and the bit field
3071 : : to be extracted. */
3072 : 4652 : tmps[i] = XEXP (src, elt);
3073 : 4652 : if (maybe_ne (subpos, 0)
3074 : 4652 : || maybe_ne (subpos + bytelen, slen0)
3075 : 9304 : || (!CONSTANT_P (tmps[i])
3076 : 4652 : && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
3077 : 0 : tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
3078 : 0 : subpos * BITS_PER_UNIT,
3079 : : 1, NULL_RTX, mode, mode, false,
3080 : : NULL);
3081 : : }
3082 : : else
3083 : : {
3084 : 2077 : rtx mem;
3085 : :
3086 : 2077 : gcc_assert (known_eq (bytepos, 0));
3087 : 2077 : mem = assign_stack_temp (GET_MODE (src), slen);
3088 : 2077 : emit_move_insn (mem, src);
3089 : 2077 : tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
3090 : : 0, 1, NULL_RTX, mode, mode, false,
3091 : : NULL);
3092 : : }
3093 : : }
3094 : 497017 : else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
3095 : 37288 : && XVECLEN (dst, 0) > 1)
3096 : 37288 : tmps[i] = force_subreg (mode, src, GET_MODE (dst), bytepos);
3097 : 459729 : else if (CONSTANT_P (src))
3098 : : {
3099 : 0 : if (known_eq (bytelen, ssize))
3100 : 0 : tmps[i] = src;
3101 : : else
3102 : : {
3103 : : rtx first, second;
3104 : :
3105 : : /* TODO: const_wide_int can have sizes other than this... */
3106 : 0 : gcc_assert (known_eq (2 * bytelen, ssize));
3107 : 0 : split_double (src, &first, &second);
3108 : 0 : if (i)
3109 : 0 : tmps[i] = second;
3110 : : else
3111 : 0 : tmps[i] = first;
3112 : : }
3113 : : }
3114 : 459729 : else if (REG_P (src) && GET_MODE (src) == mode)
3115 : 0 : tmps[i] = src;
3116 : : else
3117 : 459729 : tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
3118 : 919458 : bytepos * BITS_PER_UNIT, 1, NULL_RTX,
3119 : : mode, mode, false, NULL);
3120 : :
3121 : 597779 : if (maybe_ne (shift, 0))
3122 : : tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
3123 : : shift, tmps[i], 0);
3124 : : }
3125 : : }
3126 : :
3127 : : /* Emit code to move a block SRC of type TYPE to a block DST,
3128 : : where DST is non-consecutive registers represented by a PARALLEL.
3129 : : SSIZE represents the total size of block ORIG_SRC in bytes, or -1
3130 : : if not known. */
3131 : :
3132 : : void
3133 : 10780 : emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
3134 : : {
3135 : 10780 : rtx *tmps;
3136 : 10780 : int i;
3137 : :
3138 : 10780 : tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
3139 : 10780 : emit_group_load_1 (tmps, dst, src, type, ssize);
3140 : :
3141 : : /* Copy the extracted pieces into the proper (probable) hard regs. */
3142 : 30364 : for (i = 0; i < XVECLEN (dst, 0); i++)
3143 : : {
3144 : 19584 : rtx d = XEXP (XVECEXP (dst, 0, i), 0);
3145 : 19584 : if (d == NULL)
3146 : 0 : continue;
3147 : 19584 : emit_move_insn (d, tmps[i]);
3148 : : }
3149 : 10780 : }
3150 : :
3151 : : /* Similar, but load SRC into new pseudos in a format that looks like
3152 : : PARALLEL. This can later be fed to emit_group_move to get things
3153 : : in the right place. */
3154 : :
3155 : : rtx
3156 : 293366 : emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
3157 : : {
3158 : 293366 : rtvec vec;
3159 : 293366 : int i;
3160 : :
3161 : 293366 : vec = rtvec_alloc (XVECLEN (parallel, 0));
3162 : 293366 : emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
3163 : :
3164 : : /* Convert the vector to look just like the original PARALLEL, except
3165 : : with the computed values. */
3166 : 871561 : for (i = 0; i < XVECLEN (parallel, 0); i++)
3167 : : {
3168 : 578195 : rtx e = XVECEXP (parallel, 0, i);
3169 : 578195 : rtx d = XEXP (e, 0);
3170 : :
3171 : 578195 : if (d)
3172 : : {
3173 : 578195 : d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
3174 : 578195 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
3175 : : }
3176 : 578195 : RTVEC_ELT (vec, i) = e;
3177 : : }
3178 : :
3179 : 293366 : return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
3180 : : }
3181 : :
3182 : : /* Emit code to move a block SRC to block DST, where SRC and DST are
3183 : : non-consecutive groups of registers, each represented by a PARALLEL. */
3184 : :
3185 : : void
3186 : 296335 : emit_group_move (rtx dst, rtx src)
3187 : : {
3188 : 296335 : int i;
3189 : :
3190 : 296335 : gcc_assert (GET_CODE (src) == PARALLEL
3191 : : && GET_CODE (dst) == PARALLEL
3192 : : && XVECLEN (src, 0) == XVECLEN (dst, 0));
3193 : :
3194 : : /* Skip first entry if NULL. */
3195 : 878802 : for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
3196 : 582467 : emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
3197 : 582467 : XEXP (XVECEXP (src, 0, i), 0));
3198 : 296335 : }
3199 : :
3200 : : /* Move a group of registers represented by a PARALLEL into pseudos. */
3201 : :
3202 : : rtx
3203 : 5689 : emit_group_move_into_temps (rtx src)
3204 : : {
3205 : 5689 : rtvec vec = rtvec_alloc (XVECLEN (src, 0));
3206 : 5689 : int i;
3207 : :
3208 : 13388 : for (i = 0; i < XVECLEN (src, 0); i++)
3209 : : {
3210 : 7699 : rtx e = XVECEXP (src, 0, i);
3211 : 7699 : rtx d = XEXP (e, 0);
3212 : :
3213 : 7699 : if (d)
3214 : 7699 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
3215 : 7699 : RTVEC_ELT (vec, i) = e;
3216 : : }
3217 : :
3218 : 5689 : return gen_rtx_PARALLEL (GET_MODE (src), vec);
3219 : : }
3220 : :
3221 : : /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
3222 : : where SRC is non-consecutive registers represented by a PARALLEL.
3223 : : SSIZE represents the total size of block ORIG_DST, or -1 if not
3224 : : known. */
3225 : :
3226 : : void
3227 : 63801 : emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
3228 : : poly_int64 ssize)
3229 : : {
3230 : 63801 : rtx *tmps, dst;
3231 : 63801 : int start, finish, i;
3232 : 63801 : machine_mode m = GET_MODE (orig_dst);
3233 : :
3234 : 63801 : gcc_assert (GET_CODE (src) == PARALLEL);
3235 : :
3236 : 63801 : if (!SCALAR_INT_MODE_P (m)
3237 : 12862 : && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
3238 : : {
3239 : 0 : scalar_int_mode imode;
3240 : 0 : if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode))
3241 : : {
3242 : 0 : dst = gen_reg_rtx (imode);
3243 : 0 : emit_group_store (dst, src, type, ssize);
3244 : 0 : dst = gen_lowpart (GET_MODE (orig_dst), dst);
3245 : : }
3246 : : else
3247 : : {
3248 : 0 : dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
3249 : 0 : emit_group_store (dst, src, type, ssize);
3250 : : }
3251 : 0 : emit_move_insn (orig_dst, dst);
3252 : 0 : return;
3253 : : }
3254 : :
3255 : : /* Check for a NULL entry, used to indicate that the parameter goes
3256 : : both on the stack and in registers. */
3257 : 63801 : if (XEXP (XVECEXP (src, 0, 0), 0))
3258 : : start = 0;
3259 : : else
3260 : 0 : start = 1;
3261 : 63801 : finish = XVECLEN (src, 0);
3262 : :
3263 : 63801 : tmps = XALLOCAVEC (rtx, finish);
3264 : :
3265 : : /* Copy the (probable) hard regs into pseudos. */
3266 : 183968 : for (i = start; i < finish; i++)
3267 : : {
3268 : 120167 : rtx reg = XEXP (XVECEXP (src, 0, i), 0);
3269 : 120167 : if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
3270 : : {
3271 : 112468 : tmps[i] = gen_reg_rtx (GET_MODE (reg));
3272 : 112468 : emit_move_insn (tmps[i], reg);
3273 : : }
3274 : : else
3275 : 7699 : tmps[i] = reg;
3276 : : }
3277 : :
3278 : : /* If we won't be storing directly into memory, protect the real destination
3279 : : from strange tricks we might play. */
3280 : 63801 : dst = orig_dst;
3281 : 63801 : if (GET_CODE (dst) == PARALLEL)
3282 : : {
3283 : 0 : rtx temp;
3284 : :
3285 : : /* We can get a PARALLEL dst if there is a conditional expression in
3286 : : a return statement. In that case, the dst and src are the same,
3287 : : so no action is necessary. */
3288 : 0 : if (rtx_equal_p (dst, src))
3289 : : return;
3290 : :
3291 : : /* It is unclear if we can ever reach here, but we may as well handle
3292 : : it. Allocate a temporary, and split this into a store/load to/from
3293 : : the temporary. */
3294 : 0 : temp = assign_stack_temp (GET_MODE (dst), ssize);
3295 : 0 : emit_group_store (temp, src, type, ssize);
3296 : 0 : emit_group_load (dst, temp, type, ssize);
3297 : 0 : return;
3298 : : }
3299 : 63801 : else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
3300 : : {
3301 : 50309 : machine_mode outer = GET_MODE (dst);
3302 : 50309 : machine_mode inner;
3303 : 50309 : poly_int64 bytepos;
3304 : 50309 : bool done = false;
3305 : 50309 : rtx temp;
3306 : :
3307 : 50309 : if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
3308 : 0 : dst = gen_reg_rtx (outer);
3309 : :
3310 : : /* Make life a bit easier for combine: if the first element of the
3311 : : vector is the low part of the destination mode, use a paradoxical
3312 : : subreg to initialize the destination. */
3313 : 50309 : if (start < finish)
3314 : : {
3315 : 50309 : inner = GET_MODE (tmps[start]);
3316 : 50309 : bytepos = subreg_lowpart_offset (inner, outer);
3317 : 50309 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
3318 : : bytepos))
3319 : : {
3320 : 50285 : temp = force_subreg (outer, tmps[start], inner, 0);
3321 : 50285 : if (temp)
3322 : : {
3323 : 49623 : emit_move_insn (dst, temp);
3324 : 49623 : done = true;
3325 : 49623 : start++;
3326 : : }
3327 : : }
3328 : : }
3329 : :
3330 : : /* If the first element wasn't the low part, try the last. */
3331 : 49623 : if (!done
3332 : 686 : && start < finish - 1)
3333 : : {
3334 : 619 : inner = GET_MODE (tmps[finish - 1]);
3335 : 619 : bytepos = subreg_lowpart_offset (inner, outer);
3336 : 619 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
3337 : : finish - 1), 1)),
3338 : : bytepos))
3339 : : {
3340 : 0 : temp = force_subreg (outer, tmps[finish - 1], inner, 0);
3341 : 0 : if (temp)
3342 : : {
3343 : 0 : emit_move_insn (dst, temp);
3344 : 0 : done = true;
3345 : 0 : finish--;
3346 : : }
3347 : : }
3348 : : }
3349 : :
3350 : : /* Otherwise, simply initialize the result to zero. */
3351 : 49623 : if (!done)
3352 : 686 : emit_move_insn (dst, CONST0_RTX (outer));
3353 : : }
3354 : :
3355 : : /* Process the pieces. */
3356 : 131601 : for (i = start; i < finish; i++)
3357 : : {
3358 : 70544 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
3359 : 70544 : machine_mode mode = GET_MODE (tmps[i]);
3360 : 141088 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3361 : 70544 : poly_uint64 adj_bytelen;
3362 : 70544 : rtx dest = dst;
3363 : :
3364 : : /* Handle trailing fragments that run over the size of the struct.
3365 : : It's the target's responsibility to make sure that the fragment
3366 : : cannot be strictly smaller in some cases and strictly larger
3367 : : in others. */
3368 : 70544 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3369 : 140276 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3370 : 812 : adj_bytelen = ssize - bytepos;
3371 : : else
3372 : 70544 : adj_bytelen = bytelen;
3373 : :
3374 : : /* Deal with destination CONCATs by either storing into one of the parts
3375 : : or doing a copy after storing into a register or stack temporary. */
3376 : 70544 : if (GET_CODE (dst) == CONCAT)
3377 : : {
3378 : 24288 : if (known_le (bytepos + adj_bytelen,
3379 : : GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3380 : : dest = XEXP (dst, 0);
3381 : :
3382 : 14888 : else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3383 : : {
3384 : 9400 : bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
3385 : 4700 : dest = XEXP (dst, 1);
3386 : : }
3387 : :
3388 : : else
3389 : : {
3390 : 2744 : machine_mode dest_mode = GET_MODE (dest);
3391 : 2744 : machine_mode tmp_mode = GET_MODE (tmps[i]);
3392 : 2744 : scalar_int_mode dest_imode;
3393 : :
3394 : 2744 : gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
3395 : :
3396 : : /* If the source is a single scalar integer register, and the
3397 : : destination has a complex mode for which a same-sized integer
3398 : : mode exists, then we can take the left-justified part of the
3399 : : source in the complex mode. */
3400 : 2744 : if (finish == start + 1
3401 : 2744 : && REG_P (tmps[i])
3402 : 2744 : && SCALAR_INT_MODE_P (tmp_mode)
3403 : 2744 : && COMPLEX_MODE_P (dest_mode)
3404 : 5488 : && int_mode_for_mode (dest_mode).exists (&dest_imode))
3405 : : {
3406 : 2744 : const scalar_int_mode tmp_imode
3407 : 2744 : = as_a <scalar_int_mode> (tmp_mode);
3408 : :
3409 : 5488 : if (GET_MODE_BITSIZE (dest_imode)
3410 : 2744 : < GET_MODE_BITSIZE (tmp_imode))
3411 : : {
3412 : 59 : dest = gen_reg_rtx (dest_imode);
3413 : 59 : if (BYTES_BIG_ENDIAN)
3414 : : tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
3415 : : GET_MODE_BITSIZE (tmp_imode)
3416 : : - GET_MODE_BITSIZE (dest_imode),
3417 : : NULL_RTX, 1);
3418 : 59 : emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
3419 : 59 : dst = gen_lowpart (dest_mode, dest);
3420 : : }
3421 : : else
3422 : 2685 : dst = gen_lowpart (dest_mode, tmps[i]);
3423 : : }
3424 : :
3425 : : /* Otherwise spill the source onto the stack using the more
3426 : : aligned of the two modes. */
3427 : 0 : else if (GET_MODE_ALIGNMENT (dest_mode)
3428 : 0 : >= GET_MODE_ALIGNMENT (tmp_mode))
3429 : : {
3430 : 0 : dest = assign_stack_temp (dest_mode,
3431 : 0 : GET_MODE_SIZE (dest_mode));
3432 : 0 : emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
3433 : : tmps[i]);
3434 : 0 : dst = dest;
3435 : : }
3436 : :
3437 : : else
3438 : : {
3439 : 0 : dest = assign_stack_temp (tmp_mode,
3440 : 0 : GET_MODE_SIZE (tmp_mode));
3441 : 0 : emit_move_insn (dest, tmps[i]);
3442 : 0 : dst = adjust_address (dest, dest_mode, bytepos);
3443 : : }
3444 : :
3445 : : break;
3446 : : }
3447 : : }
3448 : :
3449 : : /* Handle trailing fragments that run over the size of the struct. */
3450 : 67800 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3451 : : {
3452 : : /* store_bit_field always takes its value from the lsb.
3453 : : Move the fragment to the lsb if it's not already there. */
3454 : 753 : if (
3455 : : #ifdef BLOCK_REG_PADDING
3456 : : BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
3457 : : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3458 : : #else
3459 : : BYTES_BIG_ENDIAN
3460 : : #endif
3461 : : )
3462 : : {
3463 : : poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3464 : : tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
3465 : : shift, tmps[i], 0);
3466 : : }
3467 : :
3468 : : /* Make sure not to write past the end of the struct. */
3469 : 753 : store_bit_field (dest,
3470 : 753 : adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3471 : 2259 : bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
3472 : : VOIDmode, tmps[i], false, false);
3473 : : }
3474 : :
3475 : : /* Optimize the access just a bit. */
3476 : 67047 : else if (MEM_P (dest)
3477 : 7552 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
3478 : 0 : || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
3479 : 15104 : && multiple_p (bytepos * BITS_PER_UNIT,
3480 : : GET_MODE_ALIGNMENT (mode))
3481 : 74599 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3482 : 7552 : emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
3483 : :
3484 : : else
3485 : 118990 : store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3486 : : 0, 0, mode, tmps[i], false, false);
3487 : : }
3488 : :
3489 : : /* Copy from the pseudo into the (probable) hard reg. */
3490 : 63801 : if (orig_dst != dst)
3491 : 2744 : emit_move_insn (orig_dst, dst);
3492 : : }
3493 : :
3494 : : /* Return a form of X that does not use a PARALLEL. TYPE is the type
3495 : : of the value stored in X. */
3496 : :
3497 : : rtx
3498 : 323450 : maybe_emit_group_store (rtx x, tree type)
3499 : : {
3500 : 323450 : machine_mode mode = TYPE_MODE (type);
3501 : 323450 : gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
3502 : 323450 : if (GET_CODE (x) == PARALLEL)
3503 : : {
3504 : 0 : rtx result = gen_reg_rtx (mode);
3505 : 0 : emit_group_store (result, x, type, int_size_in_bytes (type));
3506 : 0 : return result;
3507 : : }
3508 : : return x;
3509 : : }
3510 : :
3511 : : /* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
3512 : :
3513 : : This is used on targets that return BLKmode values in registers. */
3514 : :
3515 : : static void
3516 : 246 : copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
3517 : : {
3518 : 246 : unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
3519 : 246 : rtx src = NULL, dst = NULL;
3520 : 246 : unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
3521 : 246 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
3522 : : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3523 : 246 : fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
3524 : 246 : fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
3525 : 246 : fixed_size_mode copy_mode;
3526 : :
3527 : : /* BLKmode registers created in the back-end shouldn't have survived. */
3528 : 246 : gcc_assert (mode != BLKmode);
3529 : :
3530 : : /* If the structure doesn't take up a whole number of words, see whether
3531 : : SRCREG is padded on the left or on the right. If it's on the left,
3532 : : set PADDING_CORRECTION to the number of bits to skip.
3533 : :
3534 : : In most ABIs, the structure will be returned at the least end of
3535 : : the register, which translates to right padding on little-endian
3536 : : targets and left padding on big-endian targets. The opposite
3537 : : holds if the structure is returned at the most significant
3538 : : end of the register. */
3539 : 246 : if (bytes % UNITS_PER_WORD != 0
3540 : 246 : && (targetm.calls.return_in_msb (type)
3541 : 215 : ? !BYTES_BIG_ENDIAN
3542 : : : BYTES_BIG_ENDIAN))
3543 : 0 : padding_correction
3544 : 0 : = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
3545 : :
3546 : : /* We can use a single move if we have an exact mode for the size. */
3547 : 246 : else if (MEM_P (target)
3548 : 246 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
3549 : 0 : || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
3550 : 492 : && bytes == GET_MODE_SIZE (mode))
3551 : : {
3552 : 38 : emit_move_insn (adjust_address (target, mode, 0), srcreg);
3553 : 38 : return;
3554 : : }
3555 : :
3556 : : /* And if we additionally have the same mode for a register. */
3557 : 208 : else if (REG_P (target)
3558 : 0 : && GET_MODE (target) == mode
3559 : 208 : && bytes == GET_MODE_SIZE (mode))
3560 : : {
3561 : 0 : emit_move_insn (target, srcreg);
3562 : 0 : return;
3563 : : }
3564 : :
3565 : : /* This code assumes srcreg is at least a full word. If it isn't, copy it
3566 : : into a new pseudo which is a full word. */
3567 : 416 : if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3568 : : {
3569 : 76 : srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
3570 : 76 : mode = word_mode;
3571 : : }
3572 : :
3573 : : /* Copy the structure BITSIZE bits at a time. If the target lives in
3574 : : memory, take care of not reading/writing past its end by selecting
3575 : : a copy mode suited to BITSIZE. This should always be possible given
3576 : : how it is computed.
3577 : :
3578 : : If the target lives in register, make sure not to select a copy mode
3579 : : larger than the mode of the register.
3580 : :
3581 : : We could probably emit more efficient code for machines which do not use
3582 : : strict alignment, but it doesn't seem worth the effort at the current
3583 : : time. */
3584 : :
3585 : 208 : copy_mode = word_mode;
3586 : 208 : if (MEM_P (target))
3587 : : {
3588 : 208 : opt_scalar_int_mode mem_mode = int_mode_for_size (bitsize, 1);
3589 : 208 : if (mem_mode.exists ())
3590 : 208 : copy_mode = mem_mode.require ();
3591 : : }
3592 : 0 : else if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3593 : : copy_mode = tmode;
3594 : :
3595 : 208 : for (bitpos = 0, xbitpos = padding_correction;
3596 : 1017 : bitpos < bytes * BITS_PER_UNIT;
3597 : 809 : bitpos += bitsize, xbitpos += bitsize)
3598 : : {
3599 : : /* We need a new source operand each time xbitpos is on a
3600 : : word boundary and when xbitpos == padding_correction
3601 : : (the first time through). */
3602 : 809 : if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
3603 : 208 : src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
3604 : :
3605 : : /* We need a new destination operand each time bitpos is on
3606 : : a word boundary. */
3607 : 809 : if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3608 : : dst = target;
3609 : 809 : else if (bitpos % BITS_PER_WORD == 0)
3610 : 208 : dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
3611 : :
3612 : : /* Use xbitpos for the source extraction (right justified) and
3613 : : bitpos for the destination store (left justified). */
3614 : 809 : store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
3615 : 809 : extract_bit_field (src, bitsize,
3616 : 809 : xbitpos % BITS_PER_WORD, 1,
3617 : : NULL_RTX, copy_mode, copy_mode,
3618 : : false, NULL),
3619 : : false, false);
3620 : : }
3621 : : }
3622 : :
3623 : : /* Copy BLKmode value SRC into a register of mode MODE_IN. Return the
3624 : : register if it contains any data, otherwise return null.
3625 : :
3626 : : This is used on targets that return BLKmode values in registers. */
3627 : :
3628 : : rtx
3629 : 3989 : copy_blkmode_to_reg (machine_mode mode_in, tree src)
3630 : : {
3631 : 3989 : int i, n_regs;
3632 : 3989 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
3633 : 3989 : unsigned int bitsize;
3634 : 3989 : rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
3635 : : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3636 : 3989 : fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
3637 : 3989 : fixed_size_mode dst_mode;
3638 : 3989 : scalar_int_mode min_mode;
3639 : :
3640 : 3989 : gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
3641 : :
3642 : 3989 : x = expand_normal (src);
3643 : :
3644 : 3989 : bytes = arg_int_size_in_bytes (TREE_TYPE (src));
3645 : 3989 : if (bytes == 0)
3646 : : return NULL_RTX;
3647 : :
3648 : : /* If the structure doesn't take up a whole number of words, see
3649 : : whether the register value should be padded on the left or on
3650 : : the right. Set PADDING_CORRECTION to the number of padding
3651 : : bits needed on the left side.
3652 : :
3653 : : In most ABIs, the structure will be returned at the least end of
3654 : : the register, which translates to right padding on little-endian
3655 : : targets and left padding on big-endian targets. The opposite
3656 : : holds if the structure is returned at the most significant
3657 : : end of the register. */
3658 : 1221 : if (bytes % UNITS_PER_WORD != 0
3659 : 1221 : && (targetm.calls.return_in_msb (TREE_TYPE (src))
3660 : 1185 : ? !BYTES_BIG_ENDIAN
3661 : : : BYTES_BIG_ENDIAN))
3662 : 0 : padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
3663 : 0 : * BITS_PER_UNIT));
3664 : :
3665 : 1221 : n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3666 : 1221 : dst_words = XALLOCAVEC (rtx, n_regs);
3667 : 1221 : bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
3668 : 1221 : min_mode = smallest_int_mode_for_size (bitsize).require ();
3669 : :
3670 : : /* Copy the structure BITSIZE bits at a time. */
3671 : 1221 : for (bitpos = 0, xbitpos = padding_correction;
3672 : 3965 : bitpos < bytes * BITS_PER_UNIT;
3673 : 2744 : bitpos += bitsize, xbitpos += bitsize)
3674 : : {
3675 : : /* We need a new destination pseudo each time xbitpos is
3676 : : on a word boundary and when xbitpos == padding_correction
3677 : : (the first time through). */
3678 : 2744 : if (xbitpos % BITS_PER_WORD == 0
3679 : 1520 : || xbitpos == padding_correction)
3680 : : {
3681 : : /* Generate an appropriate register. */
3682 : 1224 : dst_word = gen_reg_rtx (word_mode);
3683 : 1224 : dst_words[xbitpos / BITS_PER_WORD] = dst_word;
3684 : :
3685 : : /* Clear the destination before we move anything into it. */
3686 : 1224 : emit_move_insn (dst_word, CONST0_RTX (word_mode));
3687 : : }
3688 : :
3689 : : /* Find the largest integer mode that can be used to copy all or as
3690 : : many bits as possible of the structure if the target supports larger
3691 : : copies. There are too many corner cases here w.r.t to alignments on
3692 : : the read/writes. So if there is any padding just use single byte
3693 : : operations. */
3694 : 2744 : opt_scalar_int_mode mode_iter;
3695 : 2744 : if (padding_correction == 0 && !STRICT_ALIGNMENT)
3696 : : {
3697 : 7470 : FOR_EACH_MODE_FROM (mode_iter, min_mode)
3698 : : {
3699 : 7470 : unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
3700 : 7470 : if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
3701 : 4729 : && msize <= BITS_PER_WORD)
3702 : 4726 : bitsize = msize;
3703 : : else
3704 : : break;
3705 : : }
3706 : : }
3707 : :
3708 : : /* We need a new source operand each time bitpos is on a word
3709 : : boundary. */
3710 : 2744 : if (bitpos % BITS_PER_WORD == 0)
3711 : 1224 : src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
3712 : :
3713 : : /* Use bitpos for the source extraction (left justified) and
3714 : : xbitpos for the destination store (right justified). */
3715 : 5488 : store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
3716 : : 0, 0, word_mode,
3717 : 2744 : extract_bit_field (src_word, bitsize,
3718 : 2744 : bitpos % BITS_PER_WORD, 1,
3719 : : NULL_RTX, word_mode, word_mode,
3720 : : false, NULL),
3721 : : false, false);
3722 : : }
3723 : :
3724 : 1221 : if (mode == BLKmode)
3725 : : {
3726 : : /* Find the smallest integer mode large enough to hold the
3727 : : entire structure. */
3728 : 0 : opt_scalar_int_mode mode_iter;
3729 : 0 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3730 : 0 : if (GET_MODE_SIZE (mode_iter.require ()) >= bytes)
3731 : : break;
3732 : :
3733 : : /* A suitable mode should have been found. */
3734 : 0 : mode = mode_iter.require ();
3735 : : }
3736 : :
3737 : 3663 : if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
3738 : : dst_mode = word_mode;
3739 : : else
3740 : 495 : dst_mode = mode;
3741 : 1221 : dst = gen_reg_rtx (dst_mode);
3742 : :
3743 : 3666 : for (i = 0; i < n_regs; i++)
3744 : 1224 : emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
3745 : :
3746 : 1221 : if (mode != dst_mode)
3747 : 726 : dst = gen_lowpart (mode, dst);
3748 : :
3749 : : return dst;
3750 : : }
3751 : :
3752 : : /* Add a USE expression for REG to the (possibly empty) list pointed
3753 : : to by CALL_FUSAGE. REG must denote a hard register. */
3754 : :
3755 : : void
3756 : 11344756 : use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3757 : : {
3758 : 11344756 : gcc_assert (REG_P (reg));
3759 : :
3760 : 11344756 : if (!HARD_REGISTER_P (reg))
3761 : : return;
3762 : :
3763 : 11344756 : *call_fusage
3764 : 11344756 : = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
3765 : : }
3766 : :
3767 : : /* Add a CLOBBER expression for REG to the (possibly empty) list pointed
3768 : : to by CALL_FUSAGE. REG must denote a hard register. */
3769 : :
3770 : : void
3771 : 797494 : clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3772 : : {
3773 : 797494 : gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
3774 : :
3775 : 797494 : *call_fusage
3776 : 797494 : = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
3777 : 797494 : }
3778 : :
3779 : : /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
3780 : : starting at REGNO. All of these registers must be hard registers. */
3781 : :
3782 : : void
3783 : 1565 : use_regs (rtx *call_fusage, int regno, int nregs)
3784 : : {
3785 : 1565 : int i;
3786 : :
3787 : 1565 : gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
3788 : :
3789 : 3130 : for (i = 0; i < nregs; i++)
3790 : 1565 : use_reg (call_fusage, regno_reg_rtx[regno + i]);
3791 : 1565 : }
3792 : :
3793 : : /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
3794 : : PARALLEL REGS. This is for calls that pass values in multiple
3795 : : non-contiguous locations. The Irix 6 ABI has examples of this. */
3796 : :
3797 : : void
3798 : 300551 : use_group_regs (rtx *call_fusage, rtx regs)
3799 : : {
3800 : 300551 : int i;
3801 : :
3802 : 893116 : for (i = 0; i < XVECLEN (regs, 0); i++)
3803 : : {
3804 : 592565 : rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
3805 : :
3806 : : /* A NULL entry means the parameter goes both on the stack and in
3807 : : registers. This can also be a MEM for targets that pass values
3808 : : partially on the stack and partially in registers. */
3809 : 592565 : if (reg != 0 && REG_P (reg))
3810 : 592565 : use_reg (call_fusage, reg);
3811 : : }
3812 : 300551 : }
3813 : :
3814 : : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3815 : : assigment and the code of the expresion on the RHS is CODE. Return
3816 : : NULL otherwise. */
3817 : :
3818 : : static gimple *
3819 : 11575133 : get_def_for_expr (tree name, enum tree_code code)
3820 : : {
3821 : 11575133 : gimple *def_stmt;
3822 : :
3823 : 11575133 : if (TREE_CODE (name) != SSA_NAME)
3824 : : return NULL;
3825 : :
3826 : 9053450 : def_stmt = get_gimple_for_ssa_name (name);
3827 : 9053450 : if (!def_stmt
3828 : 1942518 : || !is_gimple_assign (def_stmt)
3829 : 10994626 : || gimple_assign_rhs_code (def_stmt) != code)
3830 : : return NULL;
3831 : :
3832 : : return def_stmt;
3833 : : }
3834 : :
3835 : : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3836 : : assigment and the class of the expresion on the RHS is CLASS. Return
3837 : : NULL otherwise. */
3838 : :
3839 : : static gimple *
3840 : 16005 : get_def_for_expr_class (tree name, enum tree_code_class tclass)
3841 : : {
3842 : 16005 : gimple *def_stmt;
3843 : :
3844 : 16005 : if (TREE_CODE (name) != SSA_NAME)
3845 : : return NULL;
3846 : :
3847 : 16005 : def_stmt = get_gimple_for_ssa_name (name);
3848 : 16005 : if (!def_stmt
3849 : 13878 : || !is_gimple_assign (def_stmt)
3850 : 29883 : || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
3851 : : return NULL;
3852 : :
3853 : : return def_stmt;
3854 : : }
3855 : :
3856 : : /* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is
3857 : : its length in bytes. */
3858 : :
3859 : : rtx
3860 : 131036 : clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
3861 : : unsigned int expected_align, HOST_WIDE_INT expected_size,
3862 : : unsigned HOST_WIDE_INT min_size,
3863 : : unsigned HOST_WIDE_INT max_size,
3864 : : unsigned HOST_WIDE_INT probable_max_size,
3865 : : unsigned ctz_size)
3866 : : {
3867 : 131036 : machine_mode mode = GET_MODE (object);
3868 : 131036 : unsigned int align;
3869 : :
3870 : 131036 : gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
3871 : :
3872 : : /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
3873 : : just move a zero. Otherwise, do this a piece at a time. */
3874 : 131036 : poly_int64 size_val;
3875 : 131036 : if (mode != BLKmode
3876 : 52478 : && poly_int_rtx_p (size, &size_val)
3877 : 183514 : && known_eq (size_val, GET_MODE_SIZE (mode)))
3878 : : {
3879 : 52478 : rtx zero = CONST0_RTX (mode);
3880 : 52478 : if (zero != NULL)
3881 : : {
3882 : 52478 : emit_move_insn (object, zero);
3883 : 52478 : return NULL;
3884 : : }
3885 : :
3886 : 0 : if (COMPLEX_MODE_P (mode))
3887 : : {
3888 : 0 : zero = CONST0_RTX (GET_MODE_INNER (mode));
3889 : 0 : if (zero != NULL)
3890 : : {
3891 : 0 : write_complex_part (object, zero, 0, true);
3892 : 0 : write_complex_part (object, zero, 1, false);
3893 : 0 : return NULL;
3894 : : }
3895 : : }
3896 : : }
3897 : :
3898 : 78558 : if (size == const0_rtx)
3899 : : return NULL;
3900 : :
3901 : 78558 : align = MEM_ALIGN (object);
3902 : :
3903 : 78558 : if (CONST_INT_P (size)
3904 : 150194 : && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
3905 : : CLEAR_BY_PIECES,
3906 : 71636 : optimize_insn_for_speed_p ()))
3907 : 52036 : clear_by_pieces (object, INTVAL (size), align);
3908 : 26522 : else if (set_storage_via_setmem (object, size, const0_rtx, align,
3909 : : expected_align, expected_size,
3910 : : min_size, max_size, probable_max_size))
3911 : : ;
3912 : 5733 : else if (try_store_by_multiple_pieces (object, size, ctz_size,
3913 : : min_size, max_size,
3914 : : NULL_RTX, 0, align))
3915 : : ;
3916 : 5685 : else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
3917 : 5685 : return set_storage_via_libcall (object, size, const0_rtx,
3918 : 5685 : method == BLOCK_OP_TAILCALL);
3919 : : else
3920 : 0 : gcc_unreachable ();
3921 : :
3922 : : return NULL;
3923 : : }
3924 : :
3925 : : rtx
3926 : 109894 : clear_storage (rtx object, rtx size, enum block_op_methods method)
3927 : : {
3928 : 109894 : unsigned HOST_WIDE_INT max, min = 0;
3929 : 109894 : if (GET_CODE (size) == CONST_INT)
3930 : 109894 : min = max = UINTVAL (size);
3931 : : else
3932 : 0 : max = GET_MODE_MASK (GET_MODE (size));
3933 : 109894 : return clear_storage_hints (object, size, method, 0, -1, min, max, max, 0);
3934 : : }
3935 : :
3936 : :
3937 : : /* A subroutine of clear_storage. Expand a call to memset.
3938 : : Return the return value of memset, 0 otherwise. */
3939 : :
3940 : : rtx
3941 : 5689 : set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
3942 : : {
3943 : 5689 : tree call_expr, fn, object_tree, size_tree, val_tree;
3944 : 5689 : machine_mode size_mode;
3945 : :
3946 : 5689 : object = copy_addr_to_reg (XEXP (object, 0));
3947 : 5689 : object_tree = make_tree (ptr_type_node, object);
3948 : :
3949 : 5689 : if (!CONST_INT_P (val))
3950 : 3 : val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
3951 : 5689 : val_tree = make_tree (integer_type_node, val);
3952 : :
3953 : 5689 : size_mode = TYPE_MODE (sizetype);
3954 : 5689 : size = convert_to_mode (size_mode, size, 1);
3955 : 5689 : size = copy_to_mode_reg (size_mode, size);
3956 : 5689 : size_tree = make_tree (sizetype, size);
3957 : :
3958 : : /* It is incorrect to use the libcall calling conventions for calls to
3959 : : memset because it can be provided by the user. */
3960 : 5689 : fn = builtin_decl_implicit (BUILT_IN_MEMSET);
3961 : 5689 : call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
3962 : 5689 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
3963 : :
3964 : 5689 : return expand_call (call_expr, NULL_RTX, false);
3965 : : }
3966 : :
3967 : : /* Expand a setmem pattern; return true if successful. */
3968 : :
3969 : : bool
3970 : 35117 : set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
3971 : : unsigned int expected_align, HOST_WIDE_INT expected_size,
3972 : : unsigned HOST_WIDE_INT min_size,
3973 : : unsigned HOST_WIDE_INT max_size,
3974 : : unsigned HOST_WIDE_INT probable_max_size)
3975 : : {
3976 : : /* Try the most limited insn first, because there's no point
3977 : : including more than one in the machine description unless
3978 : : the more limited one has some advantage. */
3979 : :
3980 : 35117 : if (expected_align < align)
3981 : : expected_align = align;
3982 : 35117 : if (expected_size != -1)
3983 : : {
3984 : 5 : if ((unsigned HOST_WIDE_INT)expected_size > max_size)
3985 : 0 : expected_size = max_size;
3986 : 5 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
3987 : 0 : expected_size = min_size;
3988 : : }
3989 : :
3990 : 35117 : opt_scalar_int_mode mode_iter;
3991 : 165700 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3992 : : {
3993 : 153769 : scalar_int_mode mode = mode_iter.require ();
3994 : 153769 : enum insn_code code = direct_optab_handler (setmem_optab, mode);
3995 : :
3996 : 153769 : if (code != CODE_FOR_nothing
3997 : : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
3998 : : here because if SIZE is less than the mode mask, as it is
3999 : : returned by the macro, it will definitely be less than the
4000 : : actual mode mask. Since SIZE is within the Pmode address
4001 : : space, we limit MODE to Pmode. */
4002 : 153769 : && ((CONST_INT_P (size)
4003 : 20906 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
4004 : 20906 : <= (GET_MODE_MASK (mode) >> 1)))
4005 : 25931 : || max_size <= (GET_MODE_MASK (mode) >> 1)
4006 : 29374 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
4007 : : {
4008 : 36465 : class expand_operand ops[9];
4009 : 36465 : unsigned int nops;
4010 : :
4011 : 36465 : nops = insn_data[(int) code].n_generator_args;
4012 : 36465 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
4013 : :
4014 : 36465 : create_fixed_operand (&ops[0], object);
4015 : : /* The check above guarantees that this size conversion is valid. */
4016 : 36465 : create_convert_operand_to (&ops[1], size, mode, true);
4017 : 36465 : create_convert_operand_from (&ops[2], val, byte_mode, true);
4018 : 36465 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
4019 : 36465 : if (nops >= 6)
4020 : : {
4021 : 36465 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
4022 : 36465 : create_integer_operand (&ops[5], expected_size);
4023 : : }
4024 : 36465 : if (nops >= 8)
4025 : : {
4026 : 36465 : create_integer_operand (&ops[6], min_size);
4027 : : /* If we cannot represent the maximal size,
4028 : : make parameter NULL. */
4029 : 36465 : if ((HOST_WIDE_INT) max_size != -1)
4030 : 34153 : create_integer_operand (&ops[7], max_size);
4031 : : else
4032 : 2312 : create_fixed_operand (&ops[7], NULL);
4033 : : }
4034 : 36465 : if (nops == 9)
4035 : : {
4036 : : /* If we cannot represent the maximal size,
4037 : : make parameter NULL. */
4038 : 36465 : if ((HOST_WIDE_INT) probable_max_size != -1)
4039 : 34644 : create_integer_operand (&ops[8], probable_max_size);
4040 : : else
4041 : 1821 : create_fixed_operand (&ops[8], NULL);
4042 : : }
4043 : 36465 : if (maybe_expand_insn (code, nops, ops))
4044 : 23186 : return true;
4045 : : }
4046 : : }
4047 : :
4048 : : return false;
4049 : : }
4050 : :
4051 : :
4052 : : /* Write to one of the components of the complex value CPLX. Write VAL to
4053 : : the real part if IMAG_P is false, and the imaginary part if its true.
4054 : : If UNDEFINED_P then the value in CPLX is currently undefined. */
4055 : :
4056 : : void
4057 : 545864 : write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
4058 : : {
4059 : 545864 : machine_mode cmode;
4060 : 545864 : scalar_mode imode;
4061 : 545864 : unsigned ibitsize;
4062 : :
4063 : 545864 : if (GET_CODE (cplx) == CONCAT)
4064 : : {
4065 : 485670 : emit_move_insn (XEXP (cplx, imag_p), val);
4066 : 485670 : return;
4067 : : }
4068 : :
4069 : 60194 : cmode = GET_MODE (cplx);
4070 : 60194 : imode = GET_MODE_INNER (cmode);
4071 : 60194 : ibitsize = GET_MODE_BITSIZE (imode);
4072 : :
4073 : : /* For MEMs simplify_gen_subreg may generate an invalid new address
4074 : : because, e.g., the original address is considered mode-dependent
4075 : : by the target, which restricts simplify_subreg from invoking
4076 : : adjust_address_nv. Instead of preparing fallback support for an
4077 : : invalid address, we call adjust_address_nv directly. */
4078 : 60194 : if (MEM_P (cplx))
4079 : : {
4080 : 73539 : emit_move_insn (adjust_address_nv (cplx, imode,
4081 : : imag_p ? GET_MODE_SIZE (imode) : 0),
4082 : : val);
4083 : 49026 : return;
4084 : : }
4085 : :
4086 : : /* If the sub-object is at least word sized, then we know that subregging
4087 : : will work. This special case is important, since store_bit_field
4088 : : wants to operate on integer modes, and there's rarely an OImode to
4089 : : correspond to TCmode. */
4090 : 11168 : if (ibitsize >= BITS_PER_WORD
4091 : : /* For hard regs we have exact predicates. Assume we can split
4092 : : the original object if it spans an even number of hard regs.
4093 : : This special case is important for SCmode on 64-bit platforms
4094 : : where the natural size of floating-point regs is 32-bit. */
4095 : 11168 : || (REG_P (cplx)
4096 : 7304 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4097 : 7120 : && REG_NREGS (cplx) % 2 == 0))
4098 : : {
4099 : 3880 : rtx part = simplify_gen_subreg (imode, cplx, cmode,
4100 : 5820 : imag_p ? GET_MODE_SIZE (imode) : 0);
4101 : 3880 : if (part)
4102 : : {
4103 : 3880 : emit_move_insn (part, val);
4104 : 3880 : return;
4105 : : }
4106 : : else
4107 : : /* simplify_gen_subreg may fail for sub-word MEMs. */
4108 : 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4109 : : }
4110 : :
4111 : 10932 : store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
4112 : : false, undefined_p);
4113 : : }
4114 : :
4115 : : /* Extract one of the components of the complex value CPLX. Extract the
4116 : : real part if IMAG_P is false, and the imaginary part if it's true. */
4117 : :
4118 : : rtx
4119 : 495010 : read_complex_part (rtx cplx, bool imag_p)
4120 : : {
4121 : 495010 : machine_mode cmode;
4122 : 495010 : scalar_mode imode;
4123 : 495010 : unsigned ibitsize;
4124 : :
4125 : 495010 : if (GET_CODE (cplx) == CONCAT)
4126 : 318799 : return XEXP (cplx, imag_p);
4127 : :
4128 : 176211 : cmode = GET_MODE (cplx);
4129 : 176211 : imode = GET_MODE_INNER (cmode);
4130 : 176211 : ibitsize = GET_MODE_BITSIZE (imode);
4131 : :
4132 : : /* Special case reads from complex constants that got spilled to memory. */
4133 : 176211 : if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
4134 : : {
4135 : 37915 : tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
4136 : 37915 : if (decl && TREE_CODE (decl) == COMPLEX_CST)
4137 : : {
4138 : 0 : tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
4139 : 0 : if (CONSTANT_CLASS_P (part))
4140 : 0 : return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
4141 : : }
4142 : : }
4143 : :
4144 : : /* For MEMs simplify_gen_subreg may generate an invalid new address
4145 : : because, e.g., the original address is considered mode-dependent
4146 : : by the target, which restricts simplify_subreg from invoking
4147 : : adjust_address_nv. Instead of preparing fallback support for an
4148 : : invalid address, we call adjust_address_nv directly. */
4149 : 176211 : if (MEM_P (cplx))
4150 : 236570 : return adjust_address_nv (cplx, imode,
4151 : : imag_p ? GET_MODE_SIZE (imode) : 0);
4152 : :
4153 : : /* If the sub-object is at least word sized, then we know that subregging
4154 : : will work. This special case is important, since extract_bit_field
4155 : : wants to operate on integer modes, and there's rarely an OImode to
4156 : : correspond to TCmode. */
4157 : 18429 : if (ibitsize >= BITS_PER_WORD
4158 : : /* For hard regs we have exact predicates. Assume we can split
4159 : : the original object if it spans an even number of hard regs.
4160 : : This special case is important for SCmode on 64-bit platforms
4161 : : where the natural size of floating-point regs is 32-bit. */
4162 : 18429 : || (REG_P (cplx)
4163 : 338 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4164 : 292 : && REG_NREGS (cplx) % 2 == 0))
4165 : : {
4166 : 9111 : rtx ret = simplify_gen_subreg (imode, cplx, cmode,
4167 : 13666 : imag_p ? GET_MODE_SIZE (imode) : 0);
4168 : 9111 : if (ret)
4169 : : return ret;
4170 : : else
4171 : : /* simplify_gen_subreg may fail for sub-word MEMs. */
4172 : 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4173 : : }
4174 : :
4175 : 13977 : return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
4176 : : true, NULL_RTX, imode, imode, false, NULL);
4177 : : }
4178 : :
4179 : : /* A subroutine of emit_move_insn_1. Yet another lowpart generator.
4180 : : NEW_MODE and OLD_MODE are the same size. Return NULL if X cannot be
4181 : : represented in NEW_MODE. If FORCE is true, this will never happen, as
4182 : : we'll force-create a SUBREG if needed. */
4183 : :
4184 : : static rtx
4185 : 244692 : emit_move_change_mode (machine_mode new_mode,
4186 : : machine_mode old_mode, rtx x, bool force)
4187 : : {
4188 : 244692 : rtx ret;
4189 : :
4190 : 244692 : if (push_operand (x, GET_MODE (x)))
4191 : : {
4192 : 1318 : ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
4193 : 1318 : MEM_COPY_ATTRIBUTES (ret, x);
4194 : : }
4195 : 243374 : else if (MEM_P (x))
4196 : : {
4197 : : /* We don't have to worry about changing the address since the
4198 : : size in bytes is supposed to be the same. */
4199 : 53323 : if (reload_in_progress)
4200 : : {
4201 : : /* Copy the MEM to change the mode and move any
4202 : : substitutions from the old MEM to the new one. */
4203 : 0 : ret = adjust_address_nv (x, new_mode, 0);
4204 : 0 : copy_replacements (x, ret);
4205 : : }
4206 : : else
4207 : 53323 : ret = adjust_address (x, new_mode, 0);
4208 : : }
4209 : : else
4210 : : {
4211 : : /* Note that we do want simplify_subreg's behavior of validating
4212 : : that the new mode is ok for a hard register. If we were to use
4213 : : simplify_gen_subreg, we would create the subreg, but would
4214 : : probably run into the target not being able to implement it. */
4215 : : /* Except, of course, when FORCE is true, when this is exactly what
4216 : : we want. Which is needed for CCmodes on some targets. */
4217 : 190051 : if (force)
4218 : 190051 : ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
4219 : : else
4220 : 0 : ret = simplify_subreg (new_mode, x, old_mode, 0);
4221 : : }
4222 : :
4223 : 244692 : return ret;
4224 : : }
4225 : :
4226 : : /* A subroutine of emit_move_insn_1. Generate a move from Y into X using
4227 : : an integer mode of the same size as MODE. Returns the instruction
4228 : : emitted, or NULL if such a move could not be generated. */
4229 : :
4230 : : static rtx_insn *
4231 : 122346 : emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
4232 : : {
4233 : 122346 : scalar_int_mode imode;
4234 : 122346 : enum insn_code code;
4235 : :
4236 : : /* There must exist a mode of the exact size we require. */
4237 : 122346 : if (!int_mode_for_mode (mode).exists (&imode))
4238 : 0 : return NULL;
4239 : :
4240 : : /* The target must support moves in this mode. */
4241 : 122346 : code = optab_handler (mov_optab, imode);
4242 : 122346 : if (code == CODE_FOR_nothing)
4243 : : return NULL;
4244 : :
4245 : 122346 : x = emit_move_change_mode (imode, mode, x, force);
4246 : 122346 : if (x == NULL_RTX)
4247 : : return NULL;
4248 : 122346 : y = emit_move_change_mode (imode, mode, y, force);
4249 : 122346 : if (y == NULL_RTX)
4250 : : return NULL;
4251 : 122346 : return emit_insn (GEN_FCN (code) (x, y));
4252 : : }
4253 : :
4254 : : /* A subroutine of emit_move_insn_1. X is a push_operand in MODE.
4255 : : Return an equivalent MEM that does not use an auto-increment. */
4256 : :
4257 : : rtx
4258 : 3593 : emit_move_resolve_push (machine_mode mode, rtx x)
4259 : : {
4260 : 3593 : enum rtx_code code = GET_CODE (XEXP (x, 0));
4261 : 3593 : rtx temp;
4262 : :
4263 : 7186 : poly_int64 adjust = GET_MODE_SIZE (mode);
4264 : : #ifdef PUSH_ROUNDING
4265 : 3593 : adjust = PUSH_ROUNDING (adjust);
4266 : : #endif
4267 : 3593 : if (code == PRE_DEC || code == POST_DEC)
4268 : 3197 : adjust = -adjust;
4269 : 396 : else if (code == PRE_MODIFY || code == POST_MODIFY)
4270 : : {
4271 : 396 : rtx expr = XEXP (XEXP (x, 0), 1);
4272 : :
4273 : 396 : gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
4274 : 396 : poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
4275 : 396 : if (GET_CODE (expr) == MINUS)
4276 : 0 : val = -val;
4277 : 396 : gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
4278 : : adjust = val;
4279 : : }
4280 : :
4281 : : /* Do not use anti_adjust_stack, since we don't want to update
4282 : : stack_pointer_delta. */
4283 : 3597 : temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
4284 : 3593 : gen_int_mode (adjust, Pmode), stack_pointer_rtx,
4285 : : 0, OPTAB_LIB_WIDEN);
4286 : 3593 : if (temp != stack_pointer_rtx)
4287 : 0 : emit_move_insn (stack_pointer_rtx, temp);
4288 : :
4289 : 3593 : switch (code)
4290 : : {
4291 : 3593 : case PRE_INC:
4292 : 3593 : case PRE_DEC:
4293 : 3593 : case PRE_MODIFY:
4294 : 3593 : temp = stack_pointer_rtx;
4295 : 3593 : break;
4296 : : case POST_INC:
4297 : : case POST_DEC:
4298 : : case POST_MODIFY:
4299 : 0 : temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
4300 : 0 : break;
4301 : 0 : default:
4302 : 0 : gcc_unreachable ();
4303 : : }
4304 : :
4305 : 3593 : return replace_equiv_address (x, temp);
4306 : : }
4307 : :
4308 : : /* A subroutine of emit_move_complex. Generate a move from Y into X.
4309 : : X is known to satisfy push_operand, and MODE is known to be complex.
4310 : : Returns the last instruction emitted. */
4311 : :
4312 : : rtx_insn *
4313 : 5225 : emit_move_complex_push (machine_mode mode, rtx x, rtx y)
4314 : : {
4315 : 5225 : scalar_mode submode = GET_MODE_INNER (mode);
4316 : 5225 : bool imag_first;
4317 : :
4318 : : #ifdef PUSH_ROUNDING
4319 : 10450 : poly_int64 submodesize = GET_MODE_SIZE (submode);
4320 : :
4321 : : /* In case we output to the stack, but the size is smaller than the
4322 : : machine can push exactly, we need to use move instructions. */
4323 : 5225 : if (maybe_ne (PUSH_ROUNDING (submodesize), submodesize))
4324 : : {
4325 : 718 : x = emit_move_resolve_push (mode, x);
4326 : 718 : return emit_move_insn (x, y);
4327 : : }
4328 : : #endif
4329 : :
4330 : : /* Note that the real part always precedes the imag part in memory
4331 : : regardless of machine's endianness. */
4332 : 4507 : switch (GET_CODE (XEXP (x, 0)))
4333 : : {
4334 : : case PRE_DEC:
4335 : : case POST_DEC:
4336 : : imag_first = true;
4337 : : break;
4338 : 0 : case PRE_INC:
4339 : 0 : case POST_INC:
4340 : 0 : imag_first = false;
4341 : 0 : break;
4342 : 0 : default:
4343 : 0 : gcc_unreachable ();
4344 : : }
4345 : :
4346 : 4507 : emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4347 : : read_complex_part (y, imag_first));
4348 : 4507 : return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4349 : 9014 : read_complex_part (y, !imag_first));
4350 : : }
4351 : :
4352 : : /* A subroutine of emit_move_complex. Perform the move from Y to X
4353 : : via two moves of the parts. Returns the last instruction emitted. */
4354 : :
4355 : : rtx_insn *
4356 : 76755 : emit_move_complex_parts (rtx x, rtx y)
4357 : : {
4358 : : /* Show the output dies here. This is necessary for SUBREGs
4359 : : of pseudos since we cannot track their lifetimes correctly;
4360 : : hard regs shouldn't appear here except as return values. */
4361 : 76755 : if (!reload_completed && !reload_in_progress
4362 : 153510 : && REG_P (x) && !reg_overlap_mentioned_p (x, y))
4363 : 5577 : emit_clobber (x);
4364 : :
4365 : 76755 : write_complex_part (x, read_complex_part (y, false), false, true);
4366 : 76755 : write_complex_part (x, read_complex_part (y, true), true, false);
4367 : :
4368 : 76755 : return get_last_insn ();
4369 : : }
4370 : :
4371 : : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4372 : : MODE is known to be complex. Returns the last instruction emitted. */
4373 : :
4374 : : static rtx_insn *
4375 : 80977 : emit_move_complex (machine_mode mode, rtx x, rtx y)
4376 : : {
4377 : 80977 : bool try_int;
4378 : :
4379 : : /* Need to take special care for pushes, to maintain proper ordering
4380 : : of the data, and possibly extra padding. */
4381 : 80977 : if (push_operand (x, mode))
4382 : 4617 : return emit_move_complex_push (mode, x, y);
4383 : :
4384 : : /* See if we can coerce the target into moving both values at once, except
4385 : : for floating point where we favor moving as parts if this is easy. */
4386 : 76360 : if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
4387 : 68160 : && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
4388 : 68160 : && !(REG_P (x)
4389 : 1672 : && HARD_REGISTER_P (x)
4390 : 300 : && REG_NREGS (x) == 1)
4391 : 144520 : && !(REG_P (y)
4392 : 2748 : && HARD_REGISTER_P (y)
4393 : 1374 : && REG_NREGS (y) == 1))
4394 : : try_int = false;
4395 : : /* Not possible if the values are inherently not adjacent. */
4396 : 8200 : else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
4397 : : try_int = false;
4398 : : /* Is possible if both are registers (or subregs of registers). */
4399 : 754 : else if (register_operand (x, mode) && register_operand (y, mode))
4400 : : try_int = true;
4401 : : /* If one of the operands is a memory, and alignment constraints
4402 : : are friendly enough, we may be able to do combined memory operations.
4403 : : We do not attempt this if Y is a constant because that combination is
4404 : : usually better with the by-parts thing below. */
4405 : 633 : else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
4406 : : && (!STRICT_ALIGNMENT
4407 : : || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
4408 : : try_int = true;
4409 : : else
4410 : : try_int = false;
4411 : :
4412 : : if (try_int)
4413 : : {
4414 : 754 : rtx_insn *ret;
4415 : :
4416 : : /* For memory to memory moves, optimal behavior can be had with the
4417 : : existing block move logic. But use normal expansion if optimizing
4418 : : for size. */
4419 : 754 : if (MEM_P (x) && MEM_P (y))
4420 : : {
4421 : 724 : emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
4422 : 359 : (optimize_insn_for_speed_p()
4423 : : ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
4424 : 359 : return get_last_insn ();
4425 : : }
4426 : :
4427 : 395 : ret = emit_move_via_integer (mode, x, y, true);
4428 : 395 : if (ret)
4429 : : return ret;
4430 : : }
4431 : :
4432 : 75606 : return emit_move_complex_parts (x, y);
4433 : : }
4434 : :
4435 : : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4436 : : MODE is known to be MODE_CC. Returns the last instruction emitted. */
4437 : :
4438 : : static rtx_insn *
4439 : 0 : emit_move_ccmode (machine_mode mode, rtx x, rtx y)
4440 : : {
4441 : 0 : rtx_insn *ret;
4442 : :
4443 : : /* Assume all MODE_CC modes are equivalent; if we have movcc, use it. */
4444 : 0 : if (mode != CCmode)
4445 : : {
4446 : 0 : enum insn_code code = optab_handler (mov_optab, CCmode);
4447 : 0 : if (code != CODE_FOR_nothing)
4448 : : {
4449 : 0 : x = emit_move_change_mode (CCmode, mode, x, true);
4450 : 0 : y = emit_move_change_mode (CCmode, mode, y, true);
4451 : 0 : return emit_insn (GEN_FCN (code) (x, y));
4452 : : }
4453 : : }
4454 : :
4455 : : /* Otherwise, find the MODE_INT mode of the same width. */
4456 : 0 : ret = emit_move_via_integer (mode, x, y, false);
4457 : 0 : gcc_assert (ret != NULL);
4458 : : return ret;
4459 : : }
4460 : :
4461 : : /* Return true if word I of OP lies entirely in the
4462 : : undefined bits of a paradoxical subreg. */
4463 : :
4464 : : static bool
4465 : 0 : undefined_operand_subword_p (const_rtx op, int i)
4466 : : {
4467 : 0 : if (GET_CODE (op) != SUBREG)
4468 : : return false;
4469 : 0 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
4470 : 0 : poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
4471 : 0 : return (known_ge (offset, GET_MODE_SIZE (innermostmode))
4472 : 0 : || known_le (offset, -UNITS_PER_WORD));
4473 : : }
4474 : :
4475 : : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4476 : : MODE is any multi-word or full-word mode that lacks a move_insn
4477 : : pattern. Note that you will get better code if you define such
4478 : : patterns, even if they must turn into multiple assembler instructions. */
4479 : :
4480 : : static rtx_insn *
4481 : 0 : emit_move_multi_word (machine_mode mode, rtx x, rtx y)
4482 : : {
4483 : 0 : rtx_insn *last_insn = 0;
4484 : 0 : rtx_insn *seq;
4485 : 0 : rtx inner;
4486 : 0 : bool need_clobber;
4487 : 0 : int i, mode_size;
4488 : :
4489 : : /* This function can only handle cases where the number of words is
4490 : : known at compile time. */
4491 : 0 : mode_size = GET_MODE_SIZE (mode).to_constant ();
4492 : 0 : gcc_assert (mode_size >= UNITS_PER_WORD);
4493 : :
4494 : : /* If X is a push on the stack, do the push now and replace
4495 : : X with a reference to the stack pointer. */
4496 : 0 : if (push_operand (x, mode))
4497 : 0 : x = emit_move_resolve_push (mode, x);
4498 : :
4499 : : /* If we are in reload, see if either operand is a MEM whose address
4500 : : is scheduled for replacement. */
4501 : 0 : if (reload_in_progress && MEM_P (x)
4502 : 0 : && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
4503 : 0 : x = replace_equiv_address_nv (x, inner);
4504 : 0 : if (reload_in_progress && MEM_P (y)
4505 : 0 : && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
4506 : 0 : y = replace_equiv_address_nv (y, inner);
4507 : :
4508 : 0 : start_sequence ();
4509 : :
4510 : 0 : need_clobber = false;
4511 : 0 : for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
4512 : : {
4513 : : /* Do not generate code for a move if it would go entirely
4514 : : to the non-existing bits of a paradoxical subreg. */
4515 : 0 : if (undefined_operand_subword_p (x, i))
4516 : 0 : continue;
4517 : :
4518 : 0 : rtx xpart = operand_subword (x, i, 1, mode);
4519 : 0 : rtx ypart;
4520 : :
4521 : : /* Do not generate code for a move if it would come entirely
4522 : : from the undefined bits of a paradoxical subreg. */
4523 : 0 : if (undefined_operand_subword_p (y, i))
4524 : 0 : continue;
4525 : :
4526 : 0 : ypart = operand_subword (y, i, 1, mode);
4527 : :
4528 : : /* If we can't get a part of Y, put Y into memory if it is a
4529 : : constant. Otherwise, force it into a register. Then we must
4530 : : be able to get a part of Y. */
4531 : 0 : if (ypart == 0 && CONSTANT_P (y))
4532 : : {
4533 : 0 : y = use_anchored_address (force_const_mem (mode, y));
4534 : 0 : ypart = operand_subword (y, i, 1, mode);
4535 : : }
4536 : 0 : else if (ypart == 0)
4537 : 0 : ypart = operand_subword_force (y, i, mode);
4538 : :
4539 : 0 : gcc_assert (xpart && ypart);
4540 : :
4541 : 0 : need_clobber |= (GET_CODE (xpart) == SUBREG);
4542 : :
4543 : 0 : last_insn = emit_move_insn (xpart, ypart);
4544 : : }
4545 : :
4546 : 0 : seq = end_sequence ();
4547 : :
4548 : : /* Show the output dies here. This is necessary for SUBREGs
4549 : : of pseudos since we cannot track their lifetimes correctly;
4550 : : hard regs shouldn't appear here except as return values.
4551 : : We never want to emit such a clobber after reload. */
4552 : 0 : if (x != y
4553 : 0 : && ! (reload_in_progress || reload_completed)
4554 : 0 : && need_clobber != 0)
4555 : 0 : emit_clobber (x);
4556 : :
4557 : 0 : emit_insn (seq);
4558 : :
4559 : 0 : return last_insn;
4560 : : }
4561 : :
4562 : : /* Low level part of emit_move_insn.
4563 : : Called just like emit_move_insn, but assumes X and Y
4564 : : are basically valid. */
4565 : :
4566 : : rtx_insn *
4567 : 75274503 : emit_move_insn_1 (rtx x, rtx y)
4568 : : {
4569 : 75274503 : machine_mode mode = GET_MODE (x);
4570 : 75274503 : enum insn_code code;
4571 : :
4572 : 75274503 : gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
4573 : :
4574 : 75274503 : code = optab_handler (mov_optab, mode);
4575 : 75274503 : if (code != CODE_FOR_nothing)
4576 : 75071575 : return emit_insn (GEN_FCN (code) (x, y));
4577 : :
4578 : : /* Expand complex moves by moving real part and imag part. */
4579 : 202928 : if (COMPLEX_MODE_P (mode))
4580 : 80977 : return emit_move_complex (mode, x, y);
4581 : :
4582 : : if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
4583 : : || ALL_FIXED_POINT_MODE_P (mode))
4584 : : {
4585 : 121951 : rtx_insn *result = emit_move_via_integer (mode, x, y, true);
4586 : :
4587 : : /* If we can't find an integer mode, use multi words. */
4588 : 121951 : if (result)
4589 : : return result;
4590 : : else
4591 : 0 : return emit_move_multi_word (mode, x, y);
4592 : : }
4593 : :
4594 : : if (GET_MODE_CLASS (mode) == MODE_CC)
4595 : 0 : return emit_move_ccmode (mode, x, y);
4596 : :
4597 : : /* Try using a move pattern for the corresponding integer mode. This is
4598 : : only safe when simplify_subreg can convert MODE constants into integer
4599 : : constants. At present, it can only do this reliably if the value
4600 : : fits within a HOST_WIDE_INT. */
4601 : 0 : if (!CONSTANT_P (y)
4602 : 0 : || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
4603 : : {
4604 : 0 : rtx_insn *ret = emit_move_via_integer (mode, x, y, lra_in_progress);
4605 : :
4606 : 0 : if (ret)
4607 : : {
4608 : 0 : if (! lra_in_progress || recog (PATTERN (ret), ret, 0) >= 0)
4609 : 0 : return ret;
4610 : : }
4611 : : }
4612 : :
4613 : 0 : return emit_move_multi_word (mode, x, y);
4614 : : }
4615 : :
4616 : : /* Generate code to copy Y into X.
4617 : : Both Y and X must have the same mode, except that
4618 : : Y can be a constant with VOIDmode.
4619 : : This mode cannot be BLKmode; use emit_block_move for that.
4620 : :
4621 : : Return the last instruction emitted. */
4622 : :
4623 : : rtx_insn *
4624 : 69420987 : emit_move_insn (rtx x, rtx y)
4625 : : {
4626 : 69420987 : machine_mode mode = GET_MODE (x);
4627 : 69420987 : rtx y_cst = NULL_RTX;
4628 : 69420987 : rtx_insn *last_insn;
4629 : 69420987 : rtx set;
4630 : :
4631 : 69420987 : gcc_assert (mode != BLKmode
4632 : : && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
4633 : :
4634 : : /* If we have a copy that looks like one of the following patterns:
4635 : : (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
4636 : : (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
4637 : : (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
4638 : : (set (subreg:M1 (reg:M2 ...)) (constant C))
4639 : : where mode M1 is equal in size to M2, try to detect whether the
4640 : : mode change involves an implicit round trip through memory.
4641 : : If so, see if we can avoid that by removing the subregs and
4642 : : doing the move in mode M2 instead. */
4643 : :
4644 : 69420987 : rtx x_inner = NULL_RTX;
4645 : 69420987 : rtx y_inner = NULL_RTX;
4646 : :
4647 : 72115367 : auto candidate_subreg_p = [&](rtx subreg) {
4648 : 2694380 : return (REG_P (SUBREG_REG (subreg))
4649 : 8081400 : && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
4650 : : GET_MODE_SIZE (GET_MODE (subreg)))
4651 : 2994507 : && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg)))
4652 : 2694380 : != CODE_FOR_nothing);
4653 : : };
4654 : :
4655 : 69426736 : auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
4656 : 5749 : return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
4657 : 5749 : && !push_operand (mem, GET_MODE (mem))
4658 : : /* Not a candiate if innermode requires too much alignment. */
4659 : 11438 : && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
4660 : 252 : || targetm.slow_unaligned_access (GET_MODE (mem),
4661 : 126 : MEM_ALIGN (mem))
4662 : 252 : || !targetm.slow_unaligned_access (innermode,
4663 : 126 : MEM_ALIGN (mem))));
4664 : : };
4665 : :
4666 : 69420987 : if (SUBREG_P (x) && candidate_subreg_p (x))
4667 : 9446 : x_inner = SUBREG_REG (x);
4668 : :
4669 : 69420987 : if (SUBREG_P (y) && candidate_subreg_p (y))
4670 : 289350 : y_inner = SUBREG_REG (y);
4671 : :
4672 : 69420987 : if (x_inner != NULL_RTX
4673 : 69420987 : && y_inner != NULL_RTX
4674 : 1096 : && GET_MODE (x_inner) == GET_MODE (y_inner)
4675 : 69421676 : && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
4676 : : {
4677 : 689 : x = x_inner;
4678 : 689 : y = y_inner;
4679 : 689 : mode = GET_MODE (x_inner);
4680 : : }
4681 : 69420298 : else if (x_inner != NULL_RTX
4682 : 8757 : && MEM_P (y)
4683 : 69420602 : && candidate_mem_p (GET_MODE (x_inner), y))
4684 : : {
4685 : 304 : x = x_inner;
4686 : 304 : y = adjust_address (y, GET_MODE (x_inner), 0);
4687 : 304 : mode = GET_MODE (x_inner);
4688 : : }
4689 : 69419994 : else if (y_inner != NULL_RTX
4690 : 288661 : && MEM_P (x)
4691 : 69425439 : && candidate_mem_p (GET_MODE (y_inner), x))
4692 : : {
4693 : 5385 : x = adjust_address (x, GET_MODE (y_inner), 0);
4694 : 5385 : y = y_inner;
4695 : 5385 : mode = GET_MODE (y_inner);
4696 : : }
4697 : 69414609 : else if (x_inner != NULL_RTX
4698 : 8453 : && CONSTANT_P (y)
4699 : 451 : && !targetm.can_change_mode_class (GET_MODE (x_inner),
4700 : : mode, ALL_REGS)
4701 : 69415060 : && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
4702 : : {
4703 : 451 : x = x_inner;
4704 : 451 : y = y_inner;
4705 : 451 : mode = GET_MODE (x_inner);
4706 : : }
4707 : :
4708 : 69420987 : if (CONSTANT_P (y))
4709 : : {
4710 : 16306253 : if (optimize
4711 : 12821516 : && SCALAR_FLOAT_MODE_P (GET_MODE (x))
4712 : 17069396 : && (last_insn = compress_float_constant (x, y)))
4713 : : return last_insn;
4714 : :
4715 : 16237612 : y_cst = y;
4716 : :
4717 : 16237612 : if (!targetm.legitimate_constant_p (mode, y))
4718 : : {
4719 : 490333 : y = force_const_mem (mode, y);
4720 : :
4721 : : /* If the target's cannot_force_const_mem prevented the spill,
4722 : : assume that the target's move expanders will also take care
4723 : : of the non-legitimate constant. */
4724 : 490333 : if (!y)
4725 : : y = y_cst;
4726 : : else
4727 : 470606 : y = use_anchored_address (y);
4728 : : }
4729 : : }
4730 : :
4731 : : /* If X or Y are memory references, verify that their addresses are valid
4732 : : for the machine. */
4733 : 69352346 : if (MEM_P (x)
4734 : 84976765 : && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
4735 : 13394200 : MEM_ADDR_SPACE (x))
4736 : 2230386 : && ! push_operand (x, GET_MODE (x))))
4737 : 167 : x = validize_mem (x);
4738 : :
4739 : 69352346 : if (MEM_P (y)
4740 : 86783854 : && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
4741 : 17431508 : MEM_ADDR_SPACE (y)))
4742 : 9260 : y = validize_mem (y);
4743 : :
4744 : 69352346 : gcc_assert (mode != BLKmode);
4745 : :
4746 : 69352346 : last_insn = emit_move_insn_1 (x, y);
4747 : :
4748 : 16237612 : if (y_cst && REG_P (x)
4749 : 11990820 : && (set = single_set (last_insn)) != NULL_RTX
4750 : 11990820 : && SET_DEST (set) == x
4751 : 81328708 : && ! rtx_equal_p (y_cst, SET_SRC (set)))
4752 : 1209986 : set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
4753 : :
4754 : : return last_insn;
4755 : : }
4756 : :
4757 : : /* Generate the body of an instruction to copy Y into X.
4758 : : It may be a list of insns, if one insn isn't enough. */
4759 : :
4760 : : rtx_insn *
4761 : 5922077 : gen_move_insn (rtx x, rtx y)
4762 : : {
4763 : 5922077 : start_sequence ();
4764 : 5922077 : emit_move_insn_1 (x, y);
4765 : 5922077 : return end_sequence ();
4766 : : }
4767 : :
4768 : : /* If Y is representable exactly in a narrower mode, and the target can
4769 : : perform the extension directly from constant or memory, then emit the
4770 : : move as an extension. */
4771 : :
4772 : : static rtx_insn *
4773 : 763143 : compress_float_constant (rtx x, rtx y)
4774 : : {
4775 : 763143 : machine_mode dstmode = GET_MODE (x);
4776 : 763143 : machine_mode orig_srcmode = GET_MODE (y);
4777 : 763143 : machine_mode srcmode;
4778 : 763143 : const REAL_VALUE_TYPE *r;
4779 : 763143 : int oldcost, newcost;
4780 : 763143 : bool speed = optimize_insn_for_speed_p ();
4781 : :
4782 : 763143 : r = CONST_DOUBLE_REAL_VALUE (y);
4783 : :
4784 : 763143 : if (targetm.legitimate_constant_p (dstmode, y))
4785 : 761697 : oldcost = set_src_cost (y, orig_srcmode, speed);
4786 : : else
4787 : 1446 : oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
4788 : :
4789 : 2697803 : FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
4790 : : {
4791 : 2003301 : enum insn_code ic;
4792 : 2003301 : rtx trunc_y;
4793 : 2003301 : rtx_insn *last_insn;
4794 : :
4795 : : /* Skip if the target can't extend this way. */
4796 : 2003301 : ic = can_extend_p (dstmode, srcmode, 0);
4797 : 2003301 : if (ic == CODE_FOR_nothing)
4798 : 1594218 : continue;
4799 : :
4800 : : /* Skip if the narrowed value isn't exact. */
4801 : 409083 : if (! exact_real_truncate (srcmode, r))
4802 : 51768 : continue;
4803 : :
4804 : 357315 : trunc_y = const_double_from_real_value (*r, srcmode);
4805 : :
4806 : 357315 : if (targetm.legitimate_constant_p (srcmode, trunc_y))
4807 : : {
4808 : : /* Skip if the target needs extra instructions to perform
4809 : : the extension. */
4810 : 353009 : if (!insn_operand_matches (ic, 1, trunc_y))
4811 : 3352 : continue;
4812 : : /* This is valid, but may not be cheaper than the original. */
4813 : 349657 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4814 : : dstmode, speed);
4815 : 349657 : if (oldcost < newcost)
4816 : 281016 : continue;
4817 : : }
4818 : 4306 : else if (float_extend_from_mem[dstmode][srcmode])
4819 : : {
4820 : 0 : trunc_y = force_const_mem (srcmode, trunc_y);
4821 : : /* This is valid, but may not be cheaper than the original. */
4822 : 0 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4823 : : dstmode, speed);
4824 : 0 : if (oldcost < newcost)
4825 : 0 : continue;
4826 : 0 : trunc_y = validize_mem (trunc_y);
4827 : : }
4828 : : else
4829 : 4306 : continue;
4830 : :
4831 : : /* For CSE's benefit, force the compressed constant pool entry
4832 : : into a new pseudo. This constant may be used in different modes,
4833 : : and if not, combine will put things back together for us. */
4834 : 68641 : trunc_y = force_reg (srcmode, trunc_y);
4835 : :
4836 : : /* If x is a hard register, perform the extension into a pseudo,
4837 : : so that e.g. stack realignment code is aware of it. */
4838 : 68641 : rtx target = x;
4839 : 68641 : if (REG_P (x) && HARD_REGISTER_P (x))
4840 : 1 : target = gen_reg_rtx (dstmode);
4841 : :
4842 : 68641 : emit_unop_insn (ic, target, trunc_y, UNKNOWN);
4843 : 68641 : last_insn = get_last_insn ();
4844 : :
4845 : 68641 : if (REG_P (target))
4846 : 57707 : set_unique_reg_note (last_insn, REG_EQUAL, y);
4847 : :
4848 : 68641 : if (target != x)
4849 : 1 : return emit_move_insn (x, target);
4850 : : return last_insn;
4851 : : }
4852 : :
4853 : : return NULL;
4854 : : }
4855 : :
4856 : : /* Pushing data onto the stack. */
4857 : :
4858 : : /* Push a block of length SIZE (perhaps variable)
4859 : : and return an rtx to address the beginning of the block.
4860 : : The value may be virtual_outgoing_args_rtx.
4861 : :
4862 : : EXTRA is the number of bytes of padding to push in addition to SIZE.
4863 : : BELOW nonzero means this padding comes at low addresses;
4864 : : otherwise, the padding comes at high addresses. */
4865 : :
4866 : : rtx
4867 : 266651 : push_block (rtx size, poly_int64 extra, int below)
4868 : : {
4869 : 266651 : rtx temp;
4870 : :
4871 : 331700 : size = convert_modes (Pmode, ptr_mode, size, 1);
4872 : 266651 : if (CONSTANT_P (size))
4873 : 331700 : anti_adjust_stack (plus_constant (Pmode, size, extra));
4874 : 0 : else if (REG_P (size) && known_eq (extra, 0))
4875 : 0 : anti_adjust_stack (size);
4876 : : else
4877 : : {
4878 : 0 : temp = copy_to_mode_reg (Pmode, size);
4879 : 0 : if (maybe_ne (extra, 0))
4880 : 0 : temp = expand_binop (Pmode, add_optab, temp,
4881 : 0 : gen_int_mode (extra, Pmode),
4882 : : temp, 0, OPTAB_LIB_WIDEN);
4883 : 0 : anti_adjust_stack (temp);
4884 : : }
4885 : :
4886 : 266651 : if (STACK_GROWS_DOWNWARD)
4887 : : {
4888 : 266651 : temp = virtual_outgoing_args_rtx;
4889 : 266651 : if (maybe_ne (extra, 0) && below)
4890 : 0 : temp = plus_constant (Pmode, temp, extra);
4891 : : }
4892 : : else
4893 : : {
4894 : : poly_int64 csize;
4895 : : if (poly_int_rtx_p (size, &csize))
4896 : : temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
4897 : : -csize - (below ? 0 : extra));
4898 : : else if (maybe_ne (extra, 0) && !below)
4899 : : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4900 : : negate_rtx (Pmode, plus_constant (Pmode, size,
4901 : : extra)));
4902 : : else
4903 : : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4904 : : negate_rtx (Pmode, size));
4905 : : }
4906 : :
4907 : 266651 : return memory_address (NARROWEST_INT_MODE, temp);
4908 : : }
4909 : :
4910 : : /* A utility routine that returns the base of an auto-inc memory, or NULL. */
4911 : :
4912 : : static rtx
4913 : 2568468 : mem_autoinc_base (rtx mem)
4914 : : {
4915 : 0 : if (MEM_P (mem))
4916 : : {
4917 : 1566033 : rtx addr = XEXP (mem, 0);
4918 : 1566033 : if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
4919 : 1025987 : return XEXP (addr, 0);
4920 : : }
4921 : : return NULL;
4922 : : }
4923 : :
4924 : : /* A utility routine used here, in reload, and in try_split. The insns
4925 : : after PREV up to and including LAST are known to adjust the stack,
4926 : : with a final value of END_ARGS_SIZE. Iterate backward from LAST
4927 : : placing notes as appropriate. PREV may be NULL, indicating the
4928 : : entire insn sequence prior to LAST should be scanned.
4929 : :
4930 : : The set of allowed stack pointer modifications is small:
4931 : : (1) One or more auto-inc style memory references (aka pushes),
4932 : : (2) One or more addition/subtraction with the SP as destination,
4933 : : (3) A single move insn with the SP as destination,
4934 : : (4) A call_pop insn,
4935 : : (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
4936 : :
4937 : : Insns in the sequence that do not modify the SP are ignored,
4938 : : except for noreturn calls.
4939 : :
4940 : : The return value is the amount of adjustment that can be trivially
4941 : : verified, via immediate operand or auto-inc. If the adjustment
4942 : : cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN. */
4943 : :
4944 : : poly_int64
4945 : 4362914 : find_args_size_adjust (rtx_insn *insn)
4946 : : {
4947 : 4362914 : rtx dest, set, pat;
4948 : 4362914 : int i;
4949 : :
4950 : 4362914 : pat = PATTERN (insn);
4951 : 4362914 : set = NULL;
4952 : :
4953 : : /* Look for a call_pop pattern. */
4954 : 4362914 : if (CALL_P (insn))
4955 : : {
4956 : : /* We have to allow non-call_pop patterns for the case
4957 : : of emit_single_push_insn of a TLS address. */
4958 : 2727675 : if (GET_CODE (pat) != PARALLEL)
4959 : 2714001 : return 0;
4960 : :
4961 : : /* All call_pop have a stack pointer adjust in the parallel.
4962 : : The call itself is always first, and the stack adjust is
4963 : : usually last, so search from the end. */
4964 : 13674 : for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
4965 : : {
4966 : 13674 : set = XVECEXP (pat, 0, i);
4967 : 13674 : if (GET_CODE (set) != SET)
4968 : 0 : continue;
4969 : 13674 : dest = SET_DEST (set);
4970 : 13674 : if (dest == stack_pointer_rtx)
4971 : : break;
4972 : : }
4973 : : /* We'd better have found the stack pointer adjust. */
4974 : 13674 : if (i == 0)
4975 : 0 : return 0;
4976 : : /* Fall through to process the extracted SET and DEST
4977 : : as if it was a standalone insn. */
4978 : : }
4979 : 1635239 : else if (GET_CODE (pat) == SET)
4980 : : set = pat;
4981 : 248366 : else if ((set = single_set (insn)) != NULL)
4982 : : ;
4983 : 47672 : else if (GET_CODE (pat) == PARALLEL)
4984 : : {
4985 : : /* ??? Some older ports use a parallel with a stack adjust
4986 : : and a store for a PUSH_ROUNDING pattern, rather than a
4987 : : PRE/POST_MODIFY rtx. Don't force them to update yet... */
4988 : : /* ??? See h8300 and m68k, pushqi1. */
4989 : 0 : for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
4990 : : {
4991 : 0 : set = XVECEXP (pat, 0, i);
4992 : 0 : if (GET_CODE (set) != SET)
4993 : 0 : continue;
4994 : 0 : dest = SET_DEST (set);
4995 : 0 : if (dest == stack_pointer_rtx)
4996 : : break;
4997 : :
4998 : : /* We do not expect an auto-inc of the sp in the parallel. */
4999 : 0 : gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
5000 : 0 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5001 : : != stack_pointer_rtx);
5002 : : }
5003 : 0 : if (i < 0)
5004 : 0 : return 0;
5005 : : }
5006 : : else
5007 : 47672 : return 0;
5008 : :
5009 : 1601241 : dest = SET_DEST (set);
5010 : :
5011 : : /* Look for direct modifications of the stack pointer. */
5012 : 1601241 : if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
5013 : : {
5014 : : /* Look for a trivial adjustment, otherwise assume nothing. */
5015 : : /* Note that the SPU restore_stack_block pattern refers to
5016 : : the stack pointer in V4SImode. Consider that non-trivial. */
5017 : 317007 : poly_int64 offset;
5018 : 317007 : if (SCALAR_INT_MODE_P (GET_MODE (dest))
5019 : 317007 : && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
5020 : 314639 : return offset;
5021 : : /* ??? Reload can generate no-op moves, which will be cleaned
5022 : : up later. Recognize it and continue searching. */
5023 : 2368 : else if (rtx_equal_p (dest, SET_SRC (set)))
5024 : 0 : return 0;
5025 : : else
5026 : 2368 : return HOST_WIDE_INT_MIN;
5027 : : }
5028 : : else
5029 : : {
5030 : 1284234 : rtx mem, addr;
5031 : :
5032 : : /* Otherwise only think about autoinc patterns. */
5033 : 2324346 : if (mem_autoinc_base (dest) == stack_pointer_rtx)
5034 : : {
5035 : 917575 : mem = dest;
5036 : 1266910 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5037 : : != stack_pointer_rtx);
5038 : : }
5039 : 543245 : else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
5040 : : mem = SET_SRC (set);
5041 : : else
5042 : 258247 : return 0;
5043 : :
5044 : 1025987 : addr = XEXP (mem, 0);
5045 : 1025987 : switch (GET_CODE (addr))
5046 : : {
5047 : 108412 : case PRE_INC:
5048 : 108412 : case POST_INC:
5049 : 216824 : return GET_MODE_SIZE (GET_MODE (mem));
5050 : 899883 : case PRE_DEC:
5051 : 899883 : case POST_DEC:
5052 : 1799766 : return -GET_MODE_SIZE (GET_MODE (mem));
5053 : 17692 : case PRE_MODIFY:
5054 : 17692 : case POST_MODIFY:
5055 : 17692 : addr = XEXP (addr, 1);
5056 : 17692 : gcc_assert (GET_CODE (addr) == PLUS);
5057 : 17692 : gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
5058 : 17692 : return rtx_to_poly_int64 (XEXP (addr, 1));
5059 : 0 : default:
5060 : 0 : gcc_unreachable ();
5061 : : }
5062 : : }
5063 : : }
5064 : :
5065 : : poly_int64
5066 : 660494 : fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
5067 : : poly_int64 end_args_size)
5068 : : {
5069 : 660494 : poly_int64 args_size = end_args_size;
5070 : 660494 : bool saw_unknown = false;
5071 : 660494 : rtx_insn *insn;
5072 : :
5073 : 1888678 : for (insn = last; insn != prev; insn = PREV_INSN (insn))
5074 : : {
5075 : 1228184 : if (!NONDEBUG_INSN_P (insn))
5076 : 0 : continue;
5077 : :
5078 : : /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
5079 : : a call argument containing a TLS address that itself requires
5080 : : a call to __tls_get_addr. The handling of stack_pointer_delta
5081 : : in emit_single_push_insn is supposed to ensure that any such
5082 : : notes are already correct. */
5083 : 1228184 : rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
5084 : 1228184 : gcc_assert (!note || known_eq (args_size, get_args_size (note)));
5085 : :
5086 : 1228184 : poly_int64 this_delta = find_args_size_adjust (insn);
5087 : 1228184 : if (known_eq (this_delta, 0))
5088 : : {
5089 : 608109 : if (!CALL_P (insn)
5090 : 5 : || ACCUMULATE_OUTGOING_ARGS
5091 : 304062 : || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
5092 : 304052 : continue;
5093 : : }
5094 : :
5095 : 924132 : gcc_assert (!saw_unknown);
5096 : 924132 : if (known_eq (this_delta, HOST_WIDE_INT_MIN))
5097 : 2346 : saw_unknown = true;
5098 : :
5099 : 924132 : if (!note)
5100 : 924132 : add_args_size_note (insn, args_size);
5101 : : if (STACK_GROWS_DOWNWARD)
5102 : 924132 : this_delta = -poly_uint64 (this_delta);
5103 : :
5104 : 924132 : if (saw_unknown)
5105 : : args_size = HOST_WIDE_INT_MIN;
5106 : : else
5107 : 1228184 : args_size -= this_delta;
5108 : : }
5109 : :
5110 : 660494 : return args_size;
5111 : : }
5112 : :
5113 : : #ifdef PUSH_ROUNDING
5114 : : /* Emit single push insn. */
5115 : :
5116 : : static void
5117 : 1820352 : emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
5118 : : {
5119 : 1820352 : rtx dest_addr;
5120 : 3640704 : poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
5121 : 1820352 : rtx dest;
5122 : 1820352 : enum insn_code icode;
5123 : :
5124 : : /* If there is push pattern, use it. Otherwise try old way of throwing
5125 : : MEM representing push operation to move expander. */
5126 : 1820352 : icode = optab_handler (push_optab, mode);
5127 : 1820352 : if (icode != CODE_FOR_nothing)
5128 : : {
5129 : 0 : class expand_operand ops[1];
5130 : :
5131 : 0 : create_input_operand (&ops[0], x, mode);
5132 : 0 : if (maybe_expand_insn (icode, 1, ops))
5133 : 0 : return;
5134 : : }
5135 : 3640704 : if (known_eq (GET_MODE_SIZE (mode), rounded_size))
5136 : 3146473 : dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
5137 : : /* If we are to pad downward, adjust the stack pointer first and
5138 : : then store X into the stack location using an offset. This is
5139 : : because emit_move_insn does not know how to pad; it does not have
5140 : : access to type. */
5141 : 101559 : else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
5142 : : {
5143 : 0 : emit_move_insn (stack_pointer_rtx,
5144 : 0 : expand_binop (Pmode,
5145 : : STACK_GROWS_DOWNWARD ? sub_optab
5146 : : : add_optab,
5147 : : stack_pointer_rtx,
5148 : 0 : gen_int_mode (rounded_size, Pmode),
5149 : : NULL_RTX, 0, OPTAB_LIB_WIDEN));
5150 : :
5151 : 0 : poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
5152 : 0 : if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
5153 : : /* We have already decremented the stack pointer, so get the
5154 : : previous value. */
5155 : : offset += rounded_size;
5156 : :
5157 : 0 : if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
5158 : : /* We have already incremented the stack pointer, so get the
5159 : : previous value. */
5160 : : offset -= rounded_size;
5161 : :
5162 : 0 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
5163 : : }
5164 : : else
5165 : : {
5166 : : if (STACK_GROWS_DOWNWARD)
5167 : : /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
5168 : 102103 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
5169 : : else
5170 : : /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
5171 : : dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
5172 : :
5173 : 102103 : dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
5174 : : }
5175 : :
5176 : 1820352 : dest = gen_rtx_MEM (mode, dest_addr);
5177 : :
5178 : 1820352 : if (type != 0)
5179 : : {
5180 : 1820305 : set_mem_attributes (dest, type, 1);
5181 : :
5182 : 1820305 : if (cfun->tail_call_marked)
5183 : : /* Function incoming arguments may overlap with sibling call
5184 : : outgoing arguments and we cannot allow reordering of reads
5185 : : from function arguments with stores to outgoing arguments
5186 : : of sibling calls. */
5187 : 137413 : set_mem_alias_set (dest, 0);
5188 : : }
5189 : 1820352 : emit_move_insn (dest, x);
5190 : : }
5191 : :
5192 : : /* Emit and annotate a single push insn. */
5193 : :
5194 : : static void
5195 : 1820352 : emit_single_push_insn (machine_mode mode, rtx x, tree type)
5196 : : {
5197 : 1820352 : poly_int64 delta, old_delta = stack_pointer_delta;
5198 : 1820352 : rtx_insn *prev = get_last_insn ();
5199 : 1820352 : rtx_insn *last;
5200 : :
5201 : 1820352 : emit_single_push_insn_1 (mode, x, type);
5202 : :
5203 : : /* Adjust stack_pointer_delta to describe the situation after the push
5204 : : we just performed. Note that we must do this after the push rather
5205 : : than before the push in case calculating X needs pushes and pops of
5206 : : its own (e.g. if calling __tls_get_addr). The REG_ARGS_SIZE notes
5207 : : for such pushes and pops must not include the effect of the future
5208 : : push of X. */
5209 : 3640704 : stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
5210 : :
5211 : 1820352 : last = get_last_insn ();
5212 : :
5213 : : /* Notice the common case where we emitted exactly one insn. */
5214 : 1820352 : if (PREV_INSN (last) == prev)
5215 : : {
5216 : 1711571 : add_args_size_note (last, stack_pointer_delta);
5217 : 1711571 : return;
5218 : : }
5219 : :
5220 : 108781 : delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
5221 : 108781 : gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
5222 : : || known_eq (delta, old_delta));
5223 : : }
5224 : : #endif
5225 : :
5226 : : /* If reading SIZE bytes from X will end up reading from
5227 : : Y return the number of bytes that overlap. Return -1
5228 : : if there is no overlap or -2 if we can't determine
5229 : : (for example when X and Y have different base registers). */
5230 : :
5231 : : static int
5232 : 0 : memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
5233 : : {
5234 : 0 : rtx tmp = plus_constant (Pmode, x, size);
5235 : 0 : rtx sub = simplify_gen_binary (MINUS, Pmode, tmp, y);
5236 : :
5237 : 0 : if (!CONST_INT_P (sub))
5238 : : return -2;
5239 : :
5240 : 0 : HOST_WIDE_INT val = INTVAL (sub);
5241 : :
5242 : 0 : return IN_RANGE (val, 1, size) ? val : -1;
5243 : : }
5244 : :
5245 : : /* Generate code to push X onto the stack, assuming it has mode MODE and
5246 : : type TYPE.
5247 : : MODE is redundant except when X is a CONST_INT (since they don't
5248 : : carry mode info).
5249 : : SIZE is an rtx for the size of data to be copied (in bytes),
5250 : : needed only if X is BLKmode.
5251 : : Return true if successful. May return false if asked to push a
5252 : : partial argument during a sibcall optimization (as specified by
5253 : : SIBCALL_P) and the incoming and outgoing pointers cannot be shown
5254 : : to not overlap.
5255 : :
5256 : : ALIGN (in bits) is maximum alignment we can assume.
5257 : :
5258 : : If PARTIAL and REG are both nonzero, then copy that many of the first
5259 : : bytes of X into registers starting with REG, and push the rest of X.
5260 : : The amount of space pushed is decreased by PARTIAL bytes.
5261 : : REG must be a hard register in this case.
5262 : : If REG is zero but PARTIAL is not, take any all others actions for an
5263 : : argument partially in registers, but do not actually load any
5264 : : registers.
5265 : :
5266 : : EXTRA is the amount in bytes of extra space to leave next to this arg.
5267 : : This is ignored if an argument block has already been allocated.
5268 : :
5269 : : On a machine that lacks real push insns, ARGS_ADDR is the address of
5270 : : the bottom of the argument block for this call. We use indexing off there
5271 : : to store the arg. On machines with push insns, ARGS_ADDR is 0 when a
5272 : : argument block has not been preallocated.
5273 : :
5274 : : ARGS_SO_FAR is the size of args previously pushed for this call.
5275 : :
5276 : : REG_PARM_STACK_SPACE is nonzero if functions require stack space
5277 : : for arguments passed in registers. If nonzero, it will be the number
5278 : : of bytes required. */
5279 : :
5280 : : bool
5281 : 2141625 : emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
5282 : : unsigned int align, int partial, rtx reg, poly_int64 extra,
5283 : : rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
5284 : : rtx alignment_pad, bool sibcall_p)
5285 : : {
5286 : 2141625 : rtx xinner;
5287 : 2141625 : pad_direction stack_direction
5288 : : = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
5289 : :
5290 : : /* Decide where to pad the argument: PAD_DOWNWARD for below,
5291 : : PAD_UPWARD for above, or PAD_NONE for don't pad it.
5292 : : Default is below for small data on big-endian machines; else above. */
5293 : 2141625 : pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
5294 : :
5295 : : /* Invert direction if stack is post-decrement.
5296 : : FIXME: why? */
5297 : 2141625 : if (STACK_PUSH_CODE == POST_DEC)
5298 : : if (where_pad != PAD_NONE)
5299 : : where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
5300 : :
5301 : 2141625 : xinner = x;
5302 : :
5303 : 2141625 : int nregs = partial / UNITS_PER_WORD;
5304 : 2141625 : rtx *tmp_regs = NULL;
5305 : 2141625 : int overlapping = 0;
5306 : :
5307 : 2141625 : if (mode == BLKmode
5308 : : || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
5309 : : {
5310 : : /* Copy a block into the stack, entirely or partially. */
5311 : :
5312 : 266739 : rtx temp;
5313 : 266739 : int used;
5314 : 266739 : int offset;
5315 : 266739 : int skip;
5316 : :
5317 : 266739 : offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5318 : 266739 : used = partial - offset;
5319 : :
5320 : 266739 : if (mode != BLKmode)
5321 : : {
5322 : : /* A value is to be stored in an insufficiently aligned
5323 : : stack slot; copy via a suitably aligned slot if
5324 : : necessary. */
5325 : : size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
5326 : : if (!MEM_P (xinner))
5327 : : {
5328 : : temp = assign_temp (type, 1, 1);
5329 : : emit_move_insn (temp, xinner);
5330 : : xinner = temp;
5331 : : }
5332 : : }
5333 : :
5334 : 266739 : gcc_assert (size);
5335 : :
5336 : : /* USED is now the # of bytes we need not copy to the stack
5337 : : because registers will take care of them. */
5338 : :
5339 : 266739 : if (partial != 0)
5340 : 0 : xinner = adjust_address (xinner, BLKmode, used);
5341 : :
5342 : : /* If the partial register-part of the arg counts in its stack size,
5343 : : skip the part of stack space corresponding to the registers.
5344 : : Otherwise, start copying to the beginning of the stack space,
5345 : : by setting SKIP to 0. */
5346 : 266739 : skip = (reg_parm_stack_space == 0) ? 0 : used;
5347 : :
5348 : : #ifdef PUSH_ROUNDING
5349 : : /* NB: Let the backend known the number of bytes to push and
5350 : : decide if push insns should be generated. */
5351 : 266739 : unsigned int push_size;
5352 : 266739 : if (CONST_INT_P (size))
5353 : 266739 : push_size = INTVAL (size);
5354 : : else
5355 : : push_size = 0;
5356 : :
5357 : : /* Do it with several push insns if that doesn't take lots of insns
5358 : : and if there is no difficulty with push insns that skip bytes
5359 : : on the stack for alignment purposes. */
5360 : 266739 : if (args_addr == 0
5361 : 266694 : && targetm.calls.push_argument (push_size)
5362 : 3786 : && CONST_INT_P (size)
5363 : 3786 : && skip == 0
5364 : 3786 : && MEM_ALIGN (xinner) >= align
5365 : 2947 : && can_move_by_pieces ((unsigned) INTVAL (size) - used, align)
5366 : : /* Here we avoid the case of a structure whose weak alignment
5367 : : forces many pushes of a small amount of data,
5368 : : and such small pushes do rounding that causes trouble. */
5369 : 2947 : && ((!targetm.slow_unaligned_access (word_mode, align))
5370 : 0 : || align >= BIGGEST_ALIGNMENT
5371 : 0 : || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
5372 : : align / BITS_PER_UNIT))
5373 : 269686 : && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
5374 : : {
5375 : : /* Push padding now if padding above and stack grows down,
5376 : : or if padding below and stack grows up.
5377 : : But if space already allocated, this has already been done. */
5378 : 45 : if (maybe_ne (extra, 0)
5379 : : && args_addr == 0
5380 : 0 : && where_pad != PAD_NONE
5381 : 45 : && where_pad != stack_direction)
5382 : 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5383 : :
5384 : 45 : move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
5385 : : RETURN_BEGIN);
5386 : : }
5387 : : else
5388 : : #endif /* PUSH_ROUNDING */
5389 : : {
5390 : 266694 : rtx target;
5391 : :
5392 : : /* Otherwise make space on the stack and copy the data
5393 : : to the address of that space. */
5394 : :
5395 : : /* Deduct words put into registers from the size we must copy. */
5396 : 266694 : if (partial != 0)
5397 : : {
5398 : 0 : if (CONST_INT_P (size))
5399 : 0 : size = GEN_INT (INTVAL (size) - used);
5400 : : else
5401 : 0 : size = expand_binop (GET_MODE (size), sub_optab, size,
5402 : 0 : gen_int_mode (used, GET_MODE (size)),
5403 : : NULL_RTX, 0, OPTAB_LIB_WIDEN);
5404 : : }
5405 : :
5406 : : /* Get the address of the stack space.
5407 : : In this case, we do not deal with EXTRA separately.
5408 : : A single stack adjust will do. */
5409 : 266694 : poly_int64 const_args_so_far;
5410 : 266694 : if (! args_addr)
5411 : : {
5412 : 266649 : temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
5413 : 266649 : extra = 0;
5414 : : }
5415 : 45 : else if (poly_int_rtx_p (args_so_far, &const_args_so_far))
5416 : 63 : temp = memory_address (BLKmode,
5417 : : plus_constant (Pmode, args_addr,
5418 : : skip + const_args_so_far));
5419 : : else
5420 : 0 : temp = memory_address (BLKmode,
5421 : : plus_constant (Pmode,
5422 : : gen_rtx_PLUS (Pmode,
5423 : : args_addr,
5424 : : args_so_far),
5425 : : skip));
5426 : :
5427 : 266694 : if (!ACCUMULATE_OUTGOING_ARGS)
5428 : : {
5429 : : /* If the source is referenced relative to the stack pointer,
5430 : : copy it to another register to stabilize it. We do not need
5431 : : to do this if we know that we won't be changing sp. */
5432 : :
5433 : 266694 : if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
5434 : 266694 : || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
5435 : 266649 : temp = copy_to_reg (temp);
5436 : : }
5437 : :
5438 : 266694 : target = gen_rtx_MEM (BLKmode, temp);
5439 : :
5440 : : /* We do *not* set_mem_attributes here, because incoming arguments
5441 : : may overlap with sibling call outgoing arguments and we cannot
5442 : : allow reordering of reads from function arguments with stores
5443 : : to outgoing arguments of sibling calls. We do, however, want
5444 : : to record the alignment of the stack slot. */
5445 : : /* ALIGN may well be better aligned than TYPE, e.g. due to
5446 : : PARM_BOUNDARY. Assume the caller isn't lying. */
5447 : 266694 : set_mem_align (target, align);
5448 : :
5449 : : /* If part should go in registers and pushing to that part would
5450 : : overwrite some of the values that need to go into regs, load the
5451 : : overlapping values into temporary pseudos to be moved into the hard
5452 : : regs at the end after the stack pushing has completed.
5453 : : We cannot load them directly into the hard regs here because
5454 : : they can be clobbered by the block move expansions.
5455 : : See PR 65358. */
5456 : :
5457 : 266694 : if (partial > 0 && reg != 0 && mode == BLKmode
5458 : 0 : && GET_CODE (reg) != PARALLEL)
5459 : : {
5460 : 0 : overlapping = memory_load_overlap (XEXP (x, 0), temp, partial);
5461 : 0 : if (overlapping > 0)
5462 : : {
5463 : 0 : gcc_assert (overlapping % UNITS_PER_WORD == 0);
5464 : 0 : overlapping /= UNITS_PER_WORD;
5465 : :
5466 : 0 : tmp_regs = XALLOCAVEC (rtx, overlapping);
5467 : :
5468 : 0 : for (int i = 0; i < overlapping; i++)
5469 : 0 : tmp_regs[i] = gen_reg_rtx (word_mode);
5470 : :
5471 : 0 : for (int i = 0; i < overlapping; i++)
5472 : 0 : emit_move_insn (tmp_regs[i],
5473 : 0 : operand_subword_force (target, i, mode));
5474 : : }
5475 : 0 : else if (overlapping == -1)
5476 : : overlapping = 0;
5477 : : /* Could not determine whether there is overlap.
5478 : : Fail the sibcall. */
5479 : : else
5480 : : {
5481 : 0 : overlapping = 0;
5482 : 0 : if (sibcall_p)
5483 : 0 : return false;
5484 : : }
5485 : : }
5486 : :
5487 : : /* If source is a constant VAR_DECL with a simple constructor,
5488 : : store the constructor to the stack instead of moving it. */
5489 : 266694 : const_tree decl;
5490 : 266694 : HOST_WIDE_INT sz;
5491 : 266694 : if (partial == 0
5492 : 266694 : && MEM_P (xinner)
5493 : 266694 : && SYMBOL_REF_P (XEXP (xinner, 0))
5494 : 81742 : && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
5495 : 81742 : && VAR_P (decl)
5496 : 81742 : && TREE_READONLY (decl)
5497 : 4502 : && !TREE_SIDE_EFFECTS (decl)
5498 : 4502 : && immediate_const_ctor_p (DECL_INITIAL (decl), 2)
5499 : 6 : && (sz = int_expr_size (DECL_INITIAL (decl))) > 0
5500 : 6 : && CONST_INT_P (size)
5501 : 266700 : && INTVAL (size) == sz)
5502 : 0 : store_constructor (DECL_INITIAL (decl), target, 0, sz, false);
5503 : : else
5504 : 266694 : emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
5505 : : }
5506 : : }
5507 : 1874886 : else if (partial > 0)
5508 : : {
5509 : : /* Scalar partly in registers. This case is only supported
5510 : : for fixed-wdth modes. */
5511 : 0 : int num_words = GET_MODE_SIZE (mode).to_constant ();
5512 : 0 : num_words /= UNITS_PER_WORD;
5513 : 0 : int i;
5514 : 0 : int not_stack;
5515 : : /* # bytes of start of argument
5516 : : that we must make space for but need not store. */
5517 : 0 : int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5518 : 0 : int args_offset = INTVAL (args_so_far);
5519 : 0 : int skip;
5520 : :
5521 : : /* Push padding now if padding above and stack grows down,
5522 : : or if padding below and stack grows up.
5523 : : But if space already allocated, this has already been done. */
5524 : 0 : if (maybe_ne (extra, 0)
5525 : 0 : && args_addr == 0
5526 : 0 : && where_pad != PAD_NONE
5527 : 0 : && where_pad != stack_direction)
5528 : 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5529 : :
5530 : : /* If we make space by pushing it, we might as well push
5531 : : the real data. Otherwise, we can leave OFFSET nonzero
5532 : : and leave the space uninitialized. */
5533 : 0 : if (args_addr == 0)
5534 : 0 : offset = 0;
5535 : :
5536 : : /* Now NOT_STACK gets the number of words that we don't need to
5537 : : allocate on the stack. Convert OFFSET to words too. */
5538 : 0 : not_stack = (partial - offset) / UNITS_PER_WORD;
5539 : 0 : offset /= UNITS_PER_WORD;
5540 : :
5541 : : /* If the partial register-part of the arg counts in its stack size,
5542 : : skip the part of stack space corresponding to the registers.
5543 : : Otherwise, start copying to the beginning of the stack space,
5544 : : by setting SKIP to 0. */
5545 : 0 : skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
5546 : :
5547 : 0 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
5548 : 0 : x = validize_mem (force_const_mem (mode, x));
5549 : :
5550 : : /* If X is a hard register in a non-integer mode, copy it into a pseudo;
5551 : : SUBREGs of such registers are not allowed. */
5552 : 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
5553 : 0 : && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
5554 : 0 : x = copy_to_reg (x);
5555 : :
5556 : : /* Loop over all the words allocated on the stack for this arg. */
5557 : : /* We can do it by words, because any scalar bigger than a word
5558 : : has a size a multiple of a word. */
5559 : 0 : tree word_mode_type = lang_hooks.types.type_for_mode (word_mode, 1);
5560 : 0 : for (i = num_words - 1; i >= not_stack; i--)
5561 : 0 : if (i >= not_stack + offset)
5562 : 0 : if (!emit_push_insn (operand_subword_force (x, i, mode),
5563 : : word_mode, word_mode_type, NULL_RTX, align, 0,
5564 : : NULL_RTX, 0, args_addr,
5565 : 0 : GEN_INT (args_offset + ((i - not_stack + skip)
5566 : : * UNITS_PER_WORD)),
5567 : : reg_parm_stack_space, alignment_pad, sibcall_p))
5568 : 0 : return false;
5569 : : }
5570 : : else
5571 : : {
5572 : 1874886 : rtx addr;
5573 : 1874886 : rtx dest;
5574 : :
5575 : : /* Push padding now if padding above and stack grows down,
5576 : : or if padding below and stack grows up.
5577 : : But if space already allocated, this has already been done. */
5578 : 1874886 : if (maybe_ne (extra, 0)
5579 : 0 : && args_addr == 0
5580 : 0 : && where_pad != PAD_NONE
5581 : 1874886 : && where_pad != stack_direction)
5582 : 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5583 : :
5584 : : #ifdef PUSH_ROUNDING
5585 : 1874886 : if (args_addr == 0 && targetm.calls.push_argument (0))
5586 : 1820305 : emit_single_push_insn (mode, x, type);
5587 : : else
5588 : : #endif
5589 : : {
5590 : 62592 : addr = simplify_gen_binary (PLUS, Pmode, args_addr, args_so_far);
5591 : 54581 : dest = gen_rtx_MEM (mode, memory_address (mode, addr));
5592 : :
5593 : : /* We do *not* set_mem_attributes here, because incoming arguments
5594 : : may overlap with sibling call outgoing arguments and we cannot
5595 : : allow reordering of reads from function arguments with stores
5596 : : to outgoing arguments of sibling calls. We do, however, want
5597 : : to record the alignment of the stack slot. */
5598 : : /* ALIGN may well be better aligned than TYPE, e.g. due to
5599 : : PARM_BOUNDARY. Assume the caller isn't lying. */
5600 : 54581 : set_mem_align (dest, align);
5601 : :
5602 : 54581 : emit_move_insn (dest, x);
5603 : : }
5604 : : }
5605 : :
5606 : : /* Move the partial arguments into the registers and any overlapping
5607 : : values that we moved into the pseudos in tmp_regs. */
5608 : 2141625 : if (partial > 0 && reg != 0)
5609 : : {
5610 : : /* Handle calls that pass values in multiple non-contiguous locations.
5611 : : The Irix 6 ABI has examples of this. */
5612 : 0 : if (GET_CODE (reg) == PARALLEL)
5613 : 0 : emit_group_load (reg, x, type, -1);
5614 : : else
5615 : : {
5616 : 0 : gcc_assert (partial % UNITS_PER_WORD == 0);
5617 : 0 : move_block_to_reg (REGNO (reg), x, nregs - overlapping, mode);
5618 : :
5619 : 0 : for (int i = 0; i < overlapping; i++)
5620 : 0 : emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg)
5621 : 0 : + nregs - overlapping + i),
5622 : 0 : tmp_regs[i]);
5623 : :
5624 : : }
5625 : : }
5626 : :
5627 : 2141625 : if (maybe_ne (extra, 0) && args_addr == 0 && where_pad == stack_direction)
5628 : 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5629 : :
5630 : 2141625 : if (alignment_pad && args_addr == 0)
5631 : 2086999 : anti_adjust_stack (alignment_pad);
5632 : :
5633 : : return true;
5634 : : }
5635 : :
5636 : : /* Return X if X can be used as a subtarget in a sequence of arithmetic
5637 : : operations. */
5638 : :
5639 : : static rtx
5640 : 197948184 : get_subtarget (rtx x)
5641 : : {
5642 : 197948184 : return (optimize
5643 : 50895402 : || x == 0
5644 : : /* Only registers can be subtargets. */
5645 : 17064061 : || !REG_P (x)
5646 : : /* Don't use hard regs to avoid extending their life. */
5647 : 11624139 : || REGNO (x) < FIRST_PSEUDO_REGISTER
5648 : 197948184 : ? 0 : x);
5649 : : }
5650 : :
5651 : : /* A subroutine of expand_assignment. Optimize FIELD op= VAL, where
5652 : : FIELD is a bitfield. Returns true if the optimization was successful,
5653 : : and there's nothing else to do. */
5654 : :
5655 : : static bool
5656 : 4663055 : optimize_bitfield_assignment_op (poly_uint64 pbitsize,
5657 : : poly_uint64 pbitpos,
5658 : : poly_uint64 pbitregion_start,
5659 : : poly_uint64 pbitregion_end,
5660 : : machine_mode mode1, rtx str_rtx,
5661 : : tree to, tree src, bool reverse)
5662 : : {
5663 : : /* str_mode is not guaranteed to be a scalar type. */
5664 : 4663055 : machine_mode str_mode = GET_MODE (str_rtx);
5665 : 4663055 : unsigned int str_bitsize;
5666 : 4663055 : tree op0, op1;
5667 : 4663055 : rtx value, result;
5668 : 4663055 : optab binop;
5669 : 4663055 : gimple *srcstmt;
5670 : 4663055 : enum tree_code code;
5671 : :
5672 : 4663055 : unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
5673 : 4663055 : if (mode1 != VOIDmode
5674 : 68889 : || !pbitsize.is_constant (&bitsize)
5675 : 68889 : || !pbitpos.is_constant (&bitpos)
5676 : 68889 : || !pbitregion_start.is_constant (&bitregion_start)
5677 : 68889 : || !pbitregion_end.is_constant (&bitregion_end)
5678 : 69462 : || bitsize >= BITS_PER_WORD
5679 : 68620 : || !GET_MODE_BITSIZE (str_mode).is_constant (&str_bitsize)
5680 : 69193 : || str_bitsize > BITS_PER_WORD
5681 : 62980 : || TREE_SIDE_EFFECTS (to)
5682 : 4725920 : || TREE_THIS_VOLATILE (to))
5683 : : return false;
5684 : :
5685 : 62865 : STRIP_NOPS (src);
5686 : 62865 : if (TREE_CODE (src) != SSA_NAME)
5687 : : return false;
5688 : 21314 : if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
5689 : : return false;
5690 : :
5691 : 20131 : srcstmt = get_gimple_for_ssa_name (src);
5692 : 20131 : if (!srcstmt
5693 : 4285 : || !is_gimple_assign (srcstmt)
5694 : 24416 : || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
5695 : : return false;
5696 : :
5697 : 445 : code = gimple_assign_rhs_code (srcstmt);
5698 : :
5699 : 445 : op0 = gimple_assign_rhs1 (srcstmt);
5700 : :
5701 : : /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
5702 : : to find its initialization. Hopefully the initialization will
5703 : : be from a bitfield load. */
5704 : 445 : if (TREE_CODE (op0) == SSA_NAME)
5705 : : {
5706 : 445 : gimple *op0stmt = get_gimple_for_ssa_name (op0);
5707 : :
5708 : : /* We want to eventually have OP0 be the same as TO, which
5709 : : should be a bitfield. */
5710 : 445 : if (!op0stmt
5711 : 415 : || !is_gimple_assign (op0stmt)
5712 : 860 : || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
5713 : : return false;
5714 : 299 : op0 = gimple_assign_rhs1 (op0stmt);
5715 : : }
5716 : :
5717 : 299 : op1 = gimple_assign_rhs2 (srcstmt);
5718 : :
5719 : 299 : if (!operand_equal_p (to, op0, 0))
5720 : : return false;
5721 : :
5722 : 229 : if (MEM_P (str_rtx))
5723 : : {
5724 : 224 : unsigned HOST_WIDE_INT offset1;
5725 : :
5726 : 224 : if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
5727 : 4 : str_bitsize = BITS_PER_WORD;
5728 : :
5729 : 224 : scalar_int_mode best_mode;
5730 : 224 : if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
5731 : 224 : MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
5732 : 0 : return false;
5733 : 224 : str_mode = best_mode;
5734 : 224 : str_bitsize = GET_MODE_BITSIZE (best_mode);
5735 : :
5736 : 224 : offset1 = bitpos;
5737 : 224 : bitpos %= str_bitsize;
5738 : 224 : offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
5739 : 224 : str_rtx = adjust_address (str_rtx, str_mode, offset1);
5740 : : }
5741 : 5 : else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
5742 : : return false;
5743 : :
5744 : : /* If the bit field covers the whole REG/MEM, store_field
5745 : : will likely generate better code. */
5746 : 229 : if (bitsize >= str_bitsize)
5747 : : return false;
5748 : :
5749 : : /* We can't handle fields split across multiple entities. */
5750 : 229 : if (bitpos + bitsize > str_bitsize)
5751 : : return false;
5752 : :
5753 : 229 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
5754 : 0 : bitpos = str_bitsize - bitpos - bitsize;
5755 : :
5756 : 229 : switch (code)
5757 : : {
5758 : 141 : case PLUS_EXPR:
5759 : 141 : case MINUS_EXPR:
5760 : : /* For now, just optimize the case of the topmost bitfield
5761 : : where we don't need to do any masking and also
5762 : : 1 bit bitfields where xor can be used.
5763 : : We might win by one instruction for the other bitfields
5764 : : too if insv/extv instructions aren't used, so that
5765 : : can be added later. */
5766 : 141 : if ((reverse || bitpos + bitsize != str_bitsize)
5767 : 97 : && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
5768 : : break;
5769 : :
5770 : 70 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5771 : 70 : value = convert_modes (str_mode,
5772 : 70 : TYPE_MODE (TREE_TYPE (op1)), value,
5773 : 70 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5774 : :
5775 : : /* We may be accessing data outside the field, which means
5776 : : we can alias adjacent data. */
5777 : 70 : if (MEM_P (str_rtx))
5778 : : {
5779 : 70 : str_rtx = shallow_copy_rtx (str_rtx);
5780 : 70 : set_mem_alias_set (str_rtx, 0);
5781 : 70 : set_mem_expr (str_rtx, 0);
5782 : : }
5783 : :
5784 : 70 : if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
5785 : : {
5786 : 26 : value = expand_and (str_mode, value, const1_rtx, NULL);
5787 : 26 : binop = xor_optab;
5788 : : }
5789 : : else
5790 : 44 : binop = code == PLUS_EXPR ? add_optab : sub_optab;
5791 : :
5792 : 70 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5793 : 70 : if (reverse)
5794 : 0 : value = flip_storage_order (str_mode, value);
5795 : 70 : result = expand_binop (str_mode, binop, str_rtx,
5796 : : value, str_rtx, 1, OPTAB_WIDEN);
5797 : 70 : if (result != str_rtx)
5798 : 0 : emit_move_insn (str_rtx, result);
5799 : : return true;
5800 : :
5801 : 58 : case BIT_IOR_EXPR:
5802 : 58 : case BIT_XOR_EXPR:
5803 : 58 : if (TREE_CODE (op1) != INTEGER_CST)
5804 : : break;
5805 : 55 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5806 : 55 : value = convert_modes (str_mode,
5807 : 55 : TYPE_MODE (TREE_TYPE (op1)), value,
5808 : 55 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5809 : :
5810 : : /* We may be accessing data outside the field, which means
5811 : : we can alias adjacent data. */
5812 : 55 : if (MEM_P (str_rtx))
5813 : : {
5814 : 55 : str_rtx = shallow_copy_rtx (str_rtx);
5815 : 55 : set_mem_alias_set (str_rtx, 0);
5816 : 55 : set_mem_expr (str_rtx, 0);
5817 : : }
5818 : :
5819 : 55 : binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
5820 : 55 : if (bitpos + bitsize != str_bitsize)
5821 : : {
5822 : 31 : rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
5823 : : str_mode);
5824 : 31 : value = expand_and (str_mode, value, mask, NULL_RTX);
5825 : : }
5826 : 55 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5827 : 55 : if (reverse)
5828 : 0 : value = flip_storage_order (str_mode, value);
5829 : 55 : result = expand_binop (str_mode, binop, str_rtx,
5830 : : value, str_rtx, 1, OPTAB_WIDEN);
5831 : 55 : if (result != str_rtx)
5832 : 0 : emit_move_insn (str_rtx, result);
5833 : : return true;
5834 : :
5835 : : default:
5836 : : break;
5837 : : }
5838 : :
5839 : : return false;
5840 : : }
5841 : :
5842 : : /* In the C++ memory model, consecutive bit fields in a structure are
5843 : : considered one memory location.
5844 : :
5845 : : Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
5846 : : returns the bit range of consecutive bits in which this COMPONENT_REF
5847 : : belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
5848 : : and *OFFSET may be adjusted in the process.
5849 : :
5850 : : If the access does not need to be restricted, 0 is returned in both
5851 : : *BITSTART and *BITEND. */
5852 : :
5853 : : void
5854 : 906230 : get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
5855 : : poly_int64 *bitpos, tree *offset)
5856 : : {
5857 : 906230 : poly_int64 bitoffset;
5858 : 906230 : tree field, repr;
5859 : :
5860 : 906230 : gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
5861 : :
5862 : 906230 : field = TREE_OPERAND (exp, 1);
5863 : 906230 : repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
5864 : : /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
5865 : : need to limit the range we can access. */
5866 : 906230 : if (!repr)
5867 : : {
5868 : 11617 : *bitstart = *bitend = 0;
5869 : 11617 : return;
5870 : : }
5871 : :
5872 : : /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
5873 : : part of a larger bit field, then the representative does not serve any
5874 : : useful purpose. This can occur in Ada. */
5875 : 894613 : if (handled_component_p (TREE_OPERAND (exp, 0)))
5876 : : {
5877 : 667529 : machine_mode rmode;
5878 : 667529 : poly_int64 rbitsize, rbitpos;
5879 : 667529 : tree roffset;
5880 : 667529 : int unsignedp, reversep, volatilep = 0;
5881 : 667529 : get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
5882 : : &roffset, &rmode, &unsignedp, &reversep,
5883 : : &volatilep);
5884 : 1335058 : if (!multiple_p (rbitpos, BITS_PER_UNIT))
5885 : : {
5886 : 0 : *bitstart = *bitend = 0;
5887 : 0 : return;
5888 : : }
5889 : : }
5890 : :
5891 : : /* Compute the adjustment to bitpos from the offset of the field
5892 : : relative to the representative. DECL_FIELD_OFFSET of field and
5893 : : repr are the same by construction if they are not constants,
5894 : : see finish_bitfield_layout. */
5895 : 894613 : poly_uint64 field_offset, repr_offset;
5896 : 894613 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
5897 : 1789221 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
5898 : 894608 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
5899 : : else
5900 : : bitoffset = 0;
5901 : 894613 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
5902 : 894613 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
5903 : :
5904 : : /* If the adjustment is larger than bitpos, we would have a negative bit
5905 : : position for the lower bound and this may wreak havoc later. Adjust
5906 : : offset and bitpos to make the lower bound non-negative in that case. */
5907 : 894613 : if (maybe_gt (bitoffset, *bitpos))
5908 : : {
5909 : 11 : poly_int64 adjust_bits = upper_bound (bitoffset, *bitpos) - *bitpos;
5910 : 11 : poly_int64 adjust_bytes = exact_div (adjust_bits, BITS_PER_UNIT);
5911 : :
5912 : 11 : *bitpos += adjust_bits;
5913 : 11 : if (*offset == NULL_TREE)
5914 : 5 : *offset = size_int (-adjust_bytes);
5915 : : else
5916 : 6 : *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
5917 : 11 : *bitstart = 0;
5918 : : }
5919 : : else
5920 : 894602 : *bitstart = *bitpos - bitoffset;
5921 : :
5922 : 894613 : *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
5923 : : }
5924 : :
5925 : : /* Returns true if BASE is a DECL that does not reside in memory and
5926 : : has non-BLKmode. DECL_RTL must not be a MEM; if
5927 : : DECL_RTL was not set yet, return false. */
5928 : :
5929 : : bool
5930 : 5322979 : non_mem_decl_p (tree base)
5931 : : {
5932 : 5322979 : if (!DECL_P (base)
5933 : 5322658 : || TREE_ADDRESSABLE (base)
5934 : 7856071 : || DECL_MODE (base) == BLKmode)
5935 : : return false;
5936 : :
5937 : 1653315 : if (!DECL_RTL_SET_P (base))
5938 : : return false;
5939 : :
5940 : 1536788 : return (!MEM_P (DECL_RTL (base)));
5941 : : }
5942 : :
5943 : : /* Returns true if REF refers to an object that does not
5944 : : reside in memory and has non-BLKmode. */
5945 : :
5946 : : bool
5947 : 11590095 : mem_ref_refers_to_non_mem_p (tree ref)
5948 : : {
5949 : 11590095 : tree base;
5950 : :
5951 : 11590095 : if (TREE_CODE (ref) == MEM_REF
5952 : 11590095 : || TREE_CODE (ref) == TARGET_MEM_REF)
5953 : : {
5954 : 10032743 : tree addr = TREE_OPERAND (ref, 0);
5955 : :
5956 : 10032743 : if (TREE_CODE (addr) != ADDR_EXPR)
5957 : : return false;
5958 : :
5959 : 3765442 : base = TREE_OPERAND (addr, 0);
5960 : : }
5961 : : else
5962 : : base = ref;
5963 : :
5964 : 5322794 : return non_mem_decl_p (base);
5965 : : }
5966 : :
5967 : : /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL
5968 : : is true, try generating a nontemporal store. */
5969 : :
5970 : : void
5971 : 18145448 : expand_assignment (tree to, tree from, bool nontemporal)
5972 : : {
5973 : 18145448 : rtx to_rtx = 0;
5974 : 18145448 : rtx result;
5975 : 18145448 : machine_mode mode;
5976 : 18145448 : unsigned int align;
5977 : 18145448 : enum insn_code icode;
5978 : :
5979 : : /* Don't crash if the lhs of the assignment was erroneous. */
5980 : 18145448 : if (TREE_CODE (to) == ERROR_MARK)
5981 : : {
5982 : 0 : expand_normal (from);
5983 : 0 : return;
5984 : : }
5985 : :
5986 : : /* Optimize away no-op moves without side-effects. */
5987 : 18145448 : if (operand_equal_p (to, from, 0))
5988 : : return;
5989 : :
5990 : : /* Handle misaligned stores. */
5991 : 18145301 : mode = TYPE_MODE (TREE_TYPE (to));
5992 : 18145301 : if ((TREE_CODE (to) == MEM_REF
5993 : 18145301 : || TREE_CODE (to) == TARGET_MEM_REF
5994 : 16038707 : || DECL_P (to))
5995 : 4055974 : && mode != BLKmode
5996 : 3554796 : && !mem_ref_refers_to_non_mem_p (to)
5997 : 6196594 : && ((align = get_object_alignment (to))
5998 : 3098297 : < GET_MODE_ALIGNMENT (mode))
5999 : 18566173 : && (((icode = optab_handler (movmisalign_optab, mode))
6000 : : != CODE_FOR_nothing)
6001 : 97834 : || targetm.slow_unaligned_access (mode, align)))
6002 : : {
6003 : 323038 : rtx reg, mem;
6004 : :
6005 : 323038 : reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6006 : : /* Handle PARALLEL. */
6007 : 323038 : reg = maybe_emit_group_store (reg, TREE_TYPE (from));
6008 : 323038 : reg = force_not_mem (reg);
6009 : 323038 : mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6010 : 323038 : if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
6011 : 0 : reg = flip_storage_order (mode, reg);
6012 : :
6013 : 323038 : if (icode != CODE_FOR_nothing)
6014 : : {
6015 : 323038 : class expand_operand ops[2];
6016 : :
6017 : 323038 : create_fixed_operand (&ops[0], mem);
6018 : 323038 : create_input_operand (&ops[1], reg, mode);
6019 : : /* The movmisalign<mode> pattern cannot fail, else the assignment
6020 : : would silently be omitted. */
6021 : 323038 : expand_insn (icode, 2, ops);
6022 : : }
6023 : : else
6024 : 0 : store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
6025 : : false, false);
6026 : 323038 : return;
6027 : : }
6028 : :
6029 : : /* Assignment of a structure component needs special treatment
6030 : : if the structure component's rtx is not simply a MEM.
6031 : : Assignment of an array element at a constant index, and assignment of
6032 : : an array element in an unaligned packed structure field, has the same
6033 : : problem. Same for (partially) storing into a non-memory object. */
6034 : 17822263 : if (handled_component_p (to)
6035 : 13400128 : || (TREE_CODE (to) == MEM_REF
6036 : 1555856 : && (REF_REVERSE_STORAGE_ORDER (to)
6037 : 1555840 : || mem_ref_refers_to_non_mem_p (to)))
6038 : 13278573 : || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
6039 : : {
6040 : 4663203 : machine_mode mode1;
6041 : 4663203 : poly_int64 bitsize, bitpos;
6042 : 4663203 : poly_uint64 bitregion_start = 0;
6043 : 4663203 : poly_uint64 bitregion_end = 0;
6044 : 4663203 : tree offset;
6045 : 4663203 : int unsignedp, reversep, volatilep = 0;
6046 : 4663203 : tree tem;
6047 : :
6048 : 4663203 : push_temp_slots ();
6049 : 4663203 : tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
6050 : : &unsignedp, &reversep, &volatilep);
6051 : :
6052 : : /* Make sure bitpos is not negative, it can wreak havoc later. */
6053 : 4663203 : if (maybe_lt (bitpos, 0))
6054 : : {
6055 : 266 : gcc_assert (offset == NULL_TREE);
6056 : 266 : offset = size_int (bits_to_bytes_round_down (bitpos));
6057 : 266 : bitpos = num_trailing_bits (bitpos);
6058 : : }
6059 : :
6060 : 4663203 : if (TREE_CODE (to) == COMPONENT_REF
6061 : 4663203 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
6062 : 85518 : get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
6063 : : /* The C++ memory model naturally applies to byte-aligned fields.
6064 : : However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
6065 : : BITSIZE are not byte-aligned, there is no need to limit the range
6066 : : we can access. This can occur with packed structures in Ada. */
6067 : 4577685 : else if (maybe_gt (bitsize, 0)
6068 : 4577670 : && multiple_p (bitsize, BITS_PER_UNIT)
6069 : 9155097 : && multiple_p (bitpos, BITS_PER_UNIT))
6070 : : {
6071 : 4577412 : bitregion_start = bitpos;
6072 : 4577412 : bitregion_end = bitpos + bitsize - 1;
6073 : : }
6074 : :
6075 : 4663203 : to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
6076 : :
6077 : : /* If the field has a mode, we want to access it in the
6078 : : field's mode, not the computed mode.
6079 : : If a MEM has VOIDmode (external with incomplete type),
6080 : : use BLKmode for it instead. */
6081 : 4663203 : if (MEM_P (to_rtx))
6082 : : {
6083 : 3953863 : if (mode1 != VOIDmode)
6084 : 3885686 : to_rtx = adjust_address (to_rtx, mode1, 0);
6085 : 68177 : else if (GET_MODE (to_rtx) == VOIDmode)
6086 : 0 : to_rtx = adjust_address (to_rtx, BLKmode, 0);
6087 : : }
6088 : :
6089 : 4663203 : rtx stemp = NULL_RTX, old_to_rtx = NULL_RTX;
6090 : 4663203 : if (offset != 0)
6091 : : {
6092 : 172087 : machine_mode address_mode;
6093 : 172087 : rtx offset_rtx;
6094 : :
6095 : 172087 : if (!MEM_P (to_rtx))
6096 : : {
6097 : : /* We can get constant negative offsets into arrays with broken
6098 : : user code. Translate this to a trap instead of ICEing. */
6099 : 4 : if (TREE_CODE (offset) == INTEGER_CST)
6100 : : {
6101 : 1 : expand_builtin_trap ();
6102 : 1 : to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
6103 : : }
6104 : : /* Else spill for variable offset to the destination. We expect
6105 : : to run into this only for hard registers. */
6106 : : else
6107 : : {
6108 : 3 : gcc_assert (VAR_P (tem) && DECL_HARD_REGISTER (tem));
6109 : 3 : stemp = assign_stack_temp (GET_MODE (to_rtx),
6110 : 6 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6111 : 3 : emit_move_insn (stemp, to_rtx);
6112 : 3 : old_to_rtx = to_rtx;
6113 : 3 : to_rtx = stemp;
6114 : : }
6115 : : }
6116 : :
6117 : 172087 : offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
6118 : 172087 : address_mode = get_address_mode (to_rtx);
6119 : 172087 : if (GET_MODE (offset_rtx) != address_mode)
6120 : : {
6121 : : /* We cannot be sure that the RTL in offset_rtx is valid outside
6122 : : of a memory address context, so force it into a register
6123 : : before attempting to convert it to the desired mode. */
6124 : 290 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
6125 : 290 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
6126 : : }
6127 : :
6128 : : /* If we have an expression in OFFSET_RTX and a non-zero
6129 : : byte offset in BITPOS, adding the byte offset before the
6130 : : OFFSET_RTX results in better intermediate code, which makes
6131 : : later rtl optimization passes perform better.
6132 : :
6133 : : We prefer intermediate code like this:
6134 : :
6135 : : r124:DI=r123:DI+0x18
6136 : : [r124:DI]=r121:DI
6137 : :
6138 : : ... instead of ...
6139 : :
6140 : : r124:DI=r123:DI+0x10
6141 : : [r124:DI+0x8]=r121:DI
6142 : :
6143 : : This is only done for aligned data values, as these can
6144 : : be expected to result in single move instructions. */
6145 : 172087 : poly_int64 bytepos;
6146 : 172087 : if (mode1 != VOIDmode
6147 : 171981 : && maybe_ne (bitpos, 0)
6148 : 45246 : && maybe_gt (bitsize, 0)
6149 : 217333 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
6150 : 217280 : && multiple_p (bitpos, bitsize)
6151 : 90386 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
6152 : 217280 : && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
6153 : : {
6154 : 45178 : to_rtx = adjust_address (to_rtx, mode1, bytepos);
6155 : 45178 : bitregion_start = 0;
6156 : 45178 : if (known_ge (bitregion_end, poly_uint64 (bitpos)))
6157 : 45178 : bitregion_end -= bitpos;
6158 : 45178 : bitpos = 0;
6159 : : }
6160 : :
6161 : 172087 : to_rtx = offset_address (to_rtx, offset_rtx,
6162 : : highest_pow2_factor_for_target (to,
6163 : : offset));
6164 : : }
6165 : :
6166 : : /* No action is needed if the target is not a memory and the field
6167 : : lies completely outside that target. This can occur if the source
6168 : : code contains an out-of-bounds access to a small array. */
6169 : 4663203 : if (!MEM_P (to_rtx)
6170 : 709336 : && GET_MODE (to_rtx) != BLKmode
6171 : 5372539 : && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
6172 : : {
6173 : 3 : expand_normal (from);
6174 : 3 : result = NULL;
6175 : : }
6176 : : /* Handle expand_expr of a complex value returning a CONCAT. */
6177 : 4663200 : else if (GET_CODE (to_rtx) == CONCAT)
6178 : : {
6179 : 139 : machine_mode to_mode = GET_MODE (to_rtx);
6180 : 139 : gcc_checking_assert (COMPLEX_MODE_P (to_mode));
6181 : 278 : poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode);
6182 : 139 : unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
6183 : 139 : if (TYPE_MODE (TREE_TYPE (from)) == to_mode
6184 : 6 : && known_eq (bitpos, 0)
6185 : 145 : && known_eq (bitsize, mode_bitsize))
6186 : 6 : result = store_expr (from, to_rtx, false, nontemporal, reversep);
6187 : 133 : else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
6188 : 86 : && known_eq (bitsize, inner_bitsize)
6189 : 219 : && (known_eq (bitpos, 0)
6190 : 33 : || known_eq (bitpos, inner_bitsize)))
6191 : 86 : result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
6192 : : false, nontemporal, reversep);
6193 : 47 : else if (known_le (bitpos + bitsize, inner_bitsize))
6194 : 5 : result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
6195 : : bitregion_start, bitregion_end,
6196 : : mode1, from, get_alias_set (to),
6197 : : nontemporal, reversep);
6198 : 42 : else if (known_ge (bitpos, inner_bitsize))
6199 : 3 : result = store_field (XEXP (to_rtx, 1), bitsize,
6200 : : bitpos - inner_bitsize,
6201 : : bitregion_start, bitregion_end,
6202 : : mode1, from, get_alias_set (to),
6203 : : nontemporal, reversep);
6204 : 39 : else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
6205 : : {
6206 : 32 : result = expand_normal (from);
6207 : 32 : if (GET_CODE (result) == CONCAT)
6208 : : {
6209 : 0 : to_mode = GET_MODE_INNER (to_mode);
6210 : 0 : machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
6211 : 0 : rtx from_real
6212 : 0 : = force_subreg (to_mode, XEXP (result, 0), from_mode, 0);
6213 : 0 : rtx from_imag
6214 : 0 : = force_subreg (to_mode, XEXP (result, 1), from_mode, 0);
6215 : 0 : if (!from_real || !from_imag)
6216 : 0 : goto concat_store_slow;
6217 : 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6218 : 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6219 : : }
6220 : : else
6221 : : {
6222 : 32 : machine_mode from_mode
6223 : 32 : = GET_MODE (result) == VOIDmode
6224 : 32 : ? TYPE_MODE (TREE_TYPE (from))
6225 : 32 : : GET_MODE (result);
6226 : 32 : rtx from_rtx;
6227 : 32 : if (MEM_P (result))
6228 : 1 : from_rtx = change_address (result, to_mode, NULL_RTX);
6229 : : else
6230 : 31 : from_rtx = force_subreg (to_mode, result, from_mode, 0);
6231 : 32 : if (from_rtx)
6232 : : {
6233 : 32 : emit_move_insn (XEXP (to_rtx, 0),
6234 : : read_complex_part (from_rtx, false));
6235 : 32 : emit_move_insn (XEXP (to_rtx, 1),
6236 : : read_complex_part (from_rtx, true));
6237 : : }
6238 : : else
6239 : : {
6240 : 0 : to_mode = GET_MODE_INNER (to_mode);
6241 : 0 : rtx from_real
6242 : 0 : = force_subreg (to_mode, result, from_mode, 0);
6243 : 0 : rtx from_imag
6244 : 0 : = force_subreg (to_mode, result, from_mode,
6245 : 0 : GET_MODE_SIZE (to_mode));
6246 : 0 : if (!from_real || !from_imag)
6247 : 0 : goto concat_store_slow;
6248 : 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6249 : 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6250 : : }
6251 : : }
6252 : : }
6253 : : else
6254 : : {
6255 : 7 : concat_store_slow:;
6256 : 7 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6257 : 14 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6258 : 7 : write_complex_part (temp, XEXP (to_rtx, 0), false, true);
6259 : 7 : write_complex_part (temp, XEXP (to_rtx, 1), true, false);
6260 : 7 : result = store_field (temp, bitsize, bitpos,
6261 : : bitregion_start, bitregion_end,
6262 : : mode1, from, get_alias_set (to),
6263 : : nontemporal, reversep);
6264 : 7 : emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
6265 : 7 : emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
6266 : : }
6267 : : }
6268 : : /* For calls to functions returning variable length structures, if TO_RTX
6269 : : is not a MEM, go through a MEM because we must not create temporaries
6270 : : of the VLA type. */
6271 : 4663061 : else if (!MEM_P (to_rtx)
6272 : 709194 : && TREE_CODE (from) == CALL_EXPR
6273 : 1317 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6274 : 4664378 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
6275 : : {
6276 : 6 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6277 : 12 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6278 : 6 : result = store_field (temp, bitsize, bitpos, bitregion_start,
6279 : : bitregion_end, mode1, from, get_alias_set (to),
6280 : : nontemporal, reversep);
6281 : 6 : emit_move_insn (to_rtx, temp);
6282 : : }
6283 : : else
6284 : : {
6285 : 4663055 : if (MEM_P (to_rtx))
6286 : : {
6287 : : /* If the field is at offset zero, we could have been given the
6288 : : DECL_RTX of the parent struct. Don't munge it. */
6289 : 3953867 : to_rtx = shallow_copy_rtx (to_rtx);
6290 : 3953867 : set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
6291 : 3953867 : if (volatilep)
6292 : 8688 : MEM_VOLATILE_P (to_rtx) = 1;
6293 : : }
6294 : :
6295 : 4663055 : gcc_checking_assert (known_ge (bitpos, 0));
6296 : 4663055 : if (optimize_bitfield_assignment_op (bitsize, bitpos,
6297 : : bitregion_start, bitregion_end,
6298 : : mode1, to_rtx, to, from,
6299 : : reversep))
6300 : : result = NULL;
6301 : 4662930 : else if (SUBREG_P (to_rtx)
6302 : 4662930 : && SUBREG_PROMOTED_VAR_P (to_rtx))
6303 : : {
6304 : : /* If to_rtx is a promoted subreg, we need to zero or sign
6305 : : extend the value afterwards. */
6306 : 0 : if (TREE_CODE (to) == MEM_REF
6307 : 0 : && TYPE_MODE (TREE_TYPE (from)) != BLKmode
6308 : 0 : && !REF_REVERSE_STORAGE_ORDER (to)
6309 : 0 : && known_eq (bitpos, 0)
6310 : 0 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
6311 : 0 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6312 : : /* Check if the field overlaps the MSB, requiring extension. */
6313 : 0 : else if (maybe_eq (bitpos + bitsize,
6314 : 0 : GET_MODE_BITSIZE (GET_MODE (to_rtx))))
6315 : : {
6316 : 0 : scalar_int_mode imode = subreg_unpromoted_mode (to_rtx);
6317 : 0 : scalar_int_mode omode = subreg_promoted_mode (to_rtx);
6318 : 0 : rtx to_rtx1 = lowpart_subreg (imode, SUBREG_REG (to_rtx),
6319 : : omode);
6320 : 0 : result = store_field (to_rtx1, bitsize, bitpos,
6321 : : bitregion_start, bitregion_end,
6322 : : mode1, from, get_alias_set (to),
6323 : : nontemporal, reversep);
6324 : : /* If the target usually keeps IMODE appropriately
6325 : : extended in OMODE it's unsafe to refer to it using
6326 : : a SUBREG whilst this invariant doesn't hold. */
6327 : 0 : if (targetm.mode_rep_extended (imode, omode) != UNKNOWN)
6328 : 0 : to_rtx1 = simplify_gen_unary (TRUNCATE, imode,
6329 : : SUBREG_REG (to_rtx), omode);
6330 : 0 : convert_move (SUBREG_REG (to_rtx), to_rtx1,
6331 : 0 : SUBREG_PROMOTED_SIGN (to_rtx));
6332 : : }
6333 : : else
6334 : 0 : result = store_field (to_rtx, bitsize, bitpos,
6335 : : bitregion_start, bitregion_end,
6336 : : mode1, from, get_alias_set (to),
6337 : : nontemporal, reversep);
6338 : : }
6339 : : else
6340 : 4662930 : result = store_field (to_rtx, bitsize, bitpos,
6341 : : bitregion_start, bitregion_end,
6342 : : mode1, from, get_alias_set (to),
6343 : : nontemporal, reversep);
6344 : : /* Move the temporary storage back to the non-MEM_P. */
6345 : 4663055 : if (stemp)
6346 : 3 : emit_move_insn (old_to_rtx, stemp);
6347 : : }
6348 : :
6349 : 4663203 : if (result)
6350 : 850912 : preserve_temp_slots (result);
6351 : 4663203 : pop_temp_slots ();
6352 : 4663203 : return;
6353 : : }
6354 : :
6355 : : /* If the rhs is a function call and its value is not an aggregate,
6356 : : call the function before we start to compute the lhs.
6357 : : This is needed for correct code for cases such as
6358 : : val = setjmp (buf) on machines where reference to val
6359 : : requires loading up part of an address in a separate insn.
6360 : :
6361 : : Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
6362 : : since it might be a promoted variable where the zero- or sign- extension
6363 : : needs to be done. Handling this in the normal way is safe because no
6364 : : computation is done before the call. The same is true for SSA names. */
6365 : 2315802 : if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
6366 : 2114001 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6367 : 2114001 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
6368 : 15273061 : && ! (((VAR_P (to)
6369 : : || TREE_CODE (to) == PARM_DECL
6370 : : || TREE_CODE (to) == RESULT_DECL)
6371 : 150628 : && REG_P (DECL_RTL (to)))
6372 : 1971260 : || TREE_CODE (to) == SSA_NAME))
6373 : : {
6374 : 8091 : rtx value;
6375 : :
6376 : 8091 : push_temp_slots ();
6377 : 8091 : value = expand_normal (from);
6378 : :
6379 : 8091 : if (to_rtx == 0)
6380 : 8091 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6381 : :
6382 : : /* Handle calls that return values in multiple non-contiguous locations.
6383 : : The Irix 6 ABI has examples of this. */
6384 : 8091 : if (GET_CODE (to_rtx) == PARALLEL)
6385 : : {
6386 : 0 : if (GET_CODE (value) == PARALLEL)
6387 : 0 : emit_group_move (to_rtx, value);
6388 : : else
6389 : 0 : emit_group_load (to_rtx, value, TREE_TYPE (from),
6390 : 0 : int_size_in_bytes (TREE_TYPE (from)));
6391 : : }
6392 : 8091 : else if (GET_CODE (value) == PARALLEL)
6393 : 1891 : emit_group_store (to_rtx, value, TREE_TYPE (from),
6394 : 1891 : int_size_in_bytes (TREE_TYPE (from)));
6395 : 6200 : else if (GET_MODE (to_rtx) == BLKmode)
6396 : : {
6397 : : /* Handle calls that return BLKmode values in registers. */
6398 : 244 : if (REG_P (value))
6399 : 244 : copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
6400 : : else
6401 : 0 : emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
6402 : : }
6403 : : else
6404 : : {
6405 : 5956 : if (POINTER_TYPE_P (TREE_TYPE (to)))
6406 : 0 : value = convert_memory_address_addr_space
6407 : 0 : (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
6408 : 0 : TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
6409 : :
6410 : 5956 : emit_move_insn (to_rtx, value);
6411 : : }
6412 : :
6413 : 8091 : preserve_temp_slots (to_rtx);
6414 : 8091 : pop_temp_slots ();
6415 : 8091 : return;
6416 : : }
6417 : :
6418 : : /* Ordinary treatment. Expand TO to get a REG or MEM rtx. */
6419 : 13150969 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6420 : :
6421 : : /* Don't move directly into a return register. */
6422 : 13150969 : if (TREE_CODE (to) == RESULT_DECL
6423 : 29840 : && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
6424 : : {
6425 : 0 : rtx temp;
6426 : :
6427 : 0 : push_temp_slots ();
6428 : :
6429 : : /* If the source is itself a return value, it still is in a pseudo at
6430 : : this point so we can move it back to the return register directly. */
6431 : 0 : if (REG_P (to_rtx)
6432 : 0 : && TYPE_MODE (TREE_TYPE (from)) == BLKmode
6433 : 0 : && TREE_CODE (from) != CALL_EXPR)
6434 : 0 : temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
6435 : : else
6436 : 0 : temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
6437 : :
6438 : : /* Handle calls that return values in multiple non-contiguous locations.
6439 : : The Irix 6 ABI has examples of this. */
6440 : 0 : if (GET_CODE (to_rtx) == PARALLEL)
6441 : : {
6442 : 0 : if (GET_CODE (temp) == PARALLEL)
6443 : 0 : emit_group_move (to_rtx, temp);
6444 : : else
6445 : 0 : emit_group_load (to_rtx, temp, TREE_TYPE (from),
6446 : 0 : int_size_in_bytes (TREE_TYPE (from)));
6447 : : }
6448 : 0 : else if (temp)
6449 : 0 : emit_move_insn (to_rtx, temp);
6450 : :
6451 : 0 : preserve_temp_slots (to_rtx);
6452 : 0 : pop_temp_slots ();
6453 : 0 : return;
6454 : : }
6455 : :
6456 : : /* In case we are returning the contents of an object which overlaps
6457 : : the place the value is being stored, use a safe function when copying
6458 : : a value through a pointer into a structure value return block. */
6459 : 13150969 : if (TREE_CODE (to) == RESULT_DECL
6460 : 29840 : && TREE_CODE (from) == INDIRECT_REF
6461 : 0 : && ADDR_SPACE_GENERIC_P
6462 : : (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
6463 : 0 : && refs_may_alias_p (to, from)
6464 : 0 : && cfun->returns_struct
6465 : 13150969 : && !cfun->returns_pcc_struct)
6466 : : {
6467 : 0 : rtx from_rtx, size;
6468 : :
6469 : 0 : push_temp_slots ();
6470 : 0 : size = expr_size (from);
6471 : 0 : from_rtx = expand_normal (from);
6472 : :
6473 : 0 : emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
6474 : :
6475 : 0 : preserve_temp_slots (to_rtx);
6476 : 0 : pop_temp_slots ();
6477 : 0 : return;
6478 : : }
6479 : :
6480 : : /* Compute FROM and store the value in the rtx we got. */
6481 : :
6482 : 13150969 : push_temp_slots ();
6483 : 13150969 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6484 : 13150969 : preserve_temp_slots (result);
6485 : 13150969 : pop_temp_slots ();
6486 : 13150969 : return;
6487 : : }
6488 : :
6489 : : /* Emits nontemporal store insn that moves FROM to TO. Returns true if this
6490 : : succeeded, false otherwise. */
6491 : :
6492 : : bool
6493 : 17 : emit_storent_insn (rtx to, rtx from)
6494 : : {
6495 : 17 : class expand_operand ops[2];
6496 : 17 : machine_mode mode = GET_MODE (to);
6497 : 17 : enum insn_code code = optab_handler (storent_optab, mode);
6498 : :
6499 : 17 : if (code == CODE_FOR_nothing)
6500 : : return false;
6501 : :
6502 : 17 : create_fixed_operand (&ops[0], to);
6503 : 17 : create_input_operand (&ops[1], from, mode);
6504 : 17 : return maybe_expand_insn (code, 2, ops);
6505 : : }
6506 : :
6507 : : /* Helper function for store_expr storing of STRING_CST. */
6508 : :
6509 : : static rtx
6510 : 94580 : string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6511 : : fixed_size_mode mode)
6512 : : {
6513 : 94580 : tree str = (tree) data;
6514 : :
6515 : 94580 : gcc_assert (offset >= 0);
6516 : 94580 : if (offset >= TREE_STRING_LENGTH (str))
6517 : 3516 : return const0_rtx;
6518 : :
6519 : 91064 : if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6520 : 91064 : > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
6521 : : {
6522 : 2638 : char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6523 : 2638 : size_t l = TREE_STRING_LENGTH (str) - offset;
6524 : 2638 : memcpy (p, TREE_STRING_POINTER (str) + offset, l);
6525 : 2638 : memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
6526 : 2638 : return c_readstr (p, mode, false);
6527 : : }
6528 : :
6529 : 88426 : return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
6530 : : }
6531 : :
6532 : : /* Generate code for computing expression EXP,
6533 : : and storing the value into TARGET.
6534 : :
6535 : : If the mode is BLKmode then we may return TARGET itself.
6536 : : It turns out that in BLKmode it doesn't cause a problem.
6537 : : because C has no operators that could combine two different
6538 : : assignments into the same BLKmode object with different values
6539 : : with no sequence point. Will other languages need this to
6540 : : be more thorough?
6541 : :
6542 : : If CALL_PARAM_P is nonzero, this is a store into a call param on the
6543 : : stack, and block moves may need to be treated specially.
6544 : :
6545 : : If NONTEMPORAL is true, try using a nontemporal store instruction.
6546 : :
6547 : : If REVERSE is true, the store is to be done in reverse order. */
6548 : :
6549 : : rtx
6550 : 17000531 : store_expr (tree exp, rtx target, int call_param_p,
6551 : : bool nontemporal, bool reverse)
6552 : : {
6553 : 17000531 : rtx temp;
6554 : 17000531 : rtx alt_rtl = NULL_RTX;
6555 : 17000531 : location_t loc = curr_insn_location ();
6556 : 17000531 : bool shortened_string_cst = false;
6557 : :
6558 : 17000531 : if (VOID_TYPE_P (TREE_TYPE (exp)))
6559 : : {
6560 : : /* C++ can generate ?: expressions with a throw expression in one
6561 : : branch and an rvalue in the other. Here, we resolve attempts to
6562 : : store the throw expression's nonexistent result. */
6563 : 0 : gcc_assert (!call_param_p);
6564 : 0 : expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
6565 : 0 : return NULL_RTX;
6566 : : }
6567 : 17000531 : if (TREE_CODE (exp) == COMPOUND_EXPR)
6568 : : {
6569 : : /* Perform first part of compound expression, then assign from second
6570 : : part. */
6571 : 0 : expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
6572 : : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6573 : 0 : return store_expr (TREE_OPERAND (exp, 1), target,
6574 : 0 : call_param_p, nontemporal, reverse);
6575 : : }
6576 : 17000531 : else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
6577 : : {
6578 : : /* For conditional expression, get safe form of the target. Then
6579 : : test the condition, doing the appropriate assignment on either
6580 : : side. This avoids the creation of unnecessary temporaries.
6581 : : For non-BLKmode, it is more efficient not to do this. */
6582 : :
6583 : 0 : rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
6584 : :
6585 : 0 : do_pending_stack_adjust ();
6586 : 0 : NO_DEFER_POP;
6587 : 0 : jumpifnot (TREE_OPERAND (exp, 0), lab1,
6588 : : profile_probability::uninitialized ());
6589 : 0 : store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
6590 : : nontemporal, reverse);
6591 : 0 : emit_jump_insn (targetm.gen_jump (lab2));
6592 : 0 : emit_barrier ();
6593 : 0 : emit_label (lab1);
6594 : 0 : store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
6595 : : nontemporal, reverse);
6596 : 0 : emit_label (lab2);
6597 : 0 : OK_DEFER_POP;
6598 : :
6599 : 0 : return NULL_RTX;
6600 : : }
6601 : 17000531 : else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
6602 : : /* If this is a scalar in a register that is stored in a wider mode
6603 : : than the declared mode, compute the result into its declared mode
6604 : : and then convert to the wider mode. Our value is the computed
6605 : : expression. */
6606 : : {
6607 : 7 : rtx inner_target = 0;
6608 : 7 : scalar_int_mode outer_mode = subreg_unpromoted_mode (target);
6609 : 7 : scalar_int_mode inner_mode = subreg_promoted_mode (target);
6610 : :
6611 : : /* We can do the conversion inside EXP, which will often result
6612 : : in some optimizations. Do the conversion in two steps: first
6613 : : change the signedness, if needed, then the extend. But don't
6614 : : do this if the type of EXP is a subtype of something else
6615 : : since then the conversion might involve more than just
6616 : : converting modes. */
6617 : 14 : if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
6618 : 0 : && TREE_TYPE (TREE_TYPE (exp)) == 0
6619 : 7 : && GET_MODE_PRECISION (outer_mode)
6620 : 0 : == TYPE_PRECISION (TREE_TYPE (exp)))
6621 : : {
6622 : 0 : if (!SUBREG_CHECK_PROMOTED_SIGN (target,
6623 : : TYPE_UNSIGNED (TREE_TYPE (exp))))
6624 : : {
6625 : : /* Some types, e.g. Fortran's logical*4, won't have a signed
6626 : : version, so use the mode instead. */
6627 : 0 : tree ntype
6628 : : = (signed_or_unsigned_type_for
6629 : 0 : (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
6630 : 0 : if (ntype == NULL)
6631 : 0 : ntype = lang_hooks.types.type_for_mode
6632 : 0 : (TYPE_MODE (TREE_TYPE (exp)),
6633 : 0 : SUBREG_PROMOTED_SIGN (target));
6634 : :
6635 : 0 : exp = fold_convert_loc (loc, ntype, exp);
6636 : : }
6637 : :
6638 : 0 : exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
6639 : 0 : (inner_mode, SUBREG_PROMOTED_SIGN (target)),
6640 : : exp);
6641 : :
6642 : 0 : inner_target = SUBREG_REG (target);
6643 : : }
6644 : :
6645 : 7 : temp = expand_expr (exp, inner_target, VOIDmode,
6646 : : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6647 : :
6648 : :
6649 : : /* If TEMP is a VOIDmode constant, use convert_modes to make
6650 : : sure that we properly convert it. */
6651 : 7 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
6652 : : {
6653 : 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6654 : 0 : temp, SUBREG_PROMOTED_SIGN (target));
6655 : 0 : temp = convert_modes (inner_mode, outer_mode, temp,
6656 : 0 : SUBREG_PROMOTED_SIGN (target));
6657 : 0 : }
6658 : 7 : else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
6659 : 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6660 : 0 : temp, SUBREG_PROMOTED_SIGN (target));
6661 : :
6662 : 21 : convert_move (SUBREG_REG (target), temp,
6663 : 7 : SUBREG_PROMOTED_SIGN (target));
6664 : :
6665 : 7 : return NULL_RTX;
6666 : : }
6667 : 17000524 : else if ((TREE_CODE (exp) == STRING_CST
6668 : 16990024 : || (TREE_CODE (exp) == MEM_REF
6669 : 1252170 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
6670 : 411118 : && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
6671 : : == STRING_CST
6672 : 4342 : && integer_zerop (TREE_OPERAND (exp, 1))))
6673 : 14842 : && !nontemporal && !call_param_p
6674 : 17015366 : && MEM_P (target))
6675 : : {
6676 : : /* Optimize initialization of an array with a STRING_CST. */
6677 : 14836 : HOST_WIDE_INT exp_len, str_copy_len;
6678 : 14836 : rtx dest_mem;
6679 : 14836 : tree str = TREE_CODE (exp) == STRING_CST
6680 : 14836 : ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6681 : :
6682 : 14836 : exp_len = int_expr_size (exp);
6683 : 14836 : if (exp_len <= 0)
6684 : 0 : goto normal_expr;
6685 : :
6686 : 14836 : if (TREE_STRING_LENGTH (str) <= 0)
6687 : 0 : goto normal_expr;
6688 : :
6689 : 29672 : if (can_store_by_pieces (exp_len, string_cst_read_str, (void *) str,
6690 : 14836 : MEM_ALIGN (target), false))
6691 : : {
6692 : 14661 : store_by_pieces (target, exp_len, string_cst_read_str, (void *) str,
6693 : 14661 : MEM_ALIGN (target), false, RETURN_BEGIN);
6694 : 14661 : return NULL_RTX;
6695 : : }
6696 : :
6697 : 175 : str_copy_len = TREE_STRING_LENGTH (str);
6698 : :
6699 : : /* Trailing NUL bytes in EXP will be handled by the call to
6700 : : clear_storage, which is more efficient than copying them from
6701 : : the STRING_CST, so trim those from STR_COPY_LEN. */
6702 : 297 : while (str_copy_len)
6703 : : {
6704 : 254 : if (TREE_STRING_POINTER (str)[str_copy_len - 1])
6705 : : break;
6706 : 122 : str_copy_len--;
6707 : : }
6708 : :
6709 : 175 : if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
6710 : : {
6711 : 175 : str_copy_len += STORE_MAX_PIECES - 1;
6712 : 175 : str_copy_len &= ~(STORE_MAX_PIECES - 1);
6713 : : }
6714 : 175 : if (str_copy_len >= exp_len)
6715 : 124 : goto normal_expr;
6716 : :
6717 : 102 : if (!can_store_by_pieces (str_copy_len, string_cst_read_str,
6718 : 51 : (void *) str, MEM_ALIGN (target), false))
6719 : 2 : goto normal_expr;
6720 : :
6721 : 49 : dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
6722 : 49 : (void *) str, MEM_ALIGN (target), false,
6723 : : RETURN_END);
6724 : 49 : clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
6725 : 49 : exp_len - str_copy_len),
6726 : : GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
6727 : 49 : return NULL_RTX;
6728 : : }
6729 : : else
6730 : : {
6731 : 16985814 : rtx tmp_target;
6732 : :
6733 : 16985814 : normal_expr:
6734 : : /* If we want to use a nontemporal or a reverse order store, force the
6735 : : value into a register first. */
6736 : 16985814 : tmp_target = nontemporal || reverse ? NULL_RTX : target;
6737 : 16985814 : tree rexp = exp;
6738 : 16985814 : if (TREE_CODE (exp) == STRING_CST
6739 : 41 : && tmp_target == target
6740 : 41 : && GET_MODE (target) == BLKmode
6741 : 16985855 : && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
6742 : : {
6743 : 41 : rtx size = expr_size (exp);
6744 : 41 : if (CONST_INT_P (size)
6745 : 41 : && size != const0_rtx
6746 : 82 : && (UINTVAL (size)
6747 : 41 : > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
6748 : : {
6749 : : /* If the STRING_CST has much larger array type than
6750 : : TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
6751 : : it into the rodata section as the code later on will use
6752 : : memset zero for the remainder anyway. See PR95052. */
6753 : 2 : tmp_target = NULL_RTX;
6754 : 2 : rexp = copy_node (exp);
6755 : 2 : tree index
6756 : 2 : = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
6757 : 2 : TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
6758 : : index);
6759 : 2 : shortened_string_cst = true;
6760 : : }
6761 : : }
6762 : 33971628 : temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
6763 : : (call_param_p
6764 : : ? EXPAND_STACK_PARM : EXPAND_NORMAL),
6765 : : &alt_rtl, false);
6766 : 16985814 : if (shortened_string_cst)
6767 : : {
6768 : 2 : gcc_assert (MEM_P (temp));
6769 : 2 : temp = change_address (temp, BLKmode, NULL_RTX);
6770 : : }
6771 : : }
6772 : :
6773 : : /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
6774 : : the same as that of TARGET, adjust the constant. This is needed, for
6775 : : example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
6776 : : only a word-sized value. */
6777 : 3422937 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
6778 : 2451109 : && TREE_CODE (exp) != ERROR_MARK
6779 : 19436923 : && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
6780 : : {
6781 : 0 : gcc_assert (!shortened_string_cst);
6782 : 0 : if (GET_MODE_CLASS (GET_MODE (target))
6783 : 0 : != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
6784 : 0 : && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
6785 : : GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
6786 : : {
6787 : 0 : rtx t = simplify_gen_subreg (GET_MODE (target), temp,
6788 : 0 : TYPE_MODE (TREE_TYPE (exp)), 0);
6789 : 0 : if (t)
6790 : 0 : temp = t;
6791 : : }
6792 : 0 : if (GET_MODE (temp) == VOIDmode)
6793 : 0 : temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
6794 : 0 : temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6795 : : }
6796 : :
6797 : : /* If value was not generated in the target, store it there.
6798 : : Convert the value to TARGET's type first if necessary and emit the
6799 : : pending incrementations that have been queued when expanding EXP.
6800 : : Note that we cannot emit the whole queue blindly because this will
6801 : : effectively disable the POST_INC optimization later.
6802 : :
6803 : : If TEMP and TARGET compare equal according to rtx_equal_p, but
6804 : : one or both of them are volatile memory refs, we have to distinguish
6805 : : two cases:
6806 : : - expand_expr has used TARGET. In this case, we must not generate
6807 : : another copy. This can be detected by TARGET being equal according
6808 : : to == .
6809 : : - expand_expr has not used TARGET - that means that the source just
6810 : : happens to have the same RTX form. Since temp will have been created
6811 : : by expand_expr, it will compare unequal according to == .
6812 : : We must generate a copy in this case, to reach the correct number
6813 : : of volatile memory references. */
6814 : :
6815 : 16985814 : if ((! rtx_equal_p (temp, target)
6816 : 3029857 : || (temp != target && (side_effects_p (temp)
6817 : 46442 : || side_effects_p (target)
6818 : 46442 : || (MEM_P (temp)
6819 : 46229 : && !mems_same_for_tbaa_p (temp, target)))))
6820 : 13955961 : && TREE_CODE (exp) != ERROR_MARK
6821 : : /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
6822 : : but TARGET is not valid memory reference, TEMP will differ
6823 : : from TARGET although it is really the same location. */
6824 : 13955961 : && !(alt_rtl
6825 : 1980678 : && rtx_equal_p (alt_rtl, target)
6826 : 1 : && !side_effects_p (alt_rtl)
6827 : 0 : && !side_effects_p (target))
6828 : : /* If there's nothing to copy, don't bother. Don't call
6829 : : expr_size unless necessary, because some front-ends (C++)
6830 : : expr_size-hook must not be given objects that are not
6831 : : supposed to be bit-copied or bit-initialized. */
6832 : 30941775 : && expr_size (exp) != const0_rtx)
6833 : : {
6834 : 13955961 : if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
6835 : : {
6836 : 1524 : gcc_assert (!shortened_string_cst);
6837 : 1524 : if (GET_MODE (target) == BLKmode)
6838 : : {
6839 : : /* Handle calls that return BLKmode values in registers. */
6840 : 2 : if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
6841 : 2 : copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
6842 : : else
6843 : 0 : store_bit_field (target,
6844 : 0 : rtx_to_poly_int64 (expr_size (exp))
6845 : 0 : * BITS_PER_UNIT,
6846 : : 0, 0, 0, GET_MODE (temp), temp, reverse,
6847 : : false);
6848 : : }
6849 : : else
6850 : 1522 : convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6851 : : }
6852 : :
6853 : 13954437 : else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
6854 : : {
6855 : : /* Handle copying a string constant into an array. The string
6856 : : constant may be shorter than the array. So copy just the string's
6857 : : actual length, and clear the rest. First get the size of the data
6858 : : type of the string, which is actually the size of the target. */
6859 : 41 : rtx size = expr_size (exp);
6860 : :
6861 : 41 : if (CONST_INT_P (size)
6862 : 41 : && INTVAL (size) < TREE_STRING_LENGTH (exp))
6863 : 0 : emit_block_move (target, temp, size,
6864 : : (call_param_p
6865 : : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6866 : : else
6867 : : {
6868 : 41 : machine_mode pointer_mode
6869 : 41 : = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
6870 : 41 : machine_mode address_mode = get_address_mode (target);
6871 : :
6872 : : /* Compute the size of the data to copy from the string. */
6873 : 41 : tree copy_size
6874 : 41 : = size_binop_loc (loc, MIN_EXPR,
6875 : : make_tree (sizetype, size),
6876 : 41 : size_int (TREE_STRING_LENGTH (exp)));
6877 : 41 : rtx copy_size_rtx
6878 : 41 : = expand_expr (copy_size, NULL_RTX, VOIDmode,
6879 : : (call_param_p
6880 : : ? EXPAND_STACK_PARM : EXPAND_NORMAL));
6881 : 41 : rtx_code_label *label = 0;
6882 : :
6883 : : /* Copy that much. */
6884 : 123 : copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
6885 : 41 : TYPE_UNSIGNED (sizetype));
6886 : 82 : emit_block_move (target, temp, copy_size_rtx,
6887 : : (call_param_p
6888 : : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6889 : :
6890 : : /* Figure out how much is left in TARGET that we have to clear.
6891 : : Do all calculations in pointer_mode. */
6892 : 41 : poly_int64 const_copy_size;
6893 : 41 : if (poly_int_rtx_p (copy_size_rtx, &const_copy_size))
6894 : : {
6895 : 41 : size = plus_constant (address_mode, size, -const_copy_size);
6896 : 41 : target = adjust_address (target, BLKmode, const_copy_size);
6897 : : }
6898 : : else
6899 : : {
6900 : 0 : size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
6901 : : copy_size_rtx, NULL_RTX, 0,
6902 : : OPTAB_LIB_WIDEN);
6903 : :
6904 : 0 : if (GET_MODE (copy_size_rtx) != address_mode)
6905 : 0 : copy_size_rtx = convert_to_mode (address_mode,
6906 : : copy_size_rtx,
6907 : 0 : TYPE_UNSIGNED (sizetype));
6908 : :
6909 : 0 : target = offset_address (target, copy_size_rtx,
6910 : : highest_pow2_factor (copy_size));
6911 : 0 : label = gen_label_rtx ();
6912 : 0 : emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
6913 : 0 : GET_MODE (size), 0, label);
6914 : : }
6915 : :
6916 : 41 : if (size != const0_rtx)
6917 : 2 : clear_storage (target, size, BLOCK_OP_NORMAL);
6918 : :
6919 : 41 : if (label)
6920 : 0 : emit_label (label);
6921 : : }
6922 : : }
6923 : 13954396 : else if (shortened_string_cst)
6924 : 0 : gcc_unreachable ();
6925 : : /* Handle calls that return values in multiple non-contiguous locations.
6926 : : The Irix 6 ABI has examples of this. */
6927 : 13954396 : else if (GET_CODE (target) == PARALLEL)
6928 : : {
6929 : 0 : if (GET_CODE (temp) == PARALLEL)
6930 : 0 : emit_group_move (target, temp);
6931 : : else
6932 : 0 : emit_group_load (target, temp, TREE_TYPE (exp),
6933 : 0 : int_size_in_bytes (TREE_TYPE (exp)));
6934 : : }
6935 : 13954396 : else if (GET_CODE (temp) == PARALLEL)
6936 : 0 : emit_group_store (target, temp, TREE_TYPE (exp),
6937 : 0 : int_size_in_bytes (TREE_TYPE (exp)));
6938 : 13954396 : else if (GET_MODE (temp) == BLKmode)
6939 : 659440 : emit_block_move (target, temp, expr_size (exp),
6940 : : (call_param_p
6941 : : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6942 : : /* If we emit a nontemporal store, there is nothing else to do. */
6943 : 13624676 : else if (nontemporal && emit_storent_insn (target, temp))
6944 : : ;
6945 : : else
6946 : : {
6947 : 13624659 : if (reverse)
6948 : 696 : temp = flip_storage_order (GET_MODE (target), temp);
6949 : 13624659 : temp = force_operand (temp, target);
6950 : 13624659 : if (temp != target)
6951 : 13623088 : emit_move_insn (target, temp);
6952 : : }
6953 : : }
6954 : : else
6955 : 3029853 : gcc_assert (!shortened_string_cst);
6956 : :
6957 : : return NULL_RTX;
6958 : : }
6959 : :
6960 : : /* Return true if field F of structure TYPE is a flexible array. */
6961 : :
6962 : : static bool
6963 : 3885581 : flexible_array_member_p (const_tree f, const_tree type)
6964 : : {
6965 : 3885581 : const_tree tf;
6966 : :
6967 : 3885581 : tf = TREE_TYPE (f);
6968 : 3885581 : return (DECL_CHAIN (f) == NULL
6969 : 1074241 : && TREE_CODE (tf) == ARRAY_TYPE
6970 : 2529 : && TYPE_DOMAIN (tf)
6971 : 2529 : && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
6972 : 2529 : && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
6973 : 2529 : && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
6974 : 3885620 : && int_size_in_bytes (type) >= 0);
6975 : : }
6976 : :
6977 : : /* If FOR_CTOR_P, return the number of top-level elements that a constructor
6978 : : must have in order for it to completely initialize a value of type TYPE.
6979 : : Return -1 if the number isn't known.
6980 : :
6981 : : If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
6982 : :
6983 : : static HOST_WIDE_INT
6984 : 3542186 : count_type_elements (const_tree type, bool for_ctor_p)
6985 : : {
6986 : 3542186 : switch (TREE_CODE (type))
6987 : : {
6988 : 147354 : case ARRAY_TYPE:
6989 : 147354 : {
6990 : 147354 : tree nelts_minus_one;
6991 : :
6992 : 147354 : nelts_minus_one = array_type_nelts_minus_one (type);
6993 : 147354 : if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one))
6994 : : {
6995 : 147345 : unsigned HOST_WIDE_INT n;
6996 : :
6997 : 147345 : n = tree_to_uhwi (nelts_minus_one) + 1;
6998 : 147345 : if (n == 0 || for_ctor_p)
6999 : 146584 : return n;
7000 : : else
7001 : 761 : return n * count_type_elements (TREE_TYPE (type), false);
7002 : : }
7003 : 9 : return for_ctor_p ? -1 : 1;
7004 : : }
7005 : :
7006 : 1719430 : case RECORD_TYPE:
7007 : 1719430 : {
7008 : 1719430 : unsigned HOST_WIDE_INT n;
7009 : 1719430 : tree f;
7010 : :
7011 : 1719430 : n = 0;
7012 : 15443212 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7013 : 13723782 : if (TREE_CODE (f) == FIELD_DECL)
7014 : : {
7015 : 4344830 : if (!for_ctor_p)
7016 : 459249 : n += count_type_elements (TREE_TYPE (f), false);
7017 : 3885581 : else if (!flexible_array_member_p (f, type))
7018 : : /* Don't count flexible arrays, which are not supposed
7019 : : to be initialized. */
7020 : 3885542 : n += 1;
7021 : : }
7022 : :
7023 : 1719430 : return n;
7024 : : }
7025 : :
7026 : 3791 : case UNION_TYPE:
7027 : 3791 : case QUAL_UNION_TYPE:
7028 : 3791 : {
7029 : 3791 : tree f;
7030 : 3791 : HOST_WIDE_INT n, m;
7031 : :
7032 : 3791 : gcc_assert (!for_ctor_p);
7033 : : /* Estimate the number of scalars in each field and pick the
7034 : : maximum. Other estimates would do instead; the idea is simply
7035 : : to make sure that the estimate is not sensitive to the ordering
7036 : : of the fields. */
7037 : 3791 : n = 1;
7038 : 86350 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7039 : 82559 : if (TREE_CODE (f) == FIELD_DECL)
7040 : : {
7041 : 77638 : m = count_type_elements (TREE_TYPE (f), false);
7042 : : /* If the field doesn't span the whole union, add an extra
7043 : : scalar for the rest. */
7044 : 77638 : if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
7045 : 77638 : TYPE_SIZE (type)) != 1)
7046 : 55352 : m++;
7047 : 77638 : if (n < m)
7048 : 82559 : n = m;
7049 : : }
7050 : : return n;
7051 : : }
7052 : :
7053 : : case COMPLEX_TYPE:
7054 : : return 2;
7055 : :
7056 : 306 : case VECTOR_TYPE:
7057 : 306 : {
7058 : 306 : unsigned HOST_WIDE_INT nelts;
7059 : 306 : if (TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
7060 : 306 : return nelts;
7061 : : else
7062 : : return -1;
7063 : : }
7064 : :
7065 : : case INTEGER_TYPE:
7066 : : case REAL_TYPE:
7067 : : case FIXED_POINT_TYPE:
7068 : : case ENUMERAL_TYPE:
7069 : : case BOOLEAN_TYPE:
7070 : : case POINTER_TYPE:
7071 : : case OFFSET_TYPE:
7072 : : case REFERENCE_TYPE:
7073 : : case NULLPTR_TYPE:
7074 : : case OPAQUE_TYPE:
7075 : : case BITINT_TYPE:
7076 : : return 1;
7077 : :
7078 : 0 : case ERROR_MARK:
7079 : 0 : return 0;
7080 : :
7081 : 0 : case VOID_TYPE:
7082 : 0 : case METHOD_TYPE:
7083 : 0 : case FUNCTION_TYPE:
7084 : 0 : case LANG_TYPE:
7085 : 0 : default:
7086 : 0 : gcc_unreachable ();
7087 : : }
7088 : : }
7089 : :
7090 : : /* Helper for categorize_ctor_elements. Identical interface. */
7091 : :
7092 : : static bool
7093 : 1491025 : categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7094 : : HOST_WIDE_INT *p_unique_nz_elts,
7095 : : HOST_WIDE_INT *p_init_elts, int *p_complete)
7096 : : {
7097 : 1491025 : unsigned HOST_WIDE_INT idx;
7098 : 1491025 : HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
7099 : 1491025 : tree value, purpose, elt_type;
7100 : :
7101 : : /* Whether CTOR is a valid constant initializer, in accordance with what
7102 : : initializer_constant_valid_p does. If inferred from the constructor
7103 : : elements, true until proven otherwise. */
7104 : 1491025 : bool const_from_elts_p = constructor_static_from_elts_p (ctor);
7105 : 1491025 : bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
7106 : :
7107 : 1491025 : nz_elts = 0;
7108 : 1491025 : unique_nz_elts = 0;
7109 : 1491025 : init_elts = 0;
7110 : 1491025 : num_fields = 0;
7111 : 1491025 : elt_type = NULL_TREE;
7112 : :
7113 : 5672883 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
7114 : : {
7115 : 4181858 : HOST_WIDE_INT mult = 1;
7116 : :
7117 : 4181858 : if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
7118 : : {
7119 : 603 : tree lo_index = TREE_OPERAND (purpose, 0);
7120 : 603 : tree hi_index = TREE_OPERAND (purpose, 1);
7121 : :
7122 : 603 : if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
7123 : 603 : mult = (tree_to_uhwi (hi_index)
7124 : 603 : - tree_to_uhwi (lo_index) + 1);
7125 : : }
7126 : 4181858 : num_fields += mult;
7127 : 4181858 : elt_type = TREE_TYPE (value);
7128 : :
7129 : 4181858 : switch (TREE_CODE (value))
7130 : : {
7131 : 520267 : case CONSTRUCTOR:
7132 : 520267 : {
7133 : 520267 : HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
7134 : :
7135 : 520267 : bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
7136 : : &ic, p_complete);
7137 : :
7138 : 520267 : nz_elts += mult * nz;
7139 : 520267 : unique_nz_elts += unz;
7140 : 520267 : init_elts += mult * ic;
7141 : :
7142 : 520267 : if (const_from_elts_p && const_p)
7143 : 307679 : const_p = const_elt_p;
7144 : : }
7145 : 520267 : break;
7146 : :
7147 : 2282124 : case INTEGER_CST:
7148 : 2282124 : case REAL_CST:
7149 : 2282124 : case FIXED_CST:
7150 : 2282124 : if (!initializer_zerop (value))
7151 : : {
7152 : 1649064 : nz_elts += mult;
7153 : 1649064 : unique_nz_elts++;
7154 : : }
7155 : 2282124 : init_elts += mult;
7156 : 2282124 : break;
7157 : :
7158 : 6300 : case STRING_CST:
7159 : 6300 : nz_elts += mult * TREE_STRING_LENGTH (value);
7160 : 6300 : unique_nz_elts += TREE_STRING_LENGTH (value);
7161 : 6300 : init_elts += mult * TREE_STRING_LENGTH (value);
7162 : 6300 : break;
7163 : :
7164 : 131 : case RAW_DATA_CST:
7165 : 131 : nz_elts += mult * RAW_DATA_LENGTH (value);
7166 : 131 : unique_nz_elts += RAW_DATA_LENGTH (value);
7167 : 131 : init_elts += mult * RAW_DATA_LENGTH (value);
7168 : 131 : num_fields += mult * (RAW_DATA_LENGTH (value) - 1);
7169 : 131 : break;
7170 : :
7171 : 2760 : case COMPLEX_CST:
7172 : 2760 : if (!initializer_zerop (TREE_REALPART (value)))
7173 : : {
7174 : 2325 : nz_elts += mult;
7175 : 2325 : unique_nz_elts++;
7176 : : }
7177 : 2760 : if (!initializer_zerop (TREE_IMAGPART (value)))
7178 : : {
7179 : 2245 : nz_elts += mult;
7180 : 2245 : unique_nz_elts++;
7181 : : }
7182 : 2760 : init_elts += 2 * mult;
7183 : 2760 : break;
7184 : :
7185 : 778 : case VECTOR_CST:
7186 : 778 : {
7187 : 778 : unsigned int nunits
7188 : : = constant_lower_bound
7189 : 778 : (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value)));
7190 : 5269 : for (unsigned int i = 0; i < nunits; ++i)
7191 : : {
7192 : 4491 : tree v = VECTOR_CST_ELT (value, i);
7193 : 4491 : if (!initializer_zerop (v))
7194 : : {
7195 : 1993 : nz_elts += mult;
7196 : 1993 : unique_nz_elts++;
7197 : : }
7198 : 4491 : init_elts += mult;
7199 : : }
7200 : : }
7201 : : break;
7202 : :
7203 : 1369498 : default:
7204 : 1369498 : {
7205 : 1369498 : HOST_WIDE_INT tc = count_type_elements (elt_type, false);
7206 : 1369498 : nz_elts += mult * tc;
7207 : 1369498 : unique_nz_elts += tc;
7208 : 1369498 : init_elts += mult * tc;
7209 : :
7210 : 1369498 : if (const_from_elts_p && const_p)
7211 : 527139 : const_p
7212 : 527139 : = initializer_constant_valid_p (value,
7213 : : elt_type,
7214 : 527139 : TYPE_REVERSE_STORAGE_ORDER
7215 : : (TREE_TYPE (ctor)))
7216 : : != NULL_TREE;
7217 : : }
7218 : : break;
7219 : : }
7220 : : }
7221 : :
7222 : 1491025 : if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
7223 : : num_fields, elt_type))
7224 : 176262 : *p_complete = 0;
7225 : 1314763 : else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
7226 : 1314763 : || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
7227 : : {
7228 : 11068 : if (*p_complete
7229 : 7121 : && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7230 : 20237 : && (num_fields
7231 : 4586 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7232 : 4583 : TYPE_SIZE (elt_type)) != 1
7233 : 3 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7234 : 3398 : *p_complete = 0;
7235 : 7670 : else if (*p_complete > 0
7236 : 11060 : && (num_fields
7237 : 3390 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7238 : 3390 : TYPE_SIZE (elt_type)) != 1
7239 : 0 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7240 : 239 : *p_complete = -1;
7241 : : }
7242 : 1303695 : else if (*p_complete
7243 : 1198075 : && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7244 : 1185221 : || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
7245 : 1316554 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7246 : 2068 : *p_complete = 0;
7247 : 1301627 : else if (*p_complete > 0
7248 : 1301627 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7249 : 14708 : *p_complete = -1;
7250 : :
7251 : 1491025 : *p_nz_elts += nz_elts;
7252 : 1491025 : *p_unique_nz_elts += unique_nz_elts;
7253 : 1491025 : *p_init_elts += init_elts;
7254 : :
7255 : 1491025 : return const_p;
7256 : : }
7257 : :
7258 : : /* Examine CTOR to discover:
7259 : : * how many scalar fields are set to nonzero values,
7260 : : and place it in *P_NZ_ELTS;
7261 : : * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
7262 : : high - low + 1 (this can be useful for callers to determine ctors
7263 : : that could be cheaply initialized with - perhaps nested - loops
7264 : : compared to copied from huge read-only data),
7265 : : and place it in *P_UNIQUE_NZ_ELTS;
7266 : : * how many scalar fields in total are in CTOR,
7267 : : and place it in *P_ELT_COUNT.
7268 : : * whether the constructor is complete -- in the sense that every
7269 : : meaningful byte is explicitly given a value --
7270 : : and place it in *P_COMPLETE:
7271 : : - 0 if any field is missing
7272 : : - 1 if all fields are initialized, and there's no padding
7273 : : - -1 if all fields are initialized, but there's padding
7274 : :
7275 : : Return whether or not CTOR is a valid static constant initializer, the same
7276 : : as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
7277 : :
7278 : : bool
7279 : 970758 : categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7280 : : HOST_WIDE_INT *p_unique_nz_elts,
7281 : : HOST_WIDE_INT *p_init_elts, int *p_complete)
7282 : : {
7283 : 970758 : *p_nz_elts = 0;
7284 : 970758 : *p_unique_nz_elts = 0;
7285 : 970758 : *p_init_elts = 0;
7286 : 970758 : *p_complete = 1;
7287 : :
7288 : 970758 : return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
7289 : 970758 : p_init_elts, p_complete);
7290 : : }
7291 : :
7292 : : /* Return true if constructor CTOR is simple enough to be materialized
7293 : : in an integer mode register. Limit the size to WORDS words, which
7294 : : is 1 by default. */
7295 : :
7296 : : bool
7297 : 23440 : immediate_const_ctor_p (const_tree ctor, unsigned int words)
7298 : : {
7299 : : /* Allow function to be called with a VAR_DECL's DECL_INITIAL. */
7300 : 23440 : if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
7301 : : return false;
7302 : :
7303 : 2684 : return TREE_CONSTANT (ctor)
7304 : 2684 : && !TREE_ADDRESSABLE (ctor)
7305 : 2684 : && CONSTRUCTOR_NELTS (ctor)
7306 : 2660 : && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
7307 : 642 : && int_expr_size (ctor) <= words * UNITS_PER_WORD
7308 : 2838 : && initializer_constant_valid_for_bitfield_p (ctor);
7309 : : }
7310 : :
7311 : : /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
7312 : : of which had type LAST_TYPE. Each element was itself a complete
7313 : : initializer, in the sense that every meaningful byte was explicitly
7314 : : given a value. Return true if the same is true for the constructor
7315 : : as a whole. */
7316 : :
7317 : : bool
7318 : 1643131 : complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
7319 : : const_tree last_type)
7320 : : {
7321 : 1643131 : if (TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE)
7322 : : {
7323 : 8091 : if (num_elts == 0)
7324 : : {
7325 : 24 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7326 : : return false;
7327 : :
7328 : : /* If the CONSTRUCTOR doesn't have any elts, it is
7329 : : incomplete if the union has at least one field. */
7330 : 27 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
7331 : 24 : if (TREE_CODE (f) == FIELD_DECL)
7332 : : return false;
7333 : :
7334 : : return true;
7335 : : }
7336 : :
7337 : 8067 : gcc_assert (num_elts == 1 && last_type);
7338 : :
7339 : 8067 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7340 : : /* ??? We could look at each element of the union, and find the
7341 : : largest element. Which would avoid comparing the size of the
7342 : : initialized element against any tail padding in the union.
7343 : : Doesn't seem worth the effort... */
7344 : 6 : return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
7345 : :
7346 : : return true;
7347 : : }
7348 : :
7349 : 1635040 : return count_type_elements (type, true) == num_elts;
7350 : : }
7351 : :
7352 : : /* Return true if EXP contains mostly (3/4) zeros. */
7353 : :
7354 : : static bool
7355 : 351419 : mostly_zeros_p (const_tree exp)
7356 : : {
7357 : 351419 : if (TREE_CODE (exp) == CONSTRUCTOR)
7358 : : {
7359 : 104 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7360 : 104 : int complete_p;
7361 : :
7362 : 104 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7363 : : &complete_p);
7364 : 104 : return !complete_p || nz_elts < init_elts / 4;
7365 : : }
7366 : :
7367 : 351315 : return initializer_zerop (exp);
7368 : : }
7369 : :
7370 : : /* Return true if EXP contains all zeros. */
7371 : :
7372 : : static bool
7373 : 4096 : all_zeros_p (const_tree exp)
7374 : : {
7375 : 4096 : if (TREE_CODE (exp) == CONSTRUCTOR)
7376 : : {
7377 : 4096 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7378 : 4096 : int complete_p;
7379 : :
7380 : 4096 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7381 : : &complete_p);
7382 : 4096 : return nz_elts == 0;
7383 : : }
7384 : :
7385 : 0 : return initializer_zerop (exp);
7386 : : }
7387 : :
7388 : : /* Helper function for store_constructor.
7389 : : TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
7390 : : CLEARED is as for store_constructor.
7391 : : ALIAS_SET is the alias set to use for any stores.
7392 : : If REVERSE is true, the store is to be done in reverse order.
7393 : :
7394 : : This provides a recursive shortcut back to store_constructor when it isn't
7395 : : necessary to go through store_field. This is so that we can pass through
7396 : : the cleared field to let store_constructor know that we may not have to
7397 : : clear a substructure if the outer structure has already been cleared. */
7398 : :
7399 : : static void
7400 : 32373 : store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
7401 : : poly_uint64 bitregion_start,
7402 : : poly_uint64 bitregion_end,
7403 : : machine_mode mode,
7404 : : tree exp, int cleared,
7405 : : alias_set_type alias_set, bool reverse)
7406 : : {
7407 : 32373 : poly_int64 bytepos;
7408 : 32373 : poly_uint64 bytesize;
7409 : 32373 : if (TREE_CODE (exp) == CONSTRUCTOR
7410 : : /* We can only call store_constructor recursively if the size and
7411 : : bit position are on a byte boundary. */
7412 : 60 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
7413 : 60 : && maybe_ne (bitsize, 0U)
7414 : 32373 : && multiple_p (bitsize, BITS_PER_UNIT, &bytesize)
7415 : : /* If we have a nonzero bitpos for a register target, then we just
7416 : : let store_field do the bitfield handling. This is unlikely to
7417 : : generate unnecessary clear instructions anyways. */
7418 : 32433 : && (known_eq (bitpos, 0) || MEM_P (target)))
7419 : : {
7420 : 60 : if (MEM_P (target))
7421 : : {
7422 : 18 : machine_mode target_mode = GET_MODE (target);
7423 : 18 : if (target_mode != BLKmode
7424 : 18 : && !multiple_p (bitpos, GET_MODE_ALIGNMENT (target_mode)))
7425 : : target_mode = BLKmode;
7426 : 18 : target = adjust_address (target, target_mode, bytepos);
7427 : : }
7428 : :
7429 : :
7430 : : /* Update the alias set, if required. */
7431 : 18 : if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
7432 : 78 : && MEM_ALIAS_SET (target) != 0)
7433 : : {
7434 : 18 : target = copy_rtx (target);
7435 : 18 : set_mem_alias_set (target, alias_set);
7436 : : }
7437 : :
7438 : 60 : store_constructor (exp, target, cleared, bytesize, reverse);
7439 : : }
7440 : : else
7441 : 32313 : store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
7442 : : exp, alias_set, false, reverse);
7443 : 32373 : }
7444 : :
7445 : :
7446 : : /* Returns the number of FIELD_DECLs in TYPE. */
7447 : :
7448 : : static int
7449 : 64102 : fields_length (const_tree type)
7450 : : {
7451 : 64102 : tree t = TYPE_FIELDS (type);
7452 : 64102 : int count = 0;
7453 : :
7454 : 635357 : for (; t; t = DECL_CHAIN (t))
7455 : 571255 : if (TREE_CODE (t) == FIELD_DECL)
7456 : 290716 : ++count;
7457 : :
7458 : 64102 : return count;
7459 : : }
7460 : :
7461 : :
7462 : : /* Store the value of constructor EXP into the rtx TARGET.
7463 : : TARGET is either a REG or a MEM; we know it cannot conflict, since
7464 : : safe_from_p has been called.
7465 : : CLEARED is true if TARGET is known to have been zero'd.
7466 : : SIZE is the number of bytes of TARGET we are allowed to modify: this
7467 : : may not be the same as the size of EXP if we are assigning to a field
7468 : : which has been packed to exclude padding bits.
7469 : : If REVERSE is true, the store is to be done in reverse order. */
7470 : :
7471 : : void
7472 : 242812 : store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
7473 : : bool reverse)
7474 : : {
7475 : 242812 : tree type = TREE_TYPE (exp);
7476 : 242812 : HOST_WIDE_INT exp_size = int_size_in_bytes (type);
7477 : 242812 : poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
7478 : :
7479 : 242812 : switch (TREE_CODE (type))
7480 : : {
7481 : 65980 : case RECORD_TYPE:
7482 : 65980 : case UNION_TYPE:
7483 : 65980 : case QUAL_UNION_TYPE:
7484 : 65980 : {
7485 : 65980 : unsigned HOST_WIDE_INT idx;
7486 : 65980 : tree field, value;
7487 : :
7488 : : /* The storage order is specified for every aggregate type. */
7489 : 65980 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7490 : :
7491 : : /* If size is zero or the target is already cleared, do nothing. */
7492 : 65980 : if (known_eq (size, 0) || cleared)
7493 : : cleared = 1;
7494 : : /* We either clear the aggregate or indicate the value is dead. */
7495 : 65980 : else if ((TREE_CODE (type) == UNION_TYPE
7496 : 65980 : || TREE_CODE (type) == QUAL_UNION_TYPE)
7497 : 67631 : && ! CONSTRUCTOR_ELTS (exp))
7498 : : /* If the constructor is empty, clear the union. */
7499 : : {
7500 : 1602 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
7501 : 1602 : cleared = 1;
7502 : : }
7503 : :
7504 : : /* If we are building a static constructor into a register,
7505 : : set the initial value as zero so we can fold the value into
7506 : : a constant. But if more than one register is involved,
7507 : : this probably loses. */
7508 : 3210 : else if (REG_P (target) && TREE_STATIC (exp)
7509 : 65084 : && known_le (GET_MODE_SIZE (GET_MODE (target)),
7510 : : REGMODE_NATURAL_SIZE (GET_MODE (target))))
7511 : : {
7512 : 276 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7513 : 276 : cleared = 1;
7514 : : }
7515 : :
7516 : : /* If the constructor has fewer fields than the structure or
7517 : : if we are initializing the structure to mostly zeros, clear
7518 : : the whole structure first. Don't do this if TARGET is a
7519 : : register whose mode size isn't equal to SIZE since
7520 : : clear_storage can't handle this case. */
7521 : 64102 : else if (known_size_p (size)
7522 : 64181 : && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
7523 : 66 : || mostly_zeros_p (exp))
7524 : 128138 : && (!REG_P (target)
7525 : 5864 : || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
7526 : : {
7527 : 74468 : clear_storage (target, gen_int_mode (size, Pmode),
7528 : : BLOCK_OP_NORMAL);
7529 : 64036 : cleared = 1;
7530 : : }
7531 : :
7532 : 65980 : if (REG_P (target) && !cleared)
7533 : 2 : emit_clobber (target);
7534 : :
7535 : : /* Store each element of the constructor into the
7536 : : corresponding field of TARGET. */
7537 : 66305 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
7538 : : {
7539 : 325 : machine_mode mode;
7540 : 325 : HOST_WIDE_INT bitsize;
7541 : 325 : HOST_WIDE_INT bitpos = 0;
7542 : 325 : tree offset;
7543 : 325 : rtx to_rtx = target;
7544 : :
7545 : : /* Just ignore missing fields. We cleared the whole
7546 : : structure, above, if any fields are missing. */
7547 : 325 : if (field == 0)
7548 : 325 : continue;
7549 : :
7550 : 325 : if (cleared && initializer_zerop (value))
7551 : 78 : continue;
7552 : :
7553 : 247 : if (tree_fits_uhwi_p (DECL_SIZE (field)))
7554 : 247 : bitsize = tree_to_uhwi (DECL_SIZE (field));
7555 : : else
7556 : 0 : gcc_unreachable ();
7557 : :
7558 : 247 : mode = DECL_MODE (field);
7559 : 247 : if (DECL_BIT_FIELD (field))
7560 : 74 : mode = VOIDmode;
7561 : :
7562 : 247 : offset = DECL_FIELD_OFFSET (field);
7563 : 247 : if (tree_fits_shwi_p (offset)
7564 : 247 : && tree_fits_shwi_p (bit_position (field)))
7565 : : {
7566 : 247 : bitpos = int_bit_position (field);
7567 : 247 : offset = NULL_TREE;
7568 : : }
7569 : : else
7570 : 0 : gcc_unreachable ();
7571 : :
7572 : : /* If this initializes a field that is smaller than a
7573 : : word, at the start of a word, try to widen it to a full
7574 : : word. This special case allows us to output C++ member
7575 : : function initializations in a form that the optimizers
7576 : : can understand. */
7577 : 247 : if (WORD_REGISTER_OPERATIONS
7578 : : && REG_P (target)
7579 : : && bitsize < BITS_PER_WORD
7580 : : && bitpos % BITS_PER_WORD == 0
7581 : : && GET_MODE_CLASS (mode) == MODE_INT
7582 : : && TREE_CODE (value) == INTEGER_CST
7583 : : && exp_size >= 0
7584 : : && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
7585 : : {
7586 : : type = TREE_TYPE (value);
7587 : :
7588 : : if (TYPE_PRECISION (type) < BITS_PER_WORD)
7589 : : {
7590 : : type = lang_hooks.types.type_for_mode
7591 : : (word_mode, TYPE_UNSIGNED (type));
7592 : : value = fold_convert (type, value);
7593 : : /* Make sure the bits beyond the original bitsize are zero
7594 : : so that we can correctly avoid extra zeroing stores in
7595 : : later constructor elements. */
7596 : : tree bitsize_mask
7597 : : = wide_int_to_tree (type, wi::mask (bitsize, false,
7598 : : BITS_PER_WORD));
7599 : : value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
7600 : : }
7601 : :
7602 : : if (BYTES_BIG_ENDIAN)
7603 : : value
7604 : : = fold_build2 (LSHIFT_EXPR, type, value,
7605 : : build_int_cst (type,
7606 : : BITS_PER_WORD - bitsize));
7607 : : bitsize = BITS_PER_WORD;
7608 : : mode = word_mode;
7609 : : }
7610 : :
7611 : 82 : if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
7612 : 329 : && DECL_NONADDRESSABLE_P (field))
7613 : : {
7614 : 0 : to_rtx = copy_rtx (to_rtx);
7615 : 0 : MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
7616 : : }
7617 : :
7618 : 247 : store_constructor_field (to_rtx, bitsize, bitpos,
7619 : 247 : 0, bitregion_end, mode,
7620 : : value, cleared,
7621 : 247 : get_alias_set (TREE_TYPE (field)),
7622 : : reverse);
7623 : : }
7624 : : break;
7625 : : }
7626 : 39166 : case ARRAY_TYPE:
7627 : 39166 : {
7628 : 39166 : tree value, index;
7629 : 39166 : unsigned HOST_WIDE_INT i;
7630 : 39166 : bool need_to_clear;
7631 : 39166 : tree domain;
7632 : 39166 : tree elttype = TREE_TYPE (type);
7633 : 39166 : bool const_bounds_p;
7634 : 39166 : unsigned HOST_WIDE_INT minelt = 0;
7635 : 39166 : unsigned HOST_WIDE_INT maxelt = 0;
7636 : :
7637 : : /* The storage order is specified for every aggregate type. */
7638 : 39166 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7639 : :
7640 : 39166 : domain = TYPE_DOMAIN (type);
7641 : 39166 : const_bounds_p = (TYPE_MIN_VALUE (domain)
7642 : 39166 : && TYPE_MAX_VALUE (domain)
7643 : 39166 : && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain))
7644 : 78332 : && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain)));
7645 : :
7646 : : /* If we have constant bounds for the range of the type, get them. */
7647 : 39166 : if (const_bounds_p)
7648 : : {
7649 : 39166 : minelt = tree_to_uhwi (TYPE_MIN_VALUE (domain));
7650 : 39166 : maxelt = tree_to_uhwi (TYPE_MAX_VALUE (domain));
7651 : : }
7652 : :
7653 : : /* If the constructor has fewer elements than the array, clear
7654 : : the whole array first. Similarly if this is static
7655 : : constructor of a non-BLKmode object. */
7656 : 39166 : if (cleared)
7657 : : need_to_clear = false;
7658 : 39124 : else if (REG_P (target) && TREE_STATIC (exp))
7659 : : need_to_clear = true;
7660 : : else
7661 : : {
7662 : 39117 : unsigned HOST_WIDE_INT idx;
7663 : 39117 : unsigned HOST_WIDE_INT count = 0, zero_count = 0;
7664 : 39117 : need_to_clear = ! const_bounds_p;
7665 : :
7666 : : /* This loop is a more accurate version of the loop in
7667 : : mostly_zeros_p (it handles RANGE_EXPR in an index). It
7668 : : is also needed to check for missing elements. */
7669 : 39173 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
7670 : : {
7671 : 56 : unsigned HOST_WIDE_INT this_node_count;
7672 : :
7673 : 56 : if (need_to_clear)
7674 : : break;
7675 : :
7676 : 56 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7677 : : {
7678 : 0 : tree lo_index = TREE_OPERAND (index, 0);
7679 : 0 : tree hi_index = TREE_OPERAND (index, 1);
7680 : :
7681 : 0 : if (! tree_fits_uhwi_p (lo_index)
7682 : 0 : || ! tree_fits_uhwi_p (hi_index))
7683 : : {
7684 : : need_to_clear = true;
7685 : : break;
7686 : : }
7687 : :
7688 : 0 : this_node_count = (tree_to_uhwi (hi_index)
7689 : 0 : - tree_to_uhwi (lo_index) + 1);
7690 : 0 : }
7691 : : else
7692 : : this_node_count = 1;
7693 : :
7694 : 56 : count += this_node_count;
7695 : 56 : if (mostly_zeros_p (value))
7696 : 0 : zero_count += this_node_count;
7697 : : }
7698 : :
7699 : : /* Clear the entire array first if there are any missing
7700 : : elements, or if the incidence of zero elements is >=
7701 : : 75%. */
7702 : 39117 : if (! need_to_clear
7703 : 39117 : && (count < maxelt - minelt + 1
7704 : 7 : || 4 * zero_count >= 3 * count))
7705 : : need_to_clear = true;
7706 : : }
7707 : :
7708 : 39117 : if (need_to_clear && maybe_gt (size, 0))
7709 : : {
7710 : 39117 : if (REG_P (target))
7711 : 1617 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7712 : : else
7713 : 42218 : clear_storage (target, gen_int_mode (size, Pmode),
7714 : : BLOCK_OP_NORMAL);
7715 : : cleared = 1;
7716 : : }
7717 : :
7718 : 49 : if (!cleared && REG_P (target))
7719 : : /* Inform later passes that the old value is dead. */
7720 : 0 : emit_clobber (target);
7721 : :
7722 : : /* Store each element of the constructor into the
7723 : : corresponding element of TARGET, determined by counting the
7724 : : elements. */
7725 : 39558 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
7726 : : {
7727 : 392 : machine_mode mode;
7728 : 392 : poly_int64 bitsize;
7729 : 392 : HOST_WIDE_INT bitpos;
7730 : 392 : rtx xtarget = target;
7731 : :
7732 : 392 : if (cleared && initializer_zerop (value))
7733 : 0 : continue;
7734 : :
7735 : 392 : mode = TYPE_MODE (elttype);
7736 : 392 : if (mode != BLKmode)
7737 : 784 : bitsize = GET_MODE_BITSIZE (mode);
7738 : 0 : else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
7739 : 0 : bitsize = -1;
7740 : :
7741 : 392 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7742 : : {
7743 : 0 : tree lo_index = TREE_OPERAND (index, 0);
7744 : 0 : tree hi_index = TREE_OPERAND (index, 1);
7745 : 0 : rtx index_r;
7746 : 0 : unsigned HOST_WIDE_INT lo, hi, count;
7747 : 0 : tree offset;
7748 : :
7749 : : /* If the range is constant and "small", unroll the loop. */
7750 : 0 : if (const_bounds_p
7751 : 0 : && tree_fits_uhwi_p (lo_index)
7752 : 0 : && tree_fits_uhwi_p (hi_index)
7753 : 0 : && (lo = tree_to_uhwi (lo_index),
7754 : 0 : hi = tree_to_uhwi (hi_index),
7755 : 0 : count = hi - lo + 1,
7756 : 0 : (!MEM_P (target)
7757 : 0 : || count <= 2
7758 : 0 : || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
7759 : 0 : && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
7760 : : <= 40 * 8)))))
7761 : : {
7762 : 0 : lo -= minelt; hi -= minelt;
7763 : 0 : for (; lo <= hi; lo++)
7764 : : {
7765 : 0 : bitpos = lo * tree_to_uhwi (TYPE_SIZE (elttype));
7766 : :
7767 : 0 : if (MEM_P (target)
7768 : 0 : && !MEM_KEEP_ALIAS_SET_P (target)
7769 : 0 : && TREE_CODE (type) == ARRAY_TYPE
7770 : 0 : && TYPE_NONALIASED_COMPONENT (type))
7771 : : {
7772 : 0 : target = copy_rtx (target);
7773 : 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7774 : : }
7775 : :
7776 : 0 : store_constructor_field
7777 : 0 : (target, bitsize, bitpos, 0, bitregion_end,
7778 : : mode, value, cleared,
7779 : : get_alias_set (elttype), reverse);
7780 : : }
7781 : : }
7782 : : else
7783 : : {
7784 : 0 : rtx_code_label *loop_start = gen_label_rtx ();
7785 : 0 : rtx_code_label *loop_end = gen_label_rtx ();
7786 : 0 : tree exit_cond;
7787 : :
7788 : 0 : expand_normal (hi_index);
7789 : :
7790 : 0 : index = build_decl (EXPR_LOCATION (exp),
7791 : : VAR_DECL, NULL_TREE, domain);
7792 : 0 : index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
7793 : 0 : SET_DECL_RTL (index, index_r);
7794 : 0 : store_expr (lo_index, index_r, 0, false, reverse);
7795 : :
7796 : : /* Build the head of the loop. */
7797 : 0 : do_pending_stack_adjust ();
7798 : 0 : emit_label (loop_start);
7799 : :
7800 : : /* Assign value to element index. */
7801 : 0 : offset = fold_build2 (MINUS_EXPR,
7802 : : TREE_TYPE (index),
7803 : : index,
7804 : : TYPE_MIN_VALUE (domain));
7805 : :
7806 : 0 : offset = size_binop (MULT_EXPR,
7807 : : fold_convert (sizetype, offset),
7808 : : TYPE_SIZE_UNIT (elttype));
7809 : :
7810 : 0 : xtarget = offset_address (target,
7811 : : expand_normal (offset),
7812 : : highest_pow2_factor (offset));
7813 : 0 : xtarget = adjust_address (xtarget, mode, 0);
7814 : 0 : if (TREE_CODE (value) == CONSTRUCTOR)
7815 : 0 : store_constructor (value, xtarget, cleared,
7816 : : exact_div (bitsize, BITS_PER_UNIT),
7817 : : reverse);
7818 : : else
7819 : 0 : store_expr (value, xtarget, 0, false, reverse);
7820 : :
7821 : : /* Generate a conditional jump to exit the loop. */
7822 : 0 : exit_cond = build2 (LT_EXPR, integer_type_node,
7823 : : index, hi_index);
7824 : 0 : jumpif (exit_cond, loop_end,
7825 : : profile_probability::uninitialized ());
7826 : :
7827 : : /* Update the loop counter, and jump to the head of
7828 : : the loop. */
7829 : 0 : expand_assignment (index,
7830 : 0 : build2 (PLUS_EXPR, TREE_TYPE (index),
7831 : : index, integer_one_node),
7832 : : false);
7833 : :
7834 : 0 : emit_jump (loop_start);
7835 : :
7836 : : /* Build the end of the loop. */
7837 : 0 : emit_label (loop_end);
7838 : : }
7839 : : }
7840 : 392 : else if ((index && !tree_fits_uhwi_p (index))
7841 : 392 : || !tree_fits_uhwi_p (TYPE_SIZE (elttype)))
7842 : : {
7843 : 0 : tree offset;
7844 : :
7845 : 0 : if (index)
7846 : 0 : offset = fold_build2 (MINUS_EXPR,
7847 : : TREE_TYPE (index),
7848 : : index,
7849 : : TYPE_MIN_VALUE (domain));
7850 : : else
7851 : 0 : offset = size_int (i);
7852 : :
7853 : 0 : offset = size_binop (MULT_EXPR,
7854 : : fold_convert (sizetype, offset),
7855 : : TYPE_SIZE_UNIT (elttype));
7856 : 0 : xtarget = offset_address (target,
7857 : : expand_normal (offset),
7858 : : highest_pow2_factor (offset));
7859 : 0 : xtarget = adjust_address (xtarget, mode, 0);
7860 : 0 : store_expr (value, xtarget, 0, false, reverse);
7861 : : }
7862 : : else
7863 : : {
7864 : 392 : if (index)
7865 : 784 : bitpos = ((tree_to_uhwi (index) - minelt)
7866 : 392 : * tree_to_uhwi (TYPE_SIZE (elttype)));
7867 : : else
7868 : 0 : bitpos = (i * tree_to_uhwi (TYPE_SIZE (elttype)));
7869 : :
7870 : 56 : if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
7871 : 56 : && TREE_CODE (type) == ARRAY_TYPE
7872 : 448 : && TYPE_NONALIASED_COMPONENT (type))
7873 : : {
7874 : 0 : target = copy_rtx (target);
7875 : 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7876 : : }
7877 : 392 : store_constructor_field (target, bitsize, bitpos, 0,
7878 : 392 : bitregion_end, mode, value,
7879 : : cleared, get_alias_set (elttype),
7880 : : reverse);
7881 : : }
7882 : : }
7883 : : break;
7884 : : }
7885 : :
7886 : 137666 : case VECTOR_TYPE:
7887 : 137666 : {
7888 : 137666 : unsigned HOST_WIDE_INT idx;
7889 : 137666 : constructor_elt *ce;
7890 : 137666 : bool need_to_clear;
7891 : 137666 : insn_code icode = CODE_FOR_nothing;
7892 : 137666 : tree elt;
7893 : 137666 : tree elttype = TREE_TYPE (type);
7894 : 137666 : int elt_size = vector_element_bits (type);
7895 : 137666 : machine_mode eltmode = TYPE_MODE (elttype);
7896 : 137666 : poly_int64 bitsize;
7897 : 137666 : poly_int64 bitpos;
7898 : 137666 : rtvec vector = NULL;
7899 : 137666 : poly_uint64 n_elts;
7900 : 137666 : unsigned HOST_WIDE_INT const_n_elts;
7901 : 137666 : alias_set_type alias;
7902 : 137666 : bool vec_vec_init_p = false;
7903 : 137666 : machine_mode mode = GET_MODE (target);
7904 : :
7905 : 137666 : gcc_assert (eltmode != BLKmode);
7906 : :
7907 : : /* Try using vec_duplicate_optab for uniform vectors. */
7908 : 137666 : icode = optab_handler (vec_duplicate_optab, mode);
7909 : 137666 : if (!TREE_SIDE_EFFECTS (exp)
7910 : 137666 : && VECTOR_MODE_P (mode)
7911 : 134529 : && icode != CODE_FOR_nothing
7912 : : /* If the vec_duplicate target pattern does not specify an element
7913 : : mode check that eltmode is the normal inner mode of the
7914 : : requested vector mode. But if the target allows eltmode
7915 : : explicitly go ahead and use it. */
7916 : 94137 : && (eltmode == GET_MODE_INNER (mode)
7917 : 0 : || insn_data[icode].operand[1].mode == eltmode)
7918 : 94137 : && (elt = uniform_vector_p (exp))
7919 : 154195 : && !VECTOR_TYPE_P (TREE_TYPE (elt)))
7920 : : {
7921 : 16529 : class expand_operand ops[2];
7922 : 16529 : create_output_operand (&ops[0], target, mode);
7923 : 16529 : create_input_operand (&ops[1], expand_normal (elt), eltmode);
7924 : 16529 : expand_insn (icode, 2, ops);
7925 : 16529 : if (!rtx_equal_p (target, ops[0].value))
7926 : 0 : emit_move_insn (target, ops[0].value);
7927 : 16529 : break;
7928 : : }
7929 : : /* Use sign-extension for uniform boolean vectors with
7930 : : integer modes and single-bit mask entries.
7931 : : Effectively "vec_duplicate" for bitmasks. */
7932 : 121137 : if (elt_size == 1
7933 : 144 : && !TREE_SIDE_EFFECTS (exp)
7934 : 144 : && VECTOR_BOOLEAN_TYPE_P (type)
7935 : 144 : && SCALAR_INT_MODE_P (TYPE_MODE (type))
7936 : 144 : && (elt = uniform_vector_p (exp))
7937 : 121280 : && !VECTOR_TYPE_P (TREE_TYPE (elt)))
7938 : : {
7939 : 143 : rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
7940 : : expand_normal (elt));
7941 : 143 : rtx tmp = gen_reg_rtx (mode);
7942 : 143 : convert_move (tmp, op0, 0);
7943 : :
7944 : : /* Ensure no excess bits are set.
7945 : : GCN needs this for nunits < 64.
7946 : : x86 needs this for nunits < 8. */
7947 : 143 : auto nunits = TYPE_VECTOR_SUBPARTS (type).to_constant ();
7948 : 143 : if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
7949 : 2 : tmp = expand_binop (mode, and_optab, tmp,
7950 : 2 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
7951 : : target, true, OPTAB_WIDEN);
7952 : 143 : if (tmp != target)
7953 : 141 : emit_move_insn (target, tmp);
7954 : : break;
7955 : : }
7956 : :
7957 : 120994 : n_elts = TYPE_VECTOR_SUBPARTS (type);
7958 : 120994 : if (REG_P (target)
7959 : 118171 : && VECTOR_MODE_P (mode))
7960 : : {
7961 : 118000 : const_n_elts = 0;
7962 : 118000 : if (CONSTRUCTOR_NELTS (exp)
7963 : 118000 : && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
7964 : : == VECTOR_TYPE))
7965 : : {
7966 : 1079 : tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
7967 : 1079 : gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
7968 : : * TYPE_VECTOR_SUBPARTS (etype),
7969 : : n_elts));
7970 : :
7971 : 3237 : icode = convert_optab_handler (vec_init_optab, mode,
7972 : 1079 : TYPE_MODE (etype));
7973 : 1079 : const_n_elts = CONSTRUCTOR_NELTS (exp);
7974 : 1079 : vec_vec_init_p = icode != CODE_FOR_nothing;
7975 : : }
7976 : 233842 : else if (exact_div (n_elts, GET_MODE_NUNITS (eltmode))
7977 : 116921 : .is_constant (&const_n_elts))
7978 : : {
7979 : : /* For a non-const type vector, we check it is made up of
7980 : : similarly non-const type vectors. */
7981 : 116921 : icode = convert_optab_handler (vec_init_optab, mode, eltmode);
7982 : : }
7983 : :
7984 : 118000 : if (const_n_elts && icode != CODE_FOR_nothing)
7985 : : {
7986 : 117037 : vector = rtvec_alloc (const_n_elts);
7987 : 431081 : for (unsigned int k = 0; k < const_n_elts; k++)
7988 : 314044 : RTVEC_ELT (vector, k) = CONST0_RTX (eltmode);
7989 : : }
7990 : : }
7991 : :
7992 : : /* Compute the size of the elements in the CTOR. It differs
7993 : : from the size of the vector type elements only when the
7994 : : CTOR elements are vectors themselves. */
7995 : 120994 : tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
7996 : 120994 : ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
7997 : 120994 : : elttype);
7998 : 120994 : if (VECTOR_TYPE_P (val_type))
7999 : 1367 : bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
8000 : : else
8001 : 119627 : bitsize = elt_size;
8002 : :
8003 : : /* If the constructor has fewer elements than the vector,
8004 : : clear the whole array first. Similarly if this is static
8005 : : constructor of a non-BLKmode object. */
8006 : 120994 : if (cleared)
8007 : : need_to_clear = false;
8008 : 120994 : else if (REG_P (target) && TREE_STATIC (exp))
8009 : : need_to_clear = true;
8010 : : else
8011 : : {
8012 : : poly_uint64 count = 0, zero_count = 0;
8013 : : tree value;
8014 : :
8015 : 472253 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
8016 : : {
8017 : 351259 : poly_int64 n_elts_here = exact_div (bitsize, elt_size);
8018 : 351259 : count += n_elts_here;
8019 : 351259 : if (mostly_zeros_p (value))
8020 : 351259 : zero_count += n_elts_here;
8021 : : }
8022 : :
8023 : : /* Clear the entire vector first if there are any missing elements,
8024 : : or if the incidence of zero elements is >= 75%. */
8025 : 120994 : need_to_clear = (maybe_lt (count, n_elts)
8026 : 120994 : || maybe_gt (4 * zero_count, 3 * count));
8027 : : }
8028 : :
8029 : 982 : if (need_to_clear && maybe_gt (size, 0) && !vector)
8030 : : {
8031 : 628 : if (REG_P (target))
8032 : 1 : emit_move_insn (target, CONST0_RTX (mode));
8033 : : else
8034 : 627 : clear_storage (target, gen_int_mode (size, Pmode),
8035 : : BLOCK_OP_NORMAL);
8036 : : cleared = 1;
8037 : : }
8038 : :
8039 : : /* Inform later passes that the old value is dead. */
8040 : 120994 : if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
8041 : : {
8042 : 484 : emit_move_insn (target, CONST0_RTX (mode));
8043 : 484 : cleared = 1;
8044 : : }
8045 : :
8046 : 120994 : if (MEM_P (target))
8047 : 2823 : alias = MEM_ALIAS_SET (target);
8048 : : else
8049 : 118171 : alias = get_alias_set (elttype);
8050 : :
8051 : : /* Store each element of the constructor into the corresponding
8052 : : element of TARGET, determined by counting the elements. */
8053 : 120994 : HOST_WIDE_INT chunk_size = 0;
8054 : 120994 : bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
8055 : : &chunk_size);
8056 : 120994 : gcc_assert (chunk_multiple_p || vec_vec_init_p);
8057 : :
8058 : 472253 : for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
8059 : : idx++)
8060 : : {
8061 : 351259 : HOST_WIDE_INT eltpos;
8062 : 351259 : tree value = ce->value;
8063 : :
8064 : 351259 : if (cleared && initializer_zerop (value))
8065 : 6424 : continue;
8066 : :
8067 : 344835 : if (ce->index)
8068 : 42724 : eltpos = tree_to_uhwi (ce->index);
8069 : : else
8070 : 302111 : eltpos = idx * chunk_size;
8071 : :
8072 : 344835 : if (vector)
8073 : : {
8074 : 313101 : if (vec_vec_init_p)
8075 : : {
8076 : 2138 : gcc_assert (ce->index == NULL_TREE);
8077 : 2138 : gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
8078 : 2138 : eltpos = idx;
8079 : : }
8080 : : else
8081 : 310963 : gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
8082 : 313101 : RTVEC_ELT (vector, eltpos) = expand_normal (value);
8083 : : }
8084 : : else
8085 : : {
8086 : 31734 : machine_mode value_mode
8087 : 31734 : = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
8088 : 31734 : ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
8089 : 31734 : bitpos = eltpos * elt_size;
8090 : 31734 : store_constructor_field (target, bitsize, bitpos, 0,
8091 : 31734 : bitregion_end, value_mode,
8092 : : value, cleared, alias, reverse);
8093 : : }
8094 : : }
8095 : :
8096 : 120994 : if (vector)
8097 : 117037 : emit_insn (GEN_FCN (icode) (target,
8098 : : gen_rtx_PARALLEL (mode, vector)));
8099 : : break;
8100 : : }
8101 : :
8102 : 0 : default:
8103 : 0 : gcc_unreachable ();
8104 : : }
8105 : 242812 : }
8106 : :
8107 : : /* Store the value of EXP (an expression tree)
8108 : : into a subfield of TARGET which has mode MODE and occupies
8109 : : BITSIZE bits, starting BITPOS bits from the start of TARGET.
8110 : : If MODE is VOIDmode, it means that we are storing into a bit-field.
8111 : :
8112 : : BITREGION_START is bitpos of the first bitfield in this region.
8113 : : BITREGION_END is the bitpos of the ending bitfield in this region.
8114 : : These two fields are 0, if the C++ memory model does not apply,
8115 : : or we are not interested in keeping track of bitfield regions.
8116 : :
8117 : : Always return const0_rtx unless we have something particular to
8118 : : return.
8119 : :
8120 : : ALIAS_SET is the alias set for the destination. This value will
8121 : : (in general) be different from that for TARGET, since TARGET is a
8122 : : reference to the containing structure.
8123 : :
8124 : : If NONTEMPORAL is true, try generating a nontemporal store.
8125 : :
8126 : : If REVERSE is true, the store is to be done in reverse order. */
8127 : :
8128 : : static rtx
8129 : 4695264 : store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
8130 : : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
8131 : : machine_mode mode, tree exp,
8132 : : alias_set_type alias_set, bool nontemporal, bool reverse)
8133 : : {
8134 : 4695264 : if (TREE_CODE (exp) == ERROR_MARK)
8135 : 0 : return const0_rtx;
8136 : :
8137 : : /* If we have nothing to store, do nothing unless the expression has
8138 : : side-effects. Don't do that for zero sized addressable lhs of
8139 : : calls. */
8140 : 4695264 : if (known_eq (bitsize, 0)
8141 : 4695264 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8142 : 3 : || TREE_CODE (exp) != CALL_EXPR))
8143 : 0 : return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
8144 : :
8145 : 4695264 : if (GET_CODE (target) == CONCAT)
8146 : : {
8147 : : /* We're storing into a struct containing a single __complex. */
8148 : :
8149 : 0 : gcc_assert (known_eq (bitpos, 0));
8150 : 0 : return store_expr (exp, target, 0, nontemporal, reverse);
8151 : : }
8152 : :
8153 : : /* If the structure is in a register or if the component
8154 : : is a bit field, we cannot use addressing to access it.
8155 : : Use bit-field techniques or SUBREG to store in it. */
8156 : :
8157 : 4695264 : poly_int64 decl_bitsize;
8158 : 4695264 : if (mode == VOIDmode
8159 : 4626426 : || (mode != BLKmode && ! direct_store[(int) mode]
8160 : 5443 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
8161 : 5441 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
8162 : 4621018 : || REG_P (target)
8163 : 3910417 : || GET_CODE (target) == SUBREG
8164 : : /* If the field isn't aligned enough to store as an ordinary memref,
8165 : : store it as a bit field. */
8166 : 3910417 : || (mode != BLKmode
8167 : 3794264 : && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
8168 : 7502550 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
8169 : 45769 : && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
8170 : 3794264 : || !multiple_p (bitpos, BITS_PER_UNIT)))
8171 : 3910417 : || (known_size_p (bitsize)
8172 : 3910405 : && mode != BLKmode
8173 : 3794264 : && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
8174 : : /* If the RHS and field are a constant size and the size of the
8175 : : RHS isn't the same size as the bitfield, we must use bitfield
8176 : : operations. */
8177 : 3910408 : || (known_size_p (bitsize)
8178 : 3910396 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
8179 : 3910396 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
8180 : : bitsize)
8181 : : /* Except for initialization of full bytes from a CONSTRUCTOR, which
8182 : : we will handle specially below. */
8183 : 29 : && !(TREE_CODE (exp) == CONSTRUCTOR
8184 : 11 : && multiple_p (bitsize, BITS_PER_UNIT))
8185 : : /* And except for bitwise copying of TREE_ADDRESSABLE types,
8186 : : where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
8187 : : includes some extra padding. store_expr / expand_expr will in
8188 : : that case call get_inner_reference that will have the bitsize
8189 : : we check here and thus the block move will not clobber the
8190 : : padding that shouldn't be clobbered. In the future we could
8191 : : replace the TREE_ADDRESSABLE check with a check that
8192 : : get_base_address needs to live in memory. */
8193 : 18 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8194 : 9 : || TREE_CODE (exp) != COMPONENT_REF
8195 : 6 : || !multiple_p (bitsize, BITS_PER_UNIT)
8196 : 6 : || !multiple_p (bitpos, BITS_PER_UNIT)
8197 : 6 : || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
8198 : : &decl_bitsize)
8199 : 6 : || maybe_ne (decl_bitsize, bitsize))
8200 : : /* A call with an addressable return type and return-slot
8201 : : optimization must not need bitfield operations but we must
8202 : : pass down the original target. */
8203 : 12 : && (TREE_CODE (exp) != CALL_EXPR
8204 : 6 : || !TREE_ADDRESSABLE (TREE_TYPE (exp))
8205 : 0 : || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
8206 : : /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
8207 : : decl we must use bitfield operations. */
8208 : 8605660 : || (known_size_p (bitsize)
8209 : 3910384 : && TREE_CODE (exp) == MEM_REF
8210 : 29147 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
8211 : 23107 : && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8212 : 18771 : && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8213 : 5121 : && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
8214 : : {
8215 : 785069 : rtx temp;
8216 : 785069 : gimple *nop_def;
8217 : :
8218 : : /* If EXP is a NOP_EXPR of precision less than its mode, then that
8219 : : implies a mask operation. If the precision is the same size as
8220 : : the field we're storing into, that mask is redundant. This is
8221 : : particularly common with bit field assignments generated by the
8222 : : C front end. */
8223 : 785069 : nop_def = get_def_for_expr (exp, NOP_EXPR);
8224 : 785069 : if (nop_def)
8225 : : {
8226 : 8834 : tree type = TREE_TYPE (exp);
8227 : 8834 : if (INTEGRAL_TYPE_P (type)
8228 : 8538 : && maybe_ne (TYPE_PRECISION (type),
8229 : 17076 : GET_MODE_BITSIZE (TYPE_MODE (type)))
8230 : 12566 : && known_eq (bitsize, TYPE_PRECISION (type)))
8231 : : {
8232 : 3630 : tree op = gimple_assign_rhs1 (nop_def);
8233 : 3630 : type = TREE_TYPE (op);
8234 : 3630 : if (INTEGRAL_TYPE_P (type)
8235 : 3630 : && known_ge (TYPE_PRECISION (type), bitsize))
8236 : : exp = op;
8237 : : }
8238 : : }
8239 : :
8240 : 785069 : temp = expand_normal (exp);
8241 : :
8242 : : /* We don't support variable-sized BLKmode bitfields, since our
8243 : : handling of BLKmode is bound up with the ability to break
8244 : : things into words. */
8245 : 785069 : gcc_assert (mode != BLKmode || bitsize.is_constant ());
8246 : :
8247 : : /* Handle calls that return values in multiple non-contiguous locations.
8248 : : The Irix 6 ABI has examples of this. */
8249 : 785069 : if (GET_CODE (temp) == PARALLEL)
8250 : : {
8251 : 6 : HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
8252 : 6 : machine_mode temp_mode = GET_MODE (temp);
8253 : 6 : if (temp_mode == BLKmode || temp_mode == VOIDmode)
8254 : 6 : temp_mode
8255 : 6 : = smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
8256 : 6 : rtx temp_target = gen_reg_rtx (temp_mode);
8257 : 6 : emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
8258 : 6 : temp = temp_target;
8259 : : }
8260 : :
8261 : : /* Handle calls that return BLKmode values in registers. */
8262 : 785063 : else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
8263 : : {
8264 : 0 : rtx temp_target = gen_reg_rtx (GET_MODE (temp));
8265 : 0 : copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
8266 : 0 : temp = temp_target;
8267 : : }
8268 : :
8269 : : /* If the value has aggregate type and an integral mode then, if BITSIZE
8270 : : is narrower than this mode and this is for big-endian data, we first
8271 : : need to put the value into the low-order bits for store_bit_field,
8272 : : except when MODE is BLKmode and BITSIZE larger than the word size
8273 : : (see the handling of fields larger than a word in store_bit_field).
8274 : : Moreover, the field may be not aligned on a byte boundary; in this
8275 : : case, if it has reverse storage order, it needs to be accessed as a
8276 : : scalar field with reverse storage order and we must first put the
8277 : : value into target order. */
8278 : 785069 : scalar_int_mode temp_mode;
8279 : 1567890 : if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
8280 : 786746 : && is_int_mode (GET_MODE (temp), &temp_mode))
8281 : : {
8282 : 3657 : HOST_WIDE_INT size = GET_MODE_BITSIZE (temp_mode);
8283 : :
8284 : 3657 : reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
8285 : :
8286 : 3657 : if (reverse)
8287 : 0 : temp = flip_storage_order (temp_mode, temp);
8288 : :
8289 : 3657 : gcc_checking_assert (known_le (bitsize, size));
8290 : 3657 : if (maybe_lt (bitsize, size)
8291 : 3657 : && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
8292 : : /* Use of to_constant for BLKmode was checked above. */
8293 : : && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
8294 : 0 : temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
8295 : : size - bitsize, NULL_RTX, 1);
8296 : : }
8297 : :
8298 : : /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE. */
8299 : 716231 : if (mode != VOIDmode && mode != BLKmode
8300 : 1501043 : && mode != TYPE_MODE (TREE_TYPE (exp)))
8301 : 4 : temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
8302 : :
8303 : : /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
8304 : : and BITPOS must be aligned on a byte boundary. If so, we simply do
8305 : : a block copy. Likewise for a BLKmode-like TARGET. */
8306 : 785069 : if (GET_MODE (temp) == BLKmode
8307 : 785069 : && (GET_MODE (target) == BLKmode
8308 : 173 : || (MEM_P (target)
8309 : 0 : && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
8310 : 0 : && multiple_p (bitpos, BITS_PER_UNIT)
8311 : 0 : && multiple_p (bitsize, BITS_PER_UNIT))))
8312 : : {
8313 : 78 : gcc_assert (MEM_P (target) && MEM_P (temp));
8314 : 78 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
8315 : 78 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
8316 : :
8317 : 78 : target = adjust_address (target, VOIDmode, bytepos);
8318 : 78 : emit_block_move (target, temp,
8319 : 78 : gen_int_mode (bytesize, Pmode),
8320 : : BLOCK_OP_NORMAL);
8321 : :
8322 : 78 : return const0_rtx;
8323 : : }
8324 : :
8325 : : /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
8326 : : word size, we need to load the value (see again store_bit_field). */
8327 : 785009 : if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
8328 : : {
8329 : 61 : temp_mode = smallest_int_mode_for_size (bitsize).require ();
8330 : 61 : temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
8331 : : temp_mode, false, NULL);
8332 : : }
8333 : :
8334 : : /* Store the value in the bitfield. */
8335 : 784991 : gcc_checking_assert (known_ge (bitpos, 0));
8336 : 784991 : store_bit_field (target, bitsize, bitpos,
8337 : : bitregion_start, bitregion_end,
8338 : : mode, temp, reverse, false);
8339 : :
8340 : 784991 : return const0_rtx;
8341 : : }
8342 : : else
8343 : : {
8344 : : /* Now build a reference to just the desired component. */
8345 : 3910195 : rtx to_rtx = adjust_address (target, mode,
8346 : : exact_div (bitpos, BITS_PER_UNIT));
8347 : :
8348 : 3910195 : if (to_rtx == target)
8349 : 1265440 : to_rtx = copy_rtx (to_rtx);
8350 : :
8351 : 7560680 : if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
8352 : 3392409 : set_mem_alias_set (to_rtx, alias_set);
8353 : :
8354 : : /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
8355 : : into a target smaller than its type; handle that case now. */
8356 : 3910195 : if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (bitsize))
8357 : : {
8358 : 68422 : poly_int64 bytesize = exact_div (bitsize, BITS_PER_UNIT);
8359 : 68422 : store_constructor (exp, to_rtx, 0, bytesize, reverse);
8360 : 68422 : return to_rtx;
8361 : : }
8362 : :
8363 : 3841773 : return store_expr (exp, to_rtx, 0, nontemporal, reverse);
8364 : : }
8365 : : }
8366 : :
8367 : : /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
8368 : : an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
8369 : : codes and find the ultimate containing object, which we return.
8370 : :
8371 : : We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
8372 : : bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
8373 : : storage order of the field.
8374 : : If the position of the field is variable, we store a tree
8375 : : giving the variable offset (in units) in *POFFSET.
8376 : : This offset is in addition to the bit position.
8377 : : If the position is not variable, we store 0 in *POFFSET.
8378 : :
8379 : : If any of the extraction expressions is volatile,
8380 : : we store 1 in *PVOLATILEP. Otherwise we don't change that.
8381 : :
8382 : : If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
8383 : : Otherwise, it is a mode that can be used to access the field.
8384 : :
8385 : : If the field describes a variable-sized object, *PMODE is set to
8386 : : BLKmode and *PBITSIZE is set to -1. An access cannot be made in
8387 : : this case, but the address of the object can be found. */
8388 : :
8389 : : tree
8390 : 221983551 : get_inner_reference (tree exp, poly_int64 *pbitsize,
8391 : : poly_int64 *pbitpos, tree *poffset,
8392 : : machine_mode *pmode, int *punsignedp,
8393 : : int *preversep, int *pvolatilep)
8394 : : {
8395 : 221983551 : tree size_tree = 0;
8396 : 221983551 : machine_mode mode = VOIDmode;
8397 : 221983551 : bool blkmode_bitfield = false;
8398 : 221983551 : tree offset = size_zero_node;
8399 : 221983551 : poly_offset_int bit_offset = 0;
8400 : :
8401 : : /* First get the mode, signedness, storage order and size. We do this from
8402 : : just the outermost expression. */
8403 : 221983551 : *pbitsize = -1;
8404 : 221983551 : if (TREE_CODE (exp) == COMPONENT_REF)
8405 : : {
8406 : 85988390 : tree field = TREE_OPERAND (exp, 1);
8407 : 85988390 : size_tree = DECL_SIZE (field);
8408 : 85988390 : if (flag_strict_volatile_bitfields > 0
8409 : 58 : && TREE_THIS_VOLATILE (exp)
8410 : 40 : && DECL_BIT_FIELD_TYPE (field)
8411 : 85988412 : && DECL_MODE (field) != BLKmode)
8412 : : /* Volatile bitfields should be accessed in the mode of the
8413 : : field's type, not the mode computed based on the bit
8414 : : size. */
8415 : 22 : mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
8416 : 85988368 : else if (!DECL_BIT_FIELD (field))
8417 : : {
8418 : 84513226 : mode = DECL_MODE (field);
8419 : : /* For vector fields re-check the target flags, as DECL_MODE
8420 : : could have been set with different target flags than
8421 : : the current function has. */
8422 : 84513226 : if (VECTOR_TYPE_P (TREE_TYPE (field))
8423 : 84513226 : && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
8424 : 317065 : mode = TYPE_MODE (TREE_TYPE (field));
8425 : : }
8426 : 1475142 : else if (DECL_MODE (field) == BLKmode)
8427 : 628 : blkmode_bitfield = true;
8428 : :
8429 : 85988390 : *punsignedp = DECL_UNSIGNED (field);
8430 : : }
8431 : 135995161 : else if (TREE_CODE (exp) == BIT_FIELD_REF)
8432 : : {
8433 : 581906 : size_tree = TREE_OPERAND (exp, 1);
8434 : 1163425 : *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
8435 : 1025671 : || TYPE_UNSIGNED (TREE_TYPE (exp)));
8436 : :
8437 : : /* For vector element types with the correct size of access or for
8438 : : vector typed accesses use the mode of the access type. */
8439 : 581906 : if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
8440 : 415833 : && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
8441 : 376809 : && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
8442 : 620933 : || VECTOR_TYPE_P (TREE_TYPE (exp)))
8443 : 396978 : mode = TYPE_MODE (TREE_TYPE (exp));
8444 : : }
8445 : : else
8446 : : {
8447 : 135413255 : mode = TYPE_MODE (TREE_TYPE (exp));
8448 : 135413255 : *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
8449 : :
8450 : 135413255 : if (mode == BLKmode)
8451 : 55321758 : size_tree = TYPE_SIZE (TREE_TYPE (exp));
8452 : : else
8453 : 160182994 : *pbitsize = GET_MODE_BITSIZE (mode);
8454 : : }
8455 : :
8456 : 221983551 : if (size_tree != 0)
8457 : : {
8458 : 141221974 : if (!poly_int_tree_p (size_tree, pbitsize))
8459 : 328137 : mode = BLKmode, *pbitsize = -1;
8460 : : }
8461 : :
8462 : 221983551 : *preversep = reverse_storage_order_for_component_p (exp);
8463 : :
8464 : : /* Compute cumulative bit-offset for nested component-refs and array-refs,
8465 : : and find the ultimate containing object. */
8466 : 522768899 : while (1)
8467 : : {
8468 : 372376225 : switch (TREE_CODE (exp))
8469 : : {
8470 : 581906 : case BIT_FIELD_REF:
8471 : 581906 : bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
8472 : 581906 : break;
8473 : :
8474 : 120274835 : case COMPONENT_REF:
8475 : 120274835 : {
8476 : 120274835 : tree field = TREE_OPERAND (exp, 1);
8477 : 120274835 : tree this_offset = component_ref_field_offset (exp);
8478 : :
8479 : : /* If this field hasn't been filled in yet, don't go past it.
8480 : : This should only happen when folding expressions made during
8481 : : type construction. */
8482 : 120274835 : if (this_offset == 0)
8483 : : break;
8484 : :
8485 : 120274835 : offset = size_binop (PLUS_EXPR, offset, this_offset);
8486 : 120274835 : bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
8487 : :
8488 : : /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */
8489 : : }
8490 : 120274835 : break;
8491 : :
8492 : 27229174 : case ARRAY_REF:
8493 : 27229174 : case ARRAY_RANGE_REF:
8494 : 27229174 : {
8495 : 27229174 : tree index = TREE_OPERAND (exp, 1);
8496 : 27229174 : tree low_bound = array_ref_low_bound (exp);
8497 : 27229174 : tree unit_size = array_ref_element_size (exp);
8498 : :
8499 : : /* We assume all arrays have sizes that are a multiple of a byte.
8500 : : First subtract the lower bound, if any, in the type of the
8501 : : index, then convert to sizetype and multiply by the size of
8502 : : the array element. */
8503 : 27229174 : if (! integer_zerop (low_bound))
8504 : 772885 : index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
8505 : : index, low_bound);
8506 : :
8507 : 27229174 : offset = size_binop (PLUS_EXPR, offset,
8508 : : size_binop (MULT_EXPR,
8509 : : fold_convert (sizetype, index),
8510 : : unit_size));
8511 : : }
8512 : 27229174 : break;
8513 : :
8514 : : case REALPART_EXPR:
8515 : : break;
8516 : :
8517 : : case IMAGPART_EXPR:
8518 : 150392674 : bit_offset += *pbitsize;
8519 : : break;
8520 : :
8521 : : case VIEW_CONVERT_EXPR:
8522 : : break;
8523 : :
8524 : 84349824 : case MEM_REF:
8525 : : /* Hand back the decl for MEM[&decl, off]. */
8526 : 84349824 : if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
8527 : : {
8528 : 18988706 : tree off = TREE_OPERAND (exp, 1);
8529 : 18988706 : if (!integer_zerop (off))
8530 : : {
8531 : 10520289 : poly_offset_int boff = mem_ref_offset (exp);
8532 : 10520289 : boff <<= LOG2_BITS_PER_UNIT;
8533 : 10520289 : bit_offset += boff;
8534 : : }
8535 : 18988706 : exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8536 : : }
8537 : 84349824 : goto done;
8538 : :
8539 : 137633727 : default:
8540 : 137633727 : goto done;
8541 : : }
8542 : :
8543 : : /* If any reference in the chain is volatile, the effect is volatile. */
8544 : 150392674 : if (TREE_THIS_VOLATILE (exp))
8545 : 452130 : *pvolatilep = 1;
8546 : :
8547 : 150392674 : exp = TREE_OPERAND (exp, 0);
8548 : 150392674 : }
8549 : 221983551 : done:
8550 : :
8551 : : /* If OFFSET is constant, see if we can return the whole thing as a
8552 : : constant bit position. Make sure to handle overflow during
8553 : : this conversion. */
8554 : 221983551 : if (poly_int_tree_p (offset))
8555 : : {
8556 : 208508750 : poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
8557 : 208508750 : TYPE_PRECISION (sizetype));
8558 : 208508750 : tem <<= LOG2_BITS_PER_UNIT;
8559 : 208508750 : tem += bit_offset;
8560 : 208508750 : if (tem.to_shwi (pbitpos))
8561 : 208507373 : *poffset = offset = NULL_TREE;
8562 : : }
8563 : :
8564 : : /* Otherwise, split it up. */
8565 : 208508750 : if (offset)
8566 : : {
8567 : : /* Avoid returning a negative bitpos as this may wreak havoc later. */
8568 : 13476178 : if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
8569 : : {
8570 : 293 : *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
8571 : 293 : poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
8572 : 293 : offset = size_binop (PLUS_EXPR, offset,
8573 : : build_int_cst (sizetype, bytes.force_shwi ()));
8574 : : }
8575 : :
8576 : 13476178 : *poffset = offset;
8577 : : }
8578 : :
8579 : : /* We can use BLKmode for a byte-aligned BLKmode bitfield. */
8580 : 221983551 : if (mode == VOIDmode
8581 : 1928922 : && blkmode_bitfield
8582 : 628 : && multiple_p (*pbitpos, BITS_PER_UNIT)
8583 : 221984039 : && multiple_p (*pbitsize, BITS_PER_UNIT))
8584 : 5 : *pmode = BLKmode;
8585 : : else
8586 : 221983546 : *pmode = mode;
8587 : :
8588 : 221983551 : return exp;
8589 : : }
8590 : :
8591 : : /* Alignment in bits the TARGET of an assignment may be assumed to have. */
8592 : :
8593 : : static unsigned HOST_WIDE_INT
8594 : 488628 : target_align (const_tree target)
8595 : : {
8596 : : /* We might have a chain of nested references with intermediate misaligning
8597 : : bitfields components, so need to recurse to find out. */
8598 : :
8599 : 488628 : unsigned HOST_WIDE_INT this_align, outer_align;
8600 : :
8601 : 488628 : switch (TREE_CODE (target))
8602 : : {
8603 : : case BIT_FIELD_REF:
8604 : : return 1;
8605 : :
8606 : 129553 : case COMPONENT_REF:
8607 : 129553 : this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
8608 : 129553 : outer_align = target_align (TREE_OPERAND (target, 0));
8609 : 129553 : return MIN (this_align, outer_align);
8610 : :
8611 : 182651 : case ARRAY_REF:
8612 : 182651 : case ARRAY_RANGE_REF:
8613 : 182651 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8614 : 182651 : outer_align = target_align (TREE_OPERAND (target, 0));
8615 : 182651 : return MIN (this_align, outer_align);
8616 : :
8617 : 4337 : CASE_CONVERT:
8618 : 4337 : case NON_LVALUE_EXPR:
8619 : 4337 : case VIEW_CONVERT_EXPR:
8620 : 4337 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8621 : 4337 : outer_align = target_align (TREE_OPERAND (target, 0));
8622 : 4337 : return MAX (this_align, outer_align);
8623 : :
8624 : 172083 : default:
8625 : 172083 : return TYPE_ALIGN (TREE_TYPE (target));
8626 : : }
8627 : : }
8628 : :
8629 : :
8630 : : /* Given an rtx VALUE that may contain additions and multiplications, return
8631 : : an equivalent value that just refers to a register, memory, or constant.
8632 : : This is done by generating instructions to perform the arithmetic and
8633 : : returning a pseudo-register containing the value.
8634 : :
8635 : : The returned value may be a REG, SUBREG, MEM or constant. */
8636 : :
8637 : : rtx
8638 : 30599031 : force_operand (rtx value, rtx target)
8639 : : {
8640 : 30599031 : rtx op1, op2;
8641 : : /* Use subtarget as the target for operand 0 of a binary operation. */
8642 : 30599031 : rtx subtarget = get_subtarget (target);
8643 : 30599031 : enum rtx_code code = GET_CODE (value);
8644 : :
8645 : : /* Check for subreg applied to an expression produced by loop optimizer. */
8646 : 30599031 : if (code == SUBREG
8647 : 240234 : && !REG_P (SUBREG_REG (value))
8648 : 123 : && !MEM_P (SUBREG_REG (value)))
8649 : : {
8650 : 123 : value
8651 : 123 : = simplify_gen_subreg (GET_MODE (value),
8652 : 123 : force_reg (GET_MODE (SUBREG_REG (value)),
8653 : : force_operand (SUBREG_REG (value),
8654 : : NULL_RTX)),
8655 : 123 : GET_MODE (SUBREG_REG (value)),
8656 : 123 : SUBREG_BYTE (value));
8657 : 123 : code = GET_CODE (value);
8658 : : }
8659 : :
8660 : : /* Check for a PIC address load. */
8661 : 30599031 : if ((code == PLUS || code == MINUS)
8662 : 3662571 : && XEXP (value, 0) == pic_offset_table_rtx
8663 : 1969 : && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
8664 : 1969 : || GET_CODE (XEXP (value, 1)) == LABEL_REF
8665 : 1969 : || GET_CODE (XEXP (value, 1)) == CONST))
8666 : : {
8667 : 220 : if (!subtarget)
8668 : 220 : subtarget = gen_reg_rtx (GET_MODE (value));
8669 : 220 : emit_move_insn (subtarget, value);
8670 : 220 : return subtarget;
8671 : : }
8672 : :
8673 : 30598811 : if (ARITHMETIC_P (value))
8674 : : {
8675 : 3773856 : op2 = XEXP (value, 1);
8676 : 3773856 : if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
8677 : 3773856 : subtarget = 0;
8678 : 3773856 : if (code == MINUS && CONST_INT_P (op2))
8679 : : {
8680 : 0 : code = PLUS;
8681 : 0 : op2 = negate_rtx (GET_MODE (value), op2);
8682 : : }
8683 : :
8684 : : /* Check for an addition with OP2 a constant integer and our first
8685 : : operand a PLUS of a virtual register and something else. In that
8686 : : case, we want to emit the sum of the virtual register and the
8687 : : constant first and then add the other value. This allows virtual
8688 : : register instantiation to simply modify the constant rather than
8689 : : creating another one around this addition. */
8690 : 3586135 : if (code == PLUS && CONST_INT_P (op2)
8691 : 3264167 : && GET_CODE (XEXP (value, 0)) == PLUS
8692 : 79819 : && REG_P (XEXP (XEXP (value, 0), 0))
8693 : 3803252 : && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
8694 : : {
8695 : 2519 : rtx temp = expand_simple_binop (GET_MODE (value), code,
8696 : : XEXP (XEXP (value, 0), 0), op2,
8697 : : subtarget, 0, OPTAB_LIB_WIDEN);
8698 : 2519 : return expand_simple_binop (GET_MODE (value), code, temp,
8699 : 2519 : force_operand (XEXP (XEXP (value,
8700 : : 0), 1), 0),
8701 : 2519 : target, 0, OPTAB_LIB_WIDEN);
8702 : : }
8703 : :
8704 : 3771337 : op1 = force_operand (XEXP (value, 0), subtarget);
8705 : 3771337 : op2 = force_operand (op2, NULL_RTX);
8706 : 3771337 : switch (code)
8707 : : {
8708 : 89093 : case MULT:
8709 : 89093 : return expand_mult (GET_MODE (value), op1, op2, target, 1);
8710 : 222 : case DIV:
8711 : 222 : if (!INTEGRAL_MODE_P (GET_MODE (value)))
8712 : 222 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8713 : 222 : target, 1, OPTAB_LIB_WIDEN);
8714 : : else
8715 : 0 : return expand_divmod (0,
8716 : : FLOAT_MODE_P (GET_MODE (value))
8717 : : ? RDIV_EXPR : TRUNC_DIV_EXPR,
8718 : 0 : GET_MODE (value), op1, op2, target, 0);
8719 : 0 : case MOD:
8720 : 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8721 : 0 : target, 0);
8722 : 383 : case UDIV:
8723 : 383 : return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
8724 : 383 : target, 1);
8725 : 0 : case UMOD:
8726 : 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8727 : 0 : target, 1);
8728 : 126 : case ASHIFTRT:
8729 : 126 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8730 : 126 : target, 0, OPTAB_LIB_WIDEN);
8731 : 3681513 : default:
8732 : 3681513 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8733 : 3681513 : target, 1, OPTAB_LIB_WIDEN);
8734 : : }
8735 : : }
8736 : 26824955 : if (UNARY_P (value))
8737 : : {
8738 : 16810 : if (!target)
8739 : 6582 : target = gen_reg_rtx (GET_MODE (value));
8740 : : /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
8741 : : while FIX with floating point mode rounds toward zero. So, some
8742 : : targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
8743 : : to express rounding toward zero during the conversion to int.
8744 : : expand_fix isn't able to handle that, it can only handle
8745 : : FIX/UNSIGNED_FIX from floating point mode to integral one. */
8746 : 16810 : if ((code == FIX || code == UNSIGNED_FIX)
8747 : 8 : && GET_CODE (XEXP (value, 0)) == FIX
8748 : 0 : && (GET_MODE (XEXP (value, 0))
8749 : 0 : == GET_MODE (XEXP (XEXP (value, 0), 0))))
8750 : 0 : op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
8751 : : else
8752 : 16810 : op1 = force_operand (XEXP (value, 0), NULL_RTX);
8753 : 16810 : switch (code)
8754 : : {
8755 : 4997 : case ZERO_EXTEND:
8756 : 4997 : case SIGN_EXTEND:
8757 : 4997 : case TRUNCATE:
8758 : 4997 : case FLOAT_EXTEND:
8759 : 4997 : case FLOAT_TRUNCATE:
8760 : 4997 : convert_move (target, op1, code == ZERO_EXTEND);
8761 : 4997 : return target;
8762 : :
8763 : 8 : case FIX:
8764 : 8 : case UNSIGNED_FIX:
8765 : 8 : expand_fix (target, op1, code == UNSIGNED_FIX);
8766 : 8 : return target;
8767 : :
8768 : 168 : case FLOAT:
8769 : 168 : case UNSIGNED_FLOAT:
8770 : 168 : expand_float (target, op1, code == UNSIGNED_FLOAT);
8771 : 168 : return target;
8772 : :
8773 : 11637 : default:
8774 : 11637 : return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
8775 : : }
8776 : : }
8777 : :
8778 : : #ifdef INSN_SCHEDULING
8779 : : /* On machines that have insn scheduling, we want all memory reference to be
8780 : : explicit, so we need to deal with such paradoxical SUBREGs. */
8781 : 26808145 : if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
8782 : 0 : value
8783 : 0 : = simplify_gen_subreg (GET_MODE (value),
8784 : 0 : force_reg (GET_MODE (SUBREG_REG (value)),
8785 : : force_operand (SUBREG_REG (value),
8786 : : NULL_RTX)),
8787 : : GET_MODE (SUBREG_REG (value)),
8788 : 0 : SUBREG_BYTE (value));
8789 : : #endif
8790 : :
8791 : : return value;
8792 : : }
8793 : :
8794 : : /* Subroutine of expand_expr: return true iff there is no way that
8795 : : EXP can reference X, which is being modified. TOP_P is nonzero if this
8796 : : call is going to be used to determine whether we need a temporary
8797 : : for EXP, as opposed to a recursive call to this function.
8798 : :
8799 : : It is always safe for this routine to return false since it merely
8800 : : searches for optimization opportunities. */
8801 : :
8802 : : bool
8803 : 8404380 : safe_from_p (const_rtx x, tree exp, int top_p)
8804 : : {
8805 : 8404396 : rtx exp_rtl = 0;
8806 : 8404396 : int i, nops;
8807 : :
8808 : 8404396 : if (x == 0
8809 : : /* If EXP has varying size, we MUST use a target since we currently
8810 : : have no way of allocating temporaries of variable size
8811 : : (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
8812 : : So we assume here that something at a higher level has prevented a
8813 : : clash. This is somewhat bogus, but the best we can do. Only
8814 : : do this when X is BLKmode and when we are at the top level. */
8815 : 1936323 : || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
8816 : 1807278 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
8817 : 0 : && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
8818 : 0 : || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
8819 : 0 : || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
8820 : : != INTEGER_CST)
8821 : 0 : && GET_MODE (x) == BLKmode)
8822 : : /* If X is in the outgoing argument area, it is always safe. */
8823 : 10340719 : || (MEM_P (x)
8824 : 182268 : && (XEXP (x, 0) == virtual_outgoing_args_rtx
8825 : 182268 : || (GET_CODE (XEXP (x, 0)) == PLUS
8826 : 134390 : && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
8827 : : return true;
8828 : :
8829 : : /* If this is a subreg of a hard register, declare it unsafe, otherwise,
8830 : : find the underlying pseudo. */
8831 : 1936323 : if (GET_CODE (x) == SUBREG)
8832 : : {
8833 : 0 : x = SUBREG_REG (x);
8834 : 0 : if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8835 : : return false;
8836 : : }
8837 : :
8838 : : /* Now look at our tree code and possibly recurse. */
8839 : 1936323 : switch (TREE_CODE_CLASS (TREE_CODE (exp)))
8840 : : {
8841 : 419 : case tcc_declaration:
8842 : 419 : exp_rtl = DECL_RTL_IF_SET (exp);
8843 : : break;
8844 : :
8845 : : case tcc_constant:
8846 : : return true;
8847 : :
8848 : 847895 : case tcc_exceptional:
8849 : 847895 : if (TREE_CODE (exp) == TREE_LIST)
8850 : : {
8851 : 0 : while (1)
8852 : : {
8853 : 0 : if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
8854 : : return false;
8855 : 0 : exp = TREE_CHAIN (exp);
8856 : 0 : if (!exp)
8857 : : return true;
8858 : 0 : if (TREE_CODE (exp) != TREE_LIST)
8859 : : return safe_from_p (x, exp, 0);
8860 : : }
8861 : : }
8862 : 847895 : else if (TREE_CODE (exp) == CONSTRUCTOR)
8863 : : {
8864 : : constructor_elt *ce;
8865 : : unsigned HOST_WIDE_INT idx;
8866 : :
8867 : 7718377 : FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
8868 : 3911 : if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
8869 : 128870 : || !safe_from_p (x, ce->value, 0))
8870 : 103686 : return false;
8871 : : return true;
8872 : : }
8873 : 708364 : else if (TREE_CODE (exp) == ERROR_MARK)
8874 : : return true; /* An already-visited SAVE_EXPR? */
8875 : : else
8876 : : return false;
8877 : :
8878 : 0 : case tcc_statement:
8879 : : /* The only case we look at here is the DECL_INITIAL inside a
8880 : : DECL_EXPR. */
8881 : 0 : return (TREE_CODE (exp) != DECL_EXPR
8882 : 0 : || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
8883 : 0 : || !DECL_INITIAL (DECL_EXPR_DECL (exp))
8884 : 0 : || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
8885 : :
8886 : 0 : case tcc_binary:
8887 : 0 : case tcc_comparison:
8888 : 0 : if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
8889 : : return false;
8890 : : /* Fall through. */
8891 : :
8892 : 16 : case tcc_unary:
8893 : 16 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
8894 : :
8895 : 266 : case tcc_expression:
8896 : 266 : case tcc_reference:
8897 : 266 : case tcc_vl_exp:
8898 : : /* Now do code-specific tests. EXP_RTL is set to any rtx we find in
8899 : : the expression. If it is set, we conflict iff we are that rtx or
8900 : : both are in memory. Otherwise, we check all operands of the
8901 : : expression recursively. */
8902 : :
8903 : 266 : switch (TREE_CODE (exp))
8904 : : {
8905 : 243 : case ADDR_EXPR:
8906 : : /* If the operand is static or we are static, we can't conflict.
8907 : : Likewise if we don't conflict with the operand at all. */
8908 : 243 : if (staticp (TREE_OPERAND (exp, 0))
8909 : 113 : || TREE_STATIC (exp)
8910 : 356 : || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
8911 : 243 : return true;
8912 : :
8913 : : /* Otherwise, the only way this can conflict is if we are taking
8914 : : the address of a DECL a that address if part of X, which is
8915 : : very rare. */
8916 : 0 : exp = TREE_OPERAND (exp, 0);
8917 : 0 : if (DECL_P (exp))
8918 : : {
8919 : 0 : if (!DECL_RTL_SET_P (exp)
8920 : 0 : || !MEM_P (DECL_RTL (exp)))
8921 : 0 : return false;
8922 : : else
8923 : 0 : exp_rtl = XEXP (DECL_RTL (exp), 0);
8924 : : }
8925 : : break;
8926 : :
8927 : 8 : case MEM_REF:
8928 : 8 : if (MEM_P (x)
8929 : 8 : && alias_sets_conflict_p (MEM_ALIAS_SET (x),
8930 : : get_alias_set (exp)))
8931 : : return false;
8932 : : break;
8933 : :
8934 : 0 : case CALL_EXPR:
8935 : : /* Assume that the call will clobber all hard registers and
8936 : : all of memory. */
8937 : 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8938 : 0 : || MEM_P (x))
8939 : : return false;
8940 : : break;
8941 : :
8942 : 0 : case WITH_CLEANUP_EXPR:
8943 : 0 : case CLEANUP_POINT_EXPR:
8944 : : /* Lowered by gimplify.cc. */
8945 : 0 : gcc_unreachable ();
8946 : :
8947 : 0 : case SAVE_EXPR:
8948 : 0 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
8949 : :
8950 : : default:
8951 : : break;
8952 : : }
8953 : :
8954 : : /* If we have an rtx, we do not need to scan our operands. */
8955 : 0 : if (exp_rtl)
8956 : : break;
8957 : :
8958 : 23 : nops = TREE_OPERAND_LENGTH (exp);
8959 : 111 : for (i = 0; i < nops; i++)
8960 : 65 : if (TREE_OPERAND (exp, i) != 0
8961 : 65 : && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
8962 : : return false;
8963 : :
8964 : : break;
8965 : :
8966 : 0 : case tcc_type:
8967 : : /* Should never get a type here. */
8968 : 0 : gcc_unreachable ();
8969 : : }
8970 : :
8971 : : /* If we have an rtl, find any enclosed object. Then see if we conflict
8972 : : with it. */
8973 : 272 : if (exp_rtl)
8974 : : {
8975 : 249 : if (GET_CODE (exp_rtl) == SUBREG)
8976 : : {
8977 : 0 : exp_rtl = SUBREG_REG (exp_rtl);
8978 : 0 : if (REG_P (exp_rtl)
8979 : 0 : && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
8980 : : return false;
8981 : : }
8982 : :
8983 : : /* If the rtl is X, then it is not safe. Otherwise, it is unless both
8984 : : are memory and they conflict. */
8985 : 249 : return ! (rtx_equal_p (x, exp_rtl)
8986 : 249 : || (MEM_P (x) && MEM_P (exp_rtl)
8987 : 4 : && true_dependence (exp_rtl, VOIDmode, x)));
8988 : : }
8989 : :
8990 : : /* If we reach here, it is safe. */
8991 : : return true;
8992 : : }
8993 : :
8994 : :
8995 : : /* Return the highest power of two that EXP is known to be a multiple of.
8996 : : This is used in updating alignment of MEMs in array references. */
8997 : :
8998 : : unsigned HOST_WIDE_INT
8999 : 32373755 : highest_pow2_factor (const_tree exp)
9000 : : {
9001 : 32373755 : unsigned HOST_WIDE_INT ret;
9002 : 32373755 : int trailing_zeros = tree_ctz (exp);
9003 : 32373755 : if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
9004 : 44846017 : return BIGGEST_ALIGNMENT;
9005 : 9621432 : ret = HOST_WIDE_INT_1U << trailing_zeros;
9006 : 18791898 : if (ret > BIGGEST_ALIGNMENT)
9007 : 12730714 : return BIGGEST_ALIGNMENT;
9008 : : return ret;
9009 : : }
9010 : :
9011 : : /* Similar, except that the alignment requirements of TARGET are
9012 : : taken into account. Assume it is at least as aligned as its
9013 : : type, unless it is a COMPONENT_REF in which case the layout of
9014 : : the structure gives the alignment. */
9015 : :
9016 : : static unsigned HOST_WIDE_INT
9017 : 172087 : highest_pow2_factor_for_target (const_tree target, const_tree exp)
9018 : : {
9019 : 172087 : unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
9020 : 172087 : unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
9021 : :
9022 : 172087 : return MAX (factor, talign);
9023 : : }
9024 : :
9025 : : /* Convert the tree comparison code TCODE to the rtl one where the
9026 : : signedness is UNSIGNEDP. */
9027 : :
9028 : : static enum rtx_code
9029 : 14137 : convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
9030 : : {
9031 : 14137 : enum rtx_code code;
9032 : 14137 : switch (tcode)
9033 : : {
9034 : : case EQ_EXPR:
9035 : : code = EQ;
9036 : : break;
9037 : 772 : case NE_EXPR:
9038 : 772 : code = NE;
9039 : 772 : break;
9040 : 3213 : case LT_EXPR:
9041 : 3213 : code = unsignedp ? LTU : LT;
9042 : : break;
9043 : 1866 : case LE_EXPR:
9044 : 1866 : code = unsignedp ? LEU : LE;
9045 : : break;
9046 : 1926 : case GT_EXPR:
9047 : 1926 : code = unsignedp ? GTU : GT;
9048 : : break;
9049 : 3466 : case GE_EXPR:
9050 : 3466 : code = unsignedp ? GEU : GE;
9051 : : break;
9052 : 4 : case UNORDERED_EXPR:
9053 : 4 : code = UNORDERED;
9054 : 4 : break;
9055 : 0 : case ORDERED_EXPR:
9056 : 0 : code = ORDERED;
9057 : 0 : break;
9058 : 0 : case UNLT_EXPR:
9059 : 0 : code = UNLT;
9060 : 0 : break;
9061 : 0 : case UNLE_EXPR:
9062 : 0 : code = UNLE;
9063 : 0 : break;
9064 : 0 : case UNGT_EXPR:
9065 : 0 : code = UNGT;
9066 : 0 : break;
9067 : 0 : case UNGE_EXPR:
9068 : 0 : code = UNGE;
9069 : 0 : break;
9070 : 0 : case UNEQ_EXPR:
9071 : 0 : code = UNEQ;
9072 : 0 : break;
9073 : 0 : case LTGT_EXPR:
9074 : 0 : code = LTGT;
9075 : 0 : break;
9076 : :
9077 : 0 : default:
9078 : 0 : gcc_unreachable ();
9079 : : }
9080 : 14137 : return code;
9081 : : }
9082 : :
9083 : : /* Subroutine of expand_expr. Expand the two operands of a binary
9084 : : expression EXP0 and EXP1 placing the results in OP0 and OP1.
9085 : : The value may be stored in TARGET if TARGET is nonzero. The
9086 : : MODIFIER argument is as documented by expand_expr. */
9087 : :
9088 : : void
9089 : 7822150 : expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
9090 : : enum expand_modifier modifier)
9091 : : {
9092 : 7822150 : if (! safe_from_p (target, exp1, 1))
9093 : 587097 : target = 0;
9094 : 7822150 : if (operand_equal_p (exp0, exp1, 0))
9095 : : {
9096 : 43343 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9097 : 43343 : *op1 = copy_rtx (*op0);
9098 : : }
9099 : : else
9100 : : {
9101 : 7778807 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9102 : 7778807 : *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
9103 : : }
9104 : 7822150 : }
9105 : :
9106 : :
9107 : : /* Return a MEM that contains constant EXP. DEFER is as for
9108 : : output_constant_def and MODIFIER is as for expand_expr. */
9109 : :
9110 : : static rtx
9111 : 2874530 : expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
9112 : : {
9113 : 2874530 : rtx mem;
9114 : :
9115 : 2874530 : mem = output_constant_def (exp, defer);
9116 : 2874530 : if (modifier != EXPAND_INITIALIZER)
9117 : 1845365 : mem = use_anchored_address (mem);
9118 : 2874530 : return mem;
9119 : : }
9120 : :
9121 : : /* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP.
9122 : : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9123 : :
9124 : : static rtx
9125 : 14231124 : expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
9126 : : enum expand_modifier modifier, addr_space_t as)
9127 : : {
9128 : 14231124 : rtx result, subtarget;
9129 : 14231124 : tree inner, offset;
9130 : 14231124 : poly_int64 bitsize, bitpos;
9131 : 14231124 : int unsignedp, reversep, volatilep = 0;
9132 : 14231124 : machine_mode mode1;
9133 : :
9134 : : /* If we are taking the address of a constant and are at the top level,
9135 : : we have to use output_constant_def since we can't call force_const_mem
9136 : : at top level. */
9137 : : /* ??? This should be considered a front-end bug. We should not be
9138 : : generating ADDR_EXPR of something that isn't an LVALUE. The only
9139 : : exception here is STRING_CST. */
9140 : 14231124 : if (CONSTANT_CLASS_P (exp))
9141 : : {
9142 : 2642822 : result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
9143 : 2642822 : if (modifier < EXPAND_SUM)
9144 : 1749300 : result = force_operand (result, target);
9145 : 2642822 : return result;
9146 : : }
9147 : :
9148 : : /* Everything must be something allowed by is_gimple_addressable. */
9149 : 11588302 : switch (TREE_CODE (exp))
9150 : : {
9151 : 36 : case INDIRECT_REF:
9152 : : /* This case will happen via recursion for &a->b. */
9153 : 36 : return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
9154 : :
9155 : 582628 : case MEM_REF:
9156 : 582628 : {
9157 : 582628 : tree tem = TREE_OPERAND (exp, 0);
9158 : 582628 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
9159 : 317194 : tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
9160 : 582628 : return expand_expr (tem, target, tmode, modifier);
9161 : : }
9162 : :
9163 : 1223 : case TARGET_MEM_REF:
9164 : 1223 : return addr_for_mem_ref (exp, as, true);
9165 : :
9166 : 58663 : case CONST_DECL:
9167 : : /* Expand the initializer like constants above. */
9168 : 58663 : result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
9169 : : 0, modifier), 0);
9170 : 58663 : if (modifier < EXPAND_SUM)
9171 : 58657 : result = force_operand (result, target);
9172 : : return result;
9173 : :
9174 : 140 : case REALPART_EXPR:
9175 : : /* The real part of the complex number is always first, therefore
9176 : : the address is the same as the address of the parent object. */
9177 : 140 : offset = 0;
9178 : 140 : bitpos = 0;
9179 : 140 : inner = TREE_OPERAND (exp, 0);
9180 : 140 : break;
9181 : :
9182 : 84 : case IMAGPART_EXPR:
9183 : : /* The imaginary part of the complex number is always second.
9184 : : The expression is therefore always offset by the size of the
9185 : : scalar type. */
9186 : 84 : offset = 0;
9187 : 168 : bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
9188 : 84 : inner = TREE_OPERAND (exp, 0);
9189 : 84 : break;
9190 : :
9191 : 13 : case COMPOUND_LITERAL_EXPR:
9192 : : /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
9193 : : initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
9194 : : with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
9195 : : array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
9196 : : the initializers aren't gimplified. */
9197 : 13 : if (COMPOUND_LITERAL_EXPR_DECL (exp)
9198 : 13 : && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
9199 : 13 : return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
9200 : 13 : target, tmode, modifier, as);
9201 : : /* FALLTHRU */
9202 : 10945515 : default:
9203 : : /* If the object is a DECL, then expand it for its rtl. Don't bypass
9204 : : expand_expr, as that can have various side effects; LABEL_DECLs for
9205 : : example, may not have their DECL_RTL set yet. Expand the rtl of
9206 : : CONSTRUCTORs too, which should yield a memory reference for the
9207 : : constructor's contents. Assume language specific tree nodes can
9208 : : be expanded in some interesting way. */
9209 : 10945515 : gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
9210 : 10945515 : if (DECL_P (exp)
9211 : 1299090 : || TREE_CODE (exp) == CONSTRUCTOR
9212 : 1299090 : || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
9213 : : {
9214 : 15800333 : result = expand_expr (exp, target, tmode,
9215 : : modifier == EXPAND_INITIALIZER
9216 : : ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
9217 : :
9218 : : /* If the DECL isn't in memory, then the DECL wasn't properly
9219 : : marked TREE_ADDRESSABLE, which will be either a front-end
9220 : : or a tree optimizer bug. */
9221 : :
9222 : 9646425 : gcc_assert (MEM_P (result));
9223 : 9646425 : result = XEXP (result, 0);
9224 : :
9225 : : /* ??? Is this needed anymore? */
9226 : 9646425 : if (DECL_P (exp))
9227 : 9646425 : TREE_USED (exp) = 1;
9228 : :
9229 : 9646425 : if (modifier != EXPAND_INITIALIZER
9230 : : && modifier != EXPAND_CONST_ADDRESS
9231 : 9646425 : && modifier != EXPAND_SUM)
9232 : 4226951 : result = force_operand (result, target);
9233 : 9646425 : return result;
9234 : : }
9235 : :
9236 : : /* Pass FALSE as the last argument to get_inner_reference although
9237 : : we are expanding to RTL. The rationale is that we know how to
9238 : : handle "aligning nodes" here: we can just bypass them because
9239 : : they won't change the final object whose address will be returned
9240 : : (they actually exist only for that purpose). */
9241 : 1299090 : inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
9242 : : &unsignedp, &reversep, &volatilep);
9243 : 1299090 : break;
9244 : : }
9245 : :
9246 : : /* We must have made progress. */
9247 : 1299314 : gcc_assert (inner != exp);
9248 : :
9249 : 1299314 : subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
9250 : : /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
9251 : : inner alignment, force the inner to be sufficiently aligned. */
9252 : 1299314 : if (CONSTANT_CLASS_P (inner)
9253 : 1299314 : && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
9254 : : {
9255 : 0 : inner = copy_node (inner);
9256 : 0 : TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
9257 : 0 : SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
9258 : 0 : TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
9259 : : }
9260 : 1299314 : result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
9261 : :
9262 : 1299314 : if (offset)
9263 : : {
9264 : 44788 : rtx tmp;
9265 : :
9266 : 44788 : if (modifier != EXPAND_NORMAL)
9267 : 859 : result = force_operand (result, NULL);
9268 : 45647 : tmp = expand_expr (offset, NULL_RTX, tmode,
9269 : : modifier == EXPAND_INITIALIZER
9270 : : ? EXPAND_INITIALIZER : EXPAND_NORMAL);
9271 : :
9272 : : /* expand_expr is allowed to return an object in a mode other
9273 : : than TMODE. If it did, we need to convert. */
9274 : 44788 : if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
9275 : 0 : tmp = convert_modes (tmode, GET_MODE (tmp),
9276 : 0 : tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
9277 : 44788 : result = convert_memory_address_addr_space (tmode, result, as);
9278 : 44788 : tmp = convert_memory_address_addr_space (tmode, tmp, as);
9279 : :
9280 : 44788 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
9281 : 859 : result = simplify_gen_binary (PLUS, tmode, result, tmp);
9282 : : else
9283 : : {
9284 : 43929 : subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
9285 : 43929 : result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
9286 : : 1, OPTAB_LIB_WIDEN);
9287 : : }
9288 : : }
9289 : :
9290 : 1299314 : if (maybe_ne (bitpos, 0))
9291 : : {
9292 : : /* Someone beforehand should have rejected taking the address
9293 : : of an object that isn't byte-aligned. */
9294 : 640524 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
9295 : 640524 : result = convert_memory_address_addr_space (tmode, result, as);
9296 : 640524 : result = plus_constant (tmode, result, bytepos);
9297 : 640524 : if (modifier < EXPAND_SUM)
9298 : 605667 : result = force_operand (result, target);
9299 : : }
9300 : :
9301 : : return result;
9302 : : }
9303 : :
9304 : : /* A subroutine of expand_expr. Evaluate EXP, which is an ADDR_EXPR.
9305 : : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9306 : :
9307 : : static rtx
9308 : 12931795 : expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
9309 : : enum expand_modifier modifier)
9310 : : {
9311 : 12931795 : addr_space_t as = ADDR_SPACE_GENERIC;
9312 : 12931795 : scalar_int_mode address_mode = Pmode;
9313 : 12931795 : scalar_int_mode pointer_mode = ptr_mode;
9314 : 12931795 : machine_mode rmode;
9315 : 12931795 : rtx result;
9316 : :
9317 : : /* Target mode of VOIDmode says "whatever's natural". */
9318 : 12931795 : if (tmode == VOIDmode)
9319 : 11016188 : tmode = TYPE_MODE (TREE_TYPE (exp));
9320 : :
9321 : 12931795 : if (POINTER_TYPE_P (TREE_TYPE (exp)))
9322 : : {
9323 : 12931795 : as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
9324 : 12931795 : address_mode = targetm.addr_space.address_mode (as);
9325 : 12931795 : pointer_mode = targetm.addr_space.pointer_mode (as);
9326 : : }
9327 : :
9328 : : /* We can get called with some Weird Things if the user does silliness
9329 : : like "(short) &a". In that case, convert_memory_address won't do
9330 : : the right thing, so ignore the given target mode. */
9331 : 12931795 : scalar_int_mode new_tmode = (tmode == pointer_mode
9332 : 12931795 : ? pointer_mode
9333 : 12931795 : : address_mode);
9334 : :
9335 : 12931795 : result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
9336 : : new_tmode, modifier, as);
9337 : :
9338 : : /* Despite expand_expr claims concerning ignoring TMODE when not
9339 : : strictly convenient, stuff breaks if we don't honor it. Note
9340 : : that combined with the above, we only do this for pointer modes. */
9341 : 12931795 : rmode = GET_MODE (result);
9342 : 12931795 : if (rmode == VOIDmode)
9343 : 6 : rmode = new_tmode;
9344 : 12931795 : if (rmode != new_tmode)
9345 : 74 : result = convert_memory_address_addr_space (new_tmode, result, as);
9346 : :
9347 : 12931795 : return result;
9348 : : }
9349 : :
9350 : : /* Generate code for computing CONSTRUCTOR EXP.
9351 : : An rtx for the computed value is returned. If AVOID_TEMP_MEM
9352 : : is TRUE, instead of creating a temporary variable in memory
9353 : : NULL is returned and the caller needs to handle it differently. */
9354 : :
9355 : : static rtx
9356 : 178421 : expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
9357 : : bool avoid_temp_mem)
9358 : : {
9359 : 178421 : tree type = TREE_TYPE (exp);
9360 : 178421 : machine_mode mode = TYPE_MODE (type);
9361 : :
9362 : : /* Try to avoid creating a temporary at all. This is possible
9363 : : if all of the initializer is zero.
9364 : : FIXME: try to handle all [0..255] initializers we can handle
9365 : : with memset. */
9366 : 178421 : if (TREE_STATIC (exp)
9367 : 5035 : && !TREE_ADDRESSABLE (exp)
9368 : 5035 : && target != 0 && mode == BLKmode
9369 : 182517 : && all_zeros_p (exp))
9370 : : {
9371 : 4091 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
9372 : 4091 : return target;
9373 : : }
9374 : :
9375 : : /* All elts simple constants => refer to a constant in memory. But
9376 : : if this is a non-BLKmode mode, let it store a field at a time
9377 : : since that should make a CONST_INT, CONST_WIDE_INT or
9378 : : CONST_DOUBLE when we fold. Likewise, if we have a target we can
9379 : : use, it is best to store directly into the target unless the type
9380 : : is large enough that memcpy will be used. If we are making an
9381 : : initializer and all operands are constant, put it in memory as
9382 : : well.
9383 : :
9384 : : FIXME: Avoid trying to fill vector constructors piece-meal.
9385 : : Output them with output_constant_def below unless we're sure
9386 : : they're zeros. This should go away when vector initializers
9387 : : are treated like VECTOR_CST instead of arrays. */
9388 : 174330 : if ((TREE_STATIC (exp)
9389 : 944 : && ((mode == BLKmode
9390 : 50 : && ! (target != 0 && safe_from_p (target, exp, 1)))
9391 : 899 : || TREE_ADDRESSABLE (exp)
9392 : 899 : || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9393 : 899 : && (! can_move_by_pieces
9394 : 899 : (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9395 : 899 : TYPE_ALIGN (type)))
9396 : 2 : && ! mostly_zeros_p (exp))))
9397 : 175227 : || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
9398 : 0 : && TREE_CONSTANT (exp)))
9399 : : {
9400 : 47 : rtx constructor;
9401 : :
9402 : 47 : if (avoid_temp_mem)
9403 : : return NULL_RTX;
9404 : :
9405 : 45 : constructor = expand_expr_constant (exp, 1, modifier);
9406 : :
9407 : 45 : if (modifier != EXPAND_CONST_ADDRESS
9408 : : && modifier != EXPAND_INITIALIZER
9409 : 45 : && modifier != EXPAND_SUM)
9410 : 45 : constructor = validize_mem (constructor);
9411 : :
9412 : 45 : return constructor;
9413 : : }
9414 : :
9415 : : /* If the CTOR is available in static storage and not mostly
9416 : : zeros and we can move it by pieces prefer to do so since
9417 : : that's usually more efficient than performing a series of
9418 : : stores from immediates. */
9419 : 174283 : if (avoid_temp_mem
9420 : 64 : && TREE_STATIC (exp)
9421 : 36 : && TREE_CONSTANT (exp)
9422 : 36 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9423 : 36 : && can_move_by_pieces (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9424 : 36 : TYPE_ALIGN (type))
9425 : 174319 : && ! mostly_zeros_p (exp))
9426 : : return NULL_RTX;
9427 : :
9428 : : /* Handle calls that pass values in multiple non-contiguous
9429 : : locations. The Irix 6 ABI has examples of this. */
9430 : 139508 : if (target == 0 || ! safe_from_p (target, exp, 1)
9431 : 35822 : || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
9432 : : /* Also make a temporary if the store is to volatile memory, to
9433 : : avoid individual accesses to aggregate members. */
9434 : 210063 : || (GET_CODE (target) == MEM
9435 : 32757 : && MEM_VOLATILE_P (target)
9436 : 132 : && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
9437 : : {
9438 : 138569 : if (avoid_temp_mem)
9439 : : return NULL_RTX;
9440 : :
9441 : 138558 : target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
9442 : : }
9443 : :
9444 : 174242 : store_constructor (exp, target, 0, int_expr_size (exp), false);
9445 : 174242 : return target;
9446 : : }
9447 : :
9448 : :
9449 : : /* expand_expr: generate code for computing expression EXP.
9450 : : An rtx for the computed value is returned. The value is never null.
9451 : : In the case of a void EXP, const0_rtx is returned.
9452 : :
9453 : : The value may be stored in TARGET if TARGET is nonzero.
9454 : : TARGET is just a suggestion; callers must assume that
9455 : : the rtx returned may not be the same as TARGET.
9456 : :
9457 : : If TARGET is CONST0_RTX, it means that the value will be ignored.
9458 : :
9459 : : If TMODE is not VOIDmode, it suggests generating the
9460 : : result in mode TMODE. But this is done only when convenient.
9461 : : Otherwise, TMODE is ignored and the value generated in its natural mode.
9462 : : TMODE is just a suggestion; callers must assume that
9463 : : the rtx returned may not have mode TMODE.
9464 : :
9465 : : Note that TARGET may have neither TMODE nor MODE. In that case, it
9466 : : probably will not be used.
9467 : :
9468 : : If MODIFIER is EXPAND_SUM then when EXP is an addition
9469 : : we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
9470 : : or a nest of (PLUS ...) and (MINUS ...) where the terms are
9471 : : products as above, or REG or MEM, or constant.
9472 : : Ordinarily in such cases we would output mul or add instructions
9473 : : and then return a pseudo reg containing the sum.
9474 : :
9475 : : EXPAND_INITIALIZER is much like EXPAND_SUM except that
9476 : : it also marks a label as absolutely required (it can't be dead).
9477 : : It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
9478 : : This is used for outputting expressions used in initializers.
9479 : :
9480 : : EXPAND_CONST_ADDRESS says that it is okay to return a MEM
9481 : : with a constant address even if that address is not normally legitimate.
9482 : : EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
9483 : :
9484 : : EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
9485 : : a call parameter. Such targets require special care as we haven't yet
9486 : : marked TARGET so that it's safe from being trashed by libcalls. We
9487 : : don't want to use TARGET for anything but the final result;
9488 : : Intermediate values must go elsewhere. Additionally, calls to
9489 : : emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
9490 : :
9491 : : If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
9492 : : address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
9493 : : DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
9494 : : COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
9495 : : recursively.
9496 : : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9497 : : then *ALT_RTL is set to TARGET (before legitimziation).
9498 : :
9499 : : If INNER_REFERENCE_P is true, we are expanding an inner reference.
9500 : : In this case, we don't adjust a returned MEM rtx that wouldn't be
9501 : : sufficiently aligned for its mode; instead, it's up to the caller
9502 : : to deal with it afterwards. This is used to make sure that unaligned
9503 : : base objects for which out-of-bounds accesses are supported, for
9504 : : example record types with trailing arrays, aren't realigned behind
9505 : : the back of the caller.
9506 : : The normal operating mode is to pass FALSE for this parameter. */
9507 : :
9508 : : rtx
9509 : 153869186 : expand_expr_real (tree exp, rtx target, machine_mode tmode,
9510 : : enum expand_modifier modifier, rtx *alt_rtl,
9511 : : bool inner_reference_p)
9512 : : {
9513 : 153869186 : rtx ret;
9514 : :
9515 : : /* Handle ERROR_MARK before anybody tries to access its type. */
9516 : 153869186 : if (TREE_CODE (exp) == ERROR_MARK
9517 : 153869186 : || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
9518 : : {
9519 : 0 : ret = CONST0_RTX (tmode);
9520 : 0 : return ret ? ret : const0_rtx;
9521 : : }
9522 : :
9523 : 153869186 : ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
9524 : : inner_reference_p);
9525 : 153869186 : return ret;
9526 : : }
9527 : :
9528 : : /* Try to expand the conditional expression which is represented by
9529 : : TREEOP0 ? TREEOP1 : TREEOP2 using conditonal moves. If it succeeds
9530 : : return the rtl reg which represents the result. Otherwise return
9531 : : NULL_RTX. */
9532 : :
9533 : : static rtx
9534 : 17545 : expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
9535 : : tree treeop1 ATTRIBUTE_UNUSED,
9536 : : tree treeop2 ATTRIBUTE_UNUSED)
9537 : : {
9538 : 17545 : rtx insn;
9539 : 17545 : rtx op00, op01, op1, op2;
9540 : 17545 : enum rtx_code comparison_code;
9541 : 17545 : machine_mode comparison_mode;
9542 : 17545 : gimple *srcstmt;
9543 : 17545 : rtx temp;
9544 : 17545 : tree type = TREE_TYPE (treeop1);
9545 : 17545 : int unsignedp = TYPE_UNSIGNED (type);
9546 : 17545 : machine_mode mode = TYPE_MODE (type);
9547 : 17545 : machine_mode orig_mode = mode;
9548 : 17545 : static bool expanding_cond_expr_using_cmove = false;
9549 : :
9550 : : /* Conditional move expansion can end up TERing two operands which,
9551 : : when recursively hitting conditional expressions can result in
9552 : : exponential behavior if the cmove expansion ultimatively fails.
9553 : : It's hardly profitable to TER a cmove into a cmove so avoid doing
9554 : : that by failing early if we end up recursing. */
9555 : 17545 : if (expanding_cond_expr_using_cmove)
9556 : : return NULL_RTX;
9557 : :
9558 : : /* If we cannot do a conditional move on the mode, try doing it
9559 : : with the promoted mode. */
9560 : 16561 : if (!can_conditionally_move_p (mode))
9561 : : {
9562 : 147 : mode = promote_mode (type, mode, &unsignedp);
9563 : 147 : if (!can_conditionally_move_p (mode))
9564 : : return NULL_RTX;
9565 : 0 : temp = assign_temp (type, 0, 0); /* Use promoted mode for temp. */
9566 : : }
9567 : : else
9568 : 16414 : temp = assign_temp (type, 0, 1);
9569 : :
9570 : 16414 : expanding_cond_expr_using_cmove = true;
9571 : 16414 : start_sequence ();
9572 : 16414 : expand_operands (treeop1, treeop2,
9573 : : mode == orig_mode ? temp : NULL_RTX, &op1, &op2,
9574 : : EXPAND_NORMAL);
9575 : :
9576 : 16414 : if (TREE_CODE (treeop0) == SSA_NAME
9577 : 16005 : && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))
9578 : 30145 : && !VECTOR_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (srcstmt))))
9579 : : {
9580 : 13728 : type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
9581 : 13728 : enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt);
9582 : 13728 : op00 = expand_normal (gimple_assign_rhs1 (srcstmt));
9583 : 13728 : op01 = expand_normal (gimple_assign_rhs2 (srcstmt));
9584 : 13728 : comparison_mode = TYPE_MODE (type);
9585 : 13728 : unsignedp = TYPE_UNSIGNED (type);
9586 : 13728 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9587 : : }
9588 : 2686 : else if (COMPARISON_CLASS_P (treeop0)
9589 : 2686 : && !VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (treeop0, 0))))
9590 : : {
9591 : 409 : type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
9592 : 409 : enum tree_code cmpcode = TREE_CODE (treeop0);
9593 : 409 : op00 = expand_normal (TREE_OPERAND (treeop0, 0));
9594 : 409 : op01 = expand_normal (TREE_OPERAND (treeop0, 1));
9595 : 409 : unsignedp = TYPE_UNSIGNED (type);
9596 : 409 : comparison_mode = TYPE_MODE (type);
9597 : 409 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9598 : : }
9599 : : else
9600 : : {
9601 : 2277 : op00 = expand_normal (treeop0);
9602 : 2277 : op01 = const0_rtx;
9603 : 2277 : comparison_code = NE;
9604 : 2277 : comparison_mode = GET_MODE (op00);
9605 : 2277 : if (comparison_mode == VOIDmode)
9606 : 0 : comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
9607 : : }
9608 : 16414 : expanding_cond_expr_using_cmove = false;
9609 : :
9610 : 16414 : if (GET_MODE (op1) != mode)
9611 : 2118 : op1 = gen_lowpart (mode, op1);
9612 : :
9613 : 16414 : if (GET_MODE (op2) != mode)
9614 : 9229 : op2 = gen_lowpart (mode, op2);
9615 : :
9616 : : /* Try to emit the conditional move. */
9617 : 16414 : insn = emit_conditional_move (temp,
9618 : : { comparison_code, op00, op01,
9619 : : comparison_mode },
9620 : : op1, op2, mode,
9621 : : unsignedp);
9622 : :
9623 : : /* If we could do the conditional move, emit the sequence,
9624 : : and return. */
9625 : 16414 : if (insn)
9626 : : {
9627 : 13978 : rtx_insn *seq = end_sequence ();
9628 : 13978 : emit_insn (seq);
9629 : 13978 : return convert_modes (orig_mode, mode, temp, 0);
9630 : : }
9631 : :
9632 : : /* Otherwise discard the sequence and fall back to code with
9633 : : branches. */
9634 : 2436 : end_sequence ();
9635 : 2436 : return NULL_RTX;
9636 : : }
9637 : :
9638 : : /* A helper function for expand_expr_real_2 to be used with a
9639 : : misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP
9640 : : is nonzero, with alignment ALIGN in bits.
9641 : : Store the value at TARGET if possible (if TARGET is nonzero).
9642 : : Regardless of TARGET, we return the rtx for where the value is placed.
9643 : : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9644 : : then *ALT_RTL is set to TARGET (before legitimziation). */
9645 : :
9646 : : static rtx
9647 : 206129 : expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
9648 : : unsigned int align, rtx target, rtx *alt_rtl)
9649 : : {
9650 : 206129 : enum insn_code icode;
9651 : :
9652 : 206129 : if ((icode = optab_handler (movmisalign_optab, mode))
9653 : : != CODE_FOR_nothing)
9654 : : {
9655 : 121665 : class expand_operand ops[2];
9656 : :
9657 : : /* We've already validated the memory, and we're creating a
9658 : : new pseudo destination. The predicates really can't fail,
9659 : : nor can the generator. */
9660 : 121665 : create_output_operand (&ops[0], NULL_RTX, mode);
9661 : 121665 : create_fixed_operand (&ops[1], temp);
9662 : 121665 : expand_insn (icode, 2, ops);
9663 : 121665 : temp = ops[0].value;
9664 : : }
9665 : 84464 : else if (targetm.slow_unaligned_access (mode, align))
9666 : 0 : temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
9667 : : 0, unsignedp, target,
9668 : : mode, mode, false, alt_rtl);
9669 : 206129 : return temp;
9670 : : }
9671 : :
9672 : : /* Helper function of expand_expr_2, expand a division or modulo.
9673 : : op0 and op1 should be already expanded treeop0 and treeop1, using
9674 : : expand_operands. */
9675 : :
9676 : : static rtx
9677 : 171994 : expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
9678 : : tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
9679 : : {
9680 : 343988 : bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
9681 : 171994 : || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
9682 : 171994 : if (SCALAR_INT_MODE_P (mode)
9683 : 171994 : && optimize >= 2
9684 : 145183 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1
9685 : 209756 : && get_range_pos_neg (treeop1, currently_expanding_gimple_stmt) == 1)
9686 : : {
9687 : : /* If both arguments are known to be positive when interpreted
9688 : : as signed, we can expand it as both signed and unsigned
9689 : : division or modulo. Choose the cheaper sequence in that case. */
9690 : 25612 : bool speed_p = optimize_insn_for_speed_p ();
9691 : 25612 : do_pending_stack_adjust ();
9692 : 25612 : start_sequence ();
9693 : 25612 : rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
9694 : 25612 : rtx_insn *uns_insns = end_sequence ();
9695 : 25612 : start_sequence ();
9696 : 25612 : rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
9697 : 25612 : rtx_insn *sgn_insns = end_sequence ();
9698 : 25612 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
9699 : 25612 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
9700 : 25612 : bool was_tie = false;
9701 : :
9702 : : /* If costs are the same then use as tie breaker the other other
9703 : : factor. */
9704 : 25612 : if (uns_cost == sgn_cost)
9705 : : {
9706 : 8044 : uns_cost = seq_cost (uns_insns, !speed_p);
9707 : 8044 : sgn_cost = seq_cost (sgn_insns, !speed_p);
9708 : 8044 : was_tie = true;
9709 : : }
9710 : :
9711 : 25612 : if (dump_file && (dump_flags & TDF_DETAILS))
9712 : 0 : fprintf (dump_file, ";; positive division:%s unsigned cost: %u; "
9713 : : "signed cost: %u\n",
9714 : : was_tie ? " (needed tie breaker)" : "", uns_cost, sgn_cost);
9715 : :
9716 : 25612 : if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
9717 : : {
9718 : 18239 : emit_insn (uns_insns);
9719 : 18239 : return uns_ret;
9720 : : }
9721 : 7373 : emit_insn (sgn_insns);
9722 : 7373 : return sgn_ret;
9723 : : }
9724 : 146382 : return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
9725 : : }
9726 : :
9727 : : rtx
9728 : 12967703 : expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
9729 : : enum expand_modifier modifier)
9730 : : {
9731 : 12967703 : rtx op0, op1, op2, temp;
9732 : 12967703 : rtx_code_label *lab;
9733 : 12967703 : tree type;
9734 : 12967703 : int unsignedp;
9735 : 12967703 : machine_mode mode;
9736 : 12967703 : scalar_int_mode int_mode;
9737 : 12967703 : enum tree_code code = ops->code;
9738 : 12967703 : optab this_optab;
9739 : 12967703 : rtx subtarget, original_target;
9740 : 12967703 : int ignore;
9741 : 12967703 : bool reduce_bit_field;
9742 : 12967703 : location_t loc = ops->location;
9743 : 12967703 : tree treeop0, treeop1, treeop2;
9744 : : #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
9745 : : ? reduce_to_bit_field_precision ((expr), \
9746 : : target, \
9747 : : type) \
9748 : : : (expr))
9749 : :
9750 : 12967703 : type = ops->type;
9751 : 12967703 : mode = TYPE_MODE (type);
9752 : 12967703 : unsignedp = TYPE_UNSIGNED (type);
9753 : :
9754 : 12967703 : treeop0 = ops->op0;
9755 : 12967703 : treeop1 = ops->op1;
9756 : 12967703 : treeop2 = ops->op2;
9757 : :
9758 : : /* We should be called only on simple (binary or unary) expressions,
9759 : : exactly those that are valid in gimple expressions that aren't
9760 : : GIMPLE_SINGLE_RHS (or invalid). */
9761 : 12967703 : gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
9762 : : || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
9763 : : || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
9764 : :
9765 : 25935406 : ignore = (target == const0_rtx
9766 : 12967703 : || ((CONVERT_EXPR_CODE_P (code)
9767 : 9324066 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
9768 : 3661182 : && TREE_CODE (type) == VOID_TYPE));
9769 : :
9770 : : /* We should be called only if we need the result. */
9771 : 0 : gcc_assert (!ignore);
9772 : :
9773 : : /* An operation in what may be a bit-field type needs the
9774 : : result to be reduced to the precision of the bit-field type,
9775 : : which is narrower than that of the type's mode. */
9776 : 26628147 : reduce_bit_field = (INTEGRAL_TYPE_P (type)
9777 : 12967703 : && !type_has_mode_precision_p (type));
9778 : :
9779 : 692741 : if (reduce_bit_field
9780 : 692741 : && (modifier == EXPAND_STACK_PARM
9781 : 692219 : || (target && GET_MODE (target) != mode)))
9782 : 386445 : target = 0;
9783 : :
9784 : : /* Use subtarget as the target for operand 0 of a binary operation. */
9785 : 12967703 : subtarget = get_subtarget (target);
9786 : 12967703 : original_target = target;
9787 : :
9788 : 12967703 : switch (code)
9789 : : {
9790 : 3646816 : case NON_LVALUE_EXPR:
9791 : 3646816 : case PAREN_EXPR:
9792 : 3646816 : CASE_CONVERT:
9793 : 3646816 : if (treeop0 == error_mark_node)
9794 : 0 : return const0_rtx;
9795 : :
9796 : 3646816 : if (TREE_CODE (type) == UNION_TYPE)
9797 : : {
9798 : 0 : tree valtype = TREE_TYPE (treeop0);
9799 : :
9800 : : /* If both input and output are BLKmode, this conversion isn't doing
9801 : : anything except possibly changing memory attribute. */
9802 : 0 : if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
9803 : : {
9804 : 0 : rtx result = expand_expr (treeop0, target, tmode,
9805 : : modifier);
9806 : :
9807 : 0 : result = copy_rtx (result);
9808 : 0 : set_mem_attributes (result, type, 0);
9809 : 0 : return result;
9810 : : }
9811 : :
9812 : 0 : if (target == 0)
9813 : : {
9814 : 0 : if (TYPE_MODE (type) != BLKmode)
9815 : 0 : target = gen_reg_rtx (TYPE_MODE (type));
9816 : : else
9817 : 0 : target = assign_temp (type, 1, 1);
9818 : : }
9819 : :
9820 : 0 : if (MEM_P (target))
9821 : : /* Store data into beginning of memory target. */
9822 : 0 : store_expr (treeop0,
9823 : 0 : adjust_address (target, TYPE_MODE (valtype), 0),
9824 : : modifier == EXPAND_STACK_PARM,
9825 : 0 : false, TYPE_REVERSE_STORAGE_ORDER (type));
9826 : :
9827 : : else
9828 : : {
9829 : 0 : gcc_assert (REG_P (target)
9830 : : && !TYPE_REVERSE_STORAGE_ORDER (type));
9831 : :
9832 : : /* Store this field into a union of the proper type. */
9833 : 0 : poly_uint64 op0_size
9834 : 0 : = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
9835 : 0 : poly_uint64 union_size = GET_MODE_BITSIZE (mode);
9836 : 0 : store_field (target,
9837 : : /* The conversion must be constructed so that
9838 : : we know at compile time how many bits
9839 : : to preserve. */
9840 : 0 : ordered_min (op0_size, union_size),
9841 : 0 : 0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
9842 : : false, false);
9843 : : }
9844 : :
9845 : : /* Return the entire union. */
9846 : 0 : return target;
9847 : : }
9848 : :
9849 : 3646816 : if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
9850 : : {
9851 : 2146232 : op0 = expand_expr (treeop0, target, VOIDmode,
9852 : : modifier);
9853 : :
9854 : 2146232 : return REDUCE_BIT_FIELD (op0);
9855 : : }
9856 : :
9857 : 1862638 : op0 = expand_expr (treeop0, NULL_RTX, mode,
9858 : : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
9859 : 1500584 : if (GET_MODE (op0) == mode)
9860 : : ;
9861 : :
9862 : : /* If OP0 is a constant, just convert it into the proper mode. */
9863 : 1457411 : else if (CONSTANT_P (op0))
9864 : : {
9865 : 896 : tree inner_type = TREE_TYPE (treeop0);
9866 : 896 : machine_mode inner_mode = GET_MODE (op0);
9867 : :
9868 : 896 : if (inner_mode == VOIDmode)
9869 : 11 : inner_mode = TYPE_MODE (inner_type);
9870 : :
9871 : 896 : if (modifier == EXPAND_INITIALIZER)
9872 : 0 : op0 = force_lowpart_subreg (mode, op0, inner_mode);
9873 : : else
9874 : 896 : op0 = convert_modes (mode, inner_mode, op0,
9875 : 896 : TYPE_UNSIGNED (inner_type));
9876 : : }
9877 : :
9878 : 1456515 : else if (modifier == EXPAND_INITIALIZER)
9879 : 24 : op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
9880 : : ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
9881 : :
9882 : 1456503 : else if (SCALAR_INT_MODE_P (GET_MODE (op0))
9883 : 1284324 : && optimize >= 2
9884 : 763696 : && SCALAR_INT_MODE_P (mode)
9885 : 763696 : && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
9886 : 1527392 : > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
9887 : 1967899 : && get_range_pos_neg (treeop0,
9888 : : currently_expanding_gimple_stmt) == 1)
9889 : : {
9890 : : /* If argument is known to be positive when interpreted
9891 : : as signed, we can expand it as both sign and zero
9892 : : extension. Choose the cheaper sequence in that case. */
9893 : 154630 : bool speed_p = optimize_insn_for_speed_p ();
9894 : 154630 : rtx uns_ret = NULL_RTX, sgn_ret = NULL_RTX;
9895 : 154630 : do_pending_stack_adjust ();
9896 : 154630 : start_sequence ();
9897 : 154630 : if (target == NULL_RTX)
9898 : 126467 : uns_ret = convert_to_mode (mode, op0, 1);
9899 : : else
9900 : 28163 : convert_move (target, op0, 1);
9901 : 154630 : rtx_insn *uns_insns = end_sequence ();
9902 : 154630 : start_sequence ();
9903 : 154630 : if (target == NULL_RTX)
9904 : 126467 : sgn_ret = convert_to_mode (mode, op0, 0);
9905 : : else
9906 : 28163 : convert_move (target, op0, 0);
9907 : 154630 : rtx_insn *sgn_insns = end_sequence ();
9908 : 154630 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
9909 : 154630 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
9910 : 154630 : bool was_tie = false;
9911 : :
9912 : : /* If costs are the same then use as tie breaker the other other
9913 : : factor. */
9914 : 154630 : if (uns_cost == sgn_cost)
9915 : : {
9916 : 41680 : uns_cost = seq_cost (uns_insns, !speed_p);
9917 : 41680 : sgn_cost = seq_cost (sgn_insns, !speed_p);
9918 : 41680 : was_tie = true;
9919 : : }
9920 : :
9921 : 154630 : if (dump_file && (dump_flags & TDF_DETAILS))
9922 : 0 : fprintf (dump_file, ";; positive extension:%s unsigned cost: %u; "
9923 : : "signed cost: %u\n",
9924 : : was_tie ? " (needed tie breaker)" : "",
9925 : : uns_cost, sgn_cost);
9926 : 154630 : if (uns_cost < sgn_cost
9927 : 154630 : || (uns_cost == sgn_cost && TYPE_UNSIGNED (TREE_TYPE (treeop0))))
9928 : : {
9929 : 141419 : emit_insn (uns_insns);
9930 : 141419 : sgn_ret = uns_ret;
9931 : : }
9932 : : else
9933 : 13211 : emit_insn (sgn_insns);
9934 : 154630 : if (target == NULL_RTX)
9935 : 126467 : op0 = sgn_ret;
9936 : : else
9937 : 28163 : op0 = target;
9938 : : }
9939 : 1301873 : else if (target == 0)
9940 : 805925 : op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
9941 : : else
9942 : : {
9943 : 495948 : convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
9944 : 495948 : op0 = target;
9945 : : }
9946 : :
9947 : 1500584 : return REDUCE_BIT_FIELD (op0);
9948 : :
9949 : 0 : case ADDR_SPACE_CONVERT_EXPR:
9950 : 0 : {
9951 : 0 : tree treeop0_type = TREE_TYPE (treeop0);
9952 : :
9953 : 0 : gcc_assert (POINTER_TYPE_P (type));
9954 : 0 : gcc_assert (POINTER_TYPE_P (treeop0_type));
9955 : :
9956 : 0 : addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
9957 : 0 : addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
9958 : :
9959 : : /* Conversions between pointers to the same address space should
9960 : : have been implemented via CONVERT_EXPR / NOP_EXPR. */
9961 : 0 : gcc_assert (as_to != as_from);
9962 : :
9963 : 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
9964 : :
9965 : : /* Ask target code to handle conversion between pointers
9966 : : to overlapping address spaces. */
9967 : 0 : if (targetm.addr_space.subset_p (as_to, as_from)
9968 : 0 : || targetm.addr_space.subset_p (as_from, as_to))
9969 : : {
9970 : 0 : op0 = targetm.addr_space.convert (op0, treeop0_type, type);
9971 : : }
9972 : : else
9973 : : {
9974 : : /* For disjoint address spaces, converting anything but a null
9975 : : pointer invokes undefined behavior. We truncate or extend the
9976 : : value as if we'd converted via integers, which handles 0 as
9977 : : required, and all others as the programmer likely expects. */
9978 : : #ifndef POINTERS_EXTEND_UNSIGNED
9979 : : const int POINTERS_EXTEND_UNSIGNED = 1;
9980 : : #endif
9981 : 0 : op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
9982 : : op0, POINTERS_EXTEND_UNSIGNED);
9983 : : }
9984 : 0 : gcc_assert (op0);
9985 : : return op0;
9986 : : }
9987 : :
9988 : 1374281 : case POINTER_PLUS_EXPR:
9989 : : /* Even though the sizetype mode and the pointer's mode can be different
9990 : : expand is able to handle this correctly and get the correct result out
9991 : : of the PLUS_EXPR code. */
9992 : : /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
9993 : : if sizetype precision is smaller than pointer precision. */
9994 : 1374281 : if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
9995 : 0 : treeop1 = fold_convert_loc (loc, type,
9996 : : fold_convert_loc (loc, ssizetype,
9997 : : treeop1));
9998 : : /* If sizetype precision is larger than pointer precision, truncate the
9999 : : offset to have matching modes. */
10000 : 1374281 : else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
10001 : 0 : treeop1 = fold_convert_loc (loc, type, treeop1);
10002 : : /* FALLTHRU */
10003 : :
10004 : 5181505 : case PLUS_EXPR:
10005 : : /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
10006 : : something else, make sure we add the register to the constant and
10007 : : then to the other thing. This case can occur during strength
10008 : : reduction and doing it this way will produce better code if the
10009 : : frame pointer or argument pointer is eliminated.
10010 : :
10011 : : fold-const.cc will ensure that the constant is always in the inner
10012 : : PLUS_EXPR, so the only case we need to do anything about is if
10013 : : sp, ap, or fp is our second argument, in which case we must swap
10014 : : the innermost first argument and our second argument. */
10015 : :
10016 : 5181505 : if (TREE_CODE (treeop0) == PLUS_EXPR
10017 : 6893 : && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
10018 : 0 : && VAR_P (treeop1)
10019 : 5181505 : && (DECL_RTL (treeop1) == frame_pointer_rtx
10020 : 0 : || DECL_RTL (treeop1) == stack_pointer_rtx
10021 : 0 : || DECL_RTL (treeop1) == arg_pointer_rtx))
10022 : : {
10023 : 0 : gcc_unreachable ();
10024 : : }
10025 : :
10026 : : /* If the result is to be ptr_mode and we are adding an integer to
10027 : : something, we might be forming a constant. So try to use
10028 : : plus_constant. If it produces a sum and we can't accept it,
10029 : : use force_operand. This allows P = &ARR[const] to generate
10030 : : efficient code on machines where a SYMBOL_REF is not a valid
10031 : : address.
10032 : :
10033 : : If this is an EXPAND_SUM call, always return the sum. */
10034 : 5181505 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
10035 : 5181505 : || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
10036 : : {
10037 : 3384875 : if (modifier == EXPAND_STACK_PARM)
10038 : 18634 : target = 0;
10039 : 3384875 : if (TREE_CODE (treeop0) == INTEGER_CST
10040 : 3385882 : && HWI_COMPUTABLE_MODE_P (mode)
10041 : 3385886 : && TREE_CONSTANT (treeop1))
10042 : : {
10043 : 4 : rtx constant_part;
10044 : 4 : HOST_WIDE_INT wc;
10045 : 4 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
10046 : :
10047 : 4 : op1 = expand_expr (treeop1, subtarget, VOIDmode,
10048 : : EXPAND_SUM);
10049 : : /* Use wi::shwi to ensure that the constant is
10050 : : truncated according to the mode of OP1, then sign extended
10051 : : to a HOST_WIDE_INT. Using the constant directly can result
10052 : : in non-canonical RTL in a 64x32 cross compile. */
10053 : 4 : wc = TREE_INT_CST_LOW (treeop0);
10054 : 4 : constant_part =
10055 : 4 : immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10056 : 4 : op1 = plus_constant (mode, op1, INTVAL (constant_part));
10057 : 4 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10058 : 1 : op1 = force_operand (op1, target);
10059 : 4 : return REDUCE_BIT_FIELD (op1);
10060 : : }
10061 : :
10062 : 3384871 : else if (TREE_CODE (treeop1) == INTEGER_CST
10063 : 7192291 : && HWI_COMPUTABLE_MODE_P (mode)
10064 : 5674798 : && TREE_CONSTANT (treeop0))
10065 : : {
10066 : 279137 : rtx constant_part;
10067 : 279137 : HOST_WIDE_INT wc;
10068 : 279137 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
10069 : :
10070 : 489309 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10071 : : (modifier == EXPAND_INITIALIZER
10072 : : ? EXPAND_INITIALIZER : EXPAND_SUM));
10073 : 279137 : if (! CONSTANT_P (op0))
10074 : : {
10075 : 6 : op1 = expand_expr (treeop1, NULL_RTX,
10076 : : VOIDmode, modifier);
10077 : : /* Return a PLUS if modifier says it's OK. */
10078 : 6 : if (modifier == EXPAND_SUM
10079 : : || modifier == EXPAND_INITIALIZER)
10080 : 6 : return simplify_gen_binary (PLUS, mode, op0, op1);
10081 : 0 : goto binop2;
10082 : : }
10083 : : /* Use wi::shwi to ensure that the constant is
10084 : : truncated according to the mode of OP1, then sign extended
10085 : : to a HOST_WIDE_INT. Using the constant directly can result
10086 : : in non-canonical RTL in a 64x32 cross compile. */
10087 : 279131 : wc = TREE_INT_CST_LOW (treeop1);
10088 : 279131 : constant_part
10089 : 279131 : = immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10090 : 279131 : op0 = plus_constant (mode, op0, INTVAL (constant_part));
10091 : 279131 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10092 : 209374 : op0 = force_operand (op0, target);
10093 : 279131 : return REDUCE_BIT_FIELD (op0);
10094 : : }
10095 : : }
10096 : :
10097 : : /* Use TER to expand pointer addition of a negated value
10098 : : as pointer subtraction. */
10099 : 8726551 : if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
10100 : 3807211 : || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
10101 : 75254 : && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
10102 : 1095153 : && TREE_CODE (treeop1) == SSA_NAME
10103 : 6030308 : && TYPE_MODE (TREE_TYPE (treeop0))
10104 : 563972 : == TYPE_MODE (TREE_TYPE (treeop1)))
10105 : : {
10106 : 563972 : gimple *def = get_def_for_expr (treeop1, NEGATE_EXPR);
10107 : 563972 : if (def)
10108 : : {
10109 : 2920 : treeop1 = gimple_assign_rhs1 (def);
10110 : 2920 : code = MINUS_EXPR;
10111 : 2920 : goto do_minus;
10112 : : }
10113 : : }
10114 : :
10115 : : /* No sense saving up arithmetic to be done
10116 : : if it's all in the wrong mode to form part of an address.
10117 : : And force_operand won't know whether to sign-extend or
10118 : : zero-extend. */
10119 : 4899444 : if (modifier != EXPAND_INITIALIZER
10120 : 4899444 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10121 : : {
10122 : 4348404 : expand_operands (treeop0, treeop1,
10123 : : subtarget, &op0, &op1, modifier);
10124 : 4348404 : if (op0 == const0_rtx)
10125 : 8680 : return op1;
10126 : 4339724 : if (op1 == const0_rtx)
10127 : : return op0;
10128 : 4339472 : goto binop2;
10129 : : }
10130 : :
10131 : 551040 : expand_operands (treeop0, treeop1,
10132 : : subtarget, &op0, &op1, modifier);
10133 : 551040 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10134 : :
10135 : 517505 : case MINUS_EXPR:
10136 : 517505 : case POINTER_DIFF_EXPR:
10137 : 517505 : do_minus:
10138 : : /* For initializers, we are allowed to return a MINUS of two
10139 : : symbolic constants. Here we handle all cases when both operands
10140 : : are constant. */
10141 : : /* Handle difference of two symbolic constants,
10142 : : for the sake of an initializer. */
10143 : 517505 : if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
10144 : 2992 : && really_constant_p (treeop0)
10145 : 517984 : && really_constant_p (treeop1))
10146 : : {
10147 : 68 : expand_operands (treeop0, treeop1,
10148 : : NULL_RTX, &op0, &op1, modifier);
10149 : 68 : return simplify_gen_binary (MINUS, mode, op0, op1);
10150 : : }
10151 : :
10152 : : /* No sense saving up arithmetic to be done
10153 : : if it's all in the wrong mode to form part of an address.
10154 : : And force_operand won't know whether to sign-extend or
10155 : : zero-extend. */
10156 : 517437 : if (modifier != EXPAND_INITIALIZER
10157 : 517437 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10158 : 514513 : goto binop;
10159 : :
10160 : 2924 : expand_operands (treeop0, treeop1,
10161 : : subtarget, &op0, &op1, modifier);
10162 : :
10163 : : /* Convert A - const to A + (-const). */
10164 : 2924 : if (CONST_INT_P (op1))
10165 : : {
10166 : 0 : op1 = negate_rtx (mode, op1);
10167 : 0 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10168 : : }
10169 : :
10170 : 2924 : goto binop2;
10171 : :
10172 : 0 : case WIDEN_MULT_PLUS_EXPR:
10173 : 0 : case WIDEN_MULT_MINUS_EXPR:
10174 : 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
10175 : 0 : op2 = expand_normal (treeop2);
10176 : 0 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
10177 : : target, unsignedp);
10178 : 0 : return target;
10179 : :
10180 : 18149 : case WIDEN_MULT_EXPR:
10181 : : /* If first operand is constant, swap them.
10182 : : Thus the following special case checks need only
10183 : : check the second operand. */
10184 : 18149 : if (TREE_CODE (treeop0) == INTEGER_CST)
10185 : 368 : std::swap (treeop0, treeop1);
10186 : :
10187 : : /* First, check if we have a multiplication of one signed and one
10188 : : unsigned operand. */
10189 : 18149 : if (TREE_CODE (treeop1) != INTEGER_CST
10190 : 18149 : && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
10191 : 13743 : != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
10192 : : {
10193 : 0 : machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
10194 : 0 : this_optab = usmul_widen_optab;
10195 : 0 : if (find_widening_optab_handler (this_optab, mode, innermode)
10196 : : != CODE_FOR_nothing)
10197 : : {
10198 : 0 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10199 : 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10200 : : EXPAND_NORMAL);
10201 : : else
10202 : 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
10203 : : EXPAND_NORMAL);
10204 : : /* op0 and op1 might still be constant, despite the above
10205 : : != INTEGER_CST check. Handle it. */
10206 : 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10207 : : {
10208 : 0 : op0 = convert_modes (mode, innermode, op0, true);
10209 : 0 : op1 = convert_modes (mode, innermode, op1, false);
10210 : 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10211 : : target, unsignedp));
10212 : : }
10213 : 0 : goto binop3;
10214 : : }
10215 : : }
10216 : : /* Check for a multiplication with matching signedness. */
10217 : 18149 : else if ((TREE_CODE (treeop1) == INTEGER_CST
10218 : 4406 : && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
10219 : 18149 : || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
10220 : 13743 : == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
10221 : : {
10222 : 18149 : tree op0type = TREE_TYPE (treeop0);
10223 : 18149 : machine_mode innermode = TYPE_MODE (op0type);
10224 : 18149 : bool zextend_p = TYPE_UNSIGNED (op0type);
10225 : 18149 : optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
10226 : 2529 : this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
10227 : :
10228 : 18149 : if (TREE_CODE (treeop0) != INTEGER_CST)
10229 : : {
10230 : 18149 : if (find_widening_optab_handler (this_optab, mode, innermode)
10231 : : != CODE_FOR_nothing)
10232 : : {
10233 : 18149 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10234 : : EXPAND_NORMAL);
10235 : : /* op0 and op1 might still be constant, despite the above
10236 : : != INTEGER_CST check. Handle it. */
10237 : 18149 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10238 : : {
10239 : 0 : widen_mult_const:
10240 : 0 : op0 = convert_modes (mode, innermode, op0, zextend_p);
10241 : 0 : op1
10242 : 0 : = convert_modes (mode, innermode, op1,
10243 : 0 : TYPE_UNSIGNED (TREE_TYPE (treeop1)));
10244 : 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10245 : : target,
10246 : : unsignedp));
10247 : : }
10248 : 18149 : temp = expand_widening_mult (mode, op0, op1, target,
10249 : : unsignedp, this_optab);
10250 : 18149 : return REDUCE_BIT_FIELD (temp);
10251 : : }
10252 : 0 : if (find_widening_optab_handler (other_optab, mode, innermode)
10253 : : != CODE_FOR_nothing
10254 : 0 : && innermode == word_mode)
10255 : : {
10256 : 0 : rtx htem, hipart;
10257 : 0 : op0 = expand_normal (treeop0);
10258 : 0 : op1 = expand_normal (treeop1);
10259 : : /* op0 and op1 might be constants, despite the above
10260 : : != INTEGER_CST check. Handle it. */
10261 : 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10262 : 0 : goto widen_mult_const;
10263 : 0 : temp = expand_binop (mode, other_optab, op0, op1, target,
10264 : : unsignedp, OPTAB_LIB_WIDEN);
10265 : 0 : hipart = gen_highpart (word_mode, temp);
10266 : 0 : htem = expand_mult_highpart_adjust (word_mode, hipart,
10267 : : op0, op1, hipart,
10268 : : zextend_p);
10269 : 0 : if (htem != hipart)
10270 : 0 : emit_move_insn (hipart, htem);
10271 : 0 : return REDUCE_BIT_FIELD (temp);
10272 : : }
10273 : : }
10274 : : }
10275 : 0 : treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
10276 : 0 : treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
10277 : 0 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10278 : 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10279 : :
10280 : 1347267 : case MULT_EXPR:
10281 : : /* If this is a fixed-point operation, then we cannot use the code
10282 : : below because "expand_mult" doesn't support sat/no-sat fixed-point
10283 : : multiplications. */
10284 : 1347267 : if (ALL_FIXED_POINT_MODE_P (mode))
10285 : 0 : goto binop;
10286 : :
10287 : : /* If first operand is constant, swap them.
10288 : : Thus the following special case checks need only
10289 : : check the second operand. */
10290 : 1347267 : if (TREE_CODE (treeop0) == INTEGER_CST)
10291 : 686 : std::swap (treeop0, treeop1);
10292 : :
10293 : : /* Attempt to return something suitable for generating an
10294 : : indexed address, for machines that support that. */
10295 : :
10296 : 523582 : if (modifier == EXPAND_SUM && mode == ptr_mode
10297 : 1870849 : && tree_fits_shwi_p (treeop1))
10298 : : {
10299 : 517163 : tree exp1 = treeop1;
10300 : :
10301 : 517163 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10302 : : EXPAND_SUM);
10303 : :
10304 : 517163 : if (!REG_P (op0))
10305 : 242669 : op0 = force_operand (op0, NULL_RTX);
10306 : 517163 : if (!REG_P (op0))
10307 : 1725 : op0 = copy_to_mode_reg (mode, op0);
10308 : :
10309 : 517163 : op1 = gen_int_mode (tree_to_shwi (exp1),
10310 : 517163 : TYPE_MODE (TREE_TYPE (exp1)));
10311 : 517163 : return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
10312 : : }
10313 : :
10314 : 830104 : if (modifier == EXPAND_STACK_PARM)
10315 : 2917 : target = 0;
10316 : :
10317 : 830104 : if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
10318 : : {
10319 : 494960 : gimple *def_stmt0 = get_def_for_expr (treeop0, TRUNC_DIV_EXPR);
10320 : 494960 : gimple *def_stmt1 = get_def_for_expr (treeop1, TRUNC_DIV_EXPR);
10321 : 494960 : if (def_stmt0
10322 : 494960 : && !operand_equal_p (treeop1, gimple_assign_rhs2 (def_stmt0), 0))
10323 : : def_stmt0 = NULL;
10324 : 494960 : if (def_stmt1
10325 : 494960 : && !operand_equal_p (treeop0, gimple_assign_rhs2 (def_stmt1), 0))
10326 : : def_stmt1 = NULL;
10327 : :
10328 : 494960 : if (def_stmt0 || def_stmt1)
10329 : : {
10330 : : /* X / Y * Y can be expanded as X - X % Y too.
10331 : : Choose the cheaper sequence of those two. */
10332 : 768 : if (def_stmt0)
10333 : 768 : treeop0 = gimple_assign_rhs1 (def_stmt0);
10334 : : else
10335 : : {
10336 : 0 : treeop1 = treeop0;
10337 : 0 : treeop0 = gimple_assign_rhs1 (def_stmt1);
10338 : : }
10339 : 768 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
10340 : : EXPAND_NORMAL);
10341 : 768 : bool speed_p = optimize_insn_for_speed_p ();
10342 : 768 : do_pending_stack_adjust ();
10343 : 768 : start_sequence ();
10344 : 768 : rtx divmul_ret
10345 : 768 : = expand_expr_divmod (TRUNC_DIV_EXPR, mode, treeop0, treeop1,
10346 : : op0, op1, NULL_RTX, unsignedp);
10347 : 768 : divmul_ret = expand_mult (mode, divmul_ret, op1, target,
10348 : : unsignedp);
10349 : 768 : rtx_insn *divmul_insns = end_sequence ();
10350 : 768 : start_sequence ();
10351 : 768 : rtx modsub_ret
10352 : 768 : = expand_expr_divmod (TRUNC_MOD_EXPR, mode, treeop0, treeop1,
10353 : : op0, op1, NULL_RTX, unsignedp);
10354 : 768 : this_optab = optab_for_tree_code (MINUS_EXPR, type,
10355 : : optab_default);
10356 : 768 : modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
10357 : : target, unsignedp, OPTAB_LIB_WIDEN);
10358 : 768 : rtx_insn *modsub_insns = end_sequence ();
10359 : 768 : unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
10360 : 768 : unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
10361 : : /* If costs are the same then use as tie breaker the other other
10362 : : factor. */
10363 : 768 : if (divmul_cost == modsub_cost)
10364 : : {
10365 : 20 : divmul_cost = seq_cost (divmul_insns, !speed_p);
10366 : 20 : modsub_cost = seq_cost (modsub_insns, !speed_p);
10367 : : }
10368 : :
10369 : 768 : if (divmul_cost <= modsub_cost)
10370 : : {
10371 : 700 : emit_insn (divmul_insns);
10372 : 700 : return REDUCE_BIT_FIELD (divmul_ret);
10373 : : }
10374 : 68 : emit_insn (modsub_insns);
10375 : 68 : return REDUCE_BIT_FIELD (modsub_ret);
10376 : : }
10377 : : }
10378 : :
10379 : 829336 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10380 : :
10381 : : /* Expand X*Y as X&-Y when Y must be zero or one. */
10382 : 829336 : if (SCALAR_INT_MODE_P (mode))
10383 : : {
10384 : 698430 : bool gimple_zero_one_valued_p (tree, tree (*)(tree));
10385 : 698430 : bool bit0_p = gimple_zero_one_valued_p (treeop0, nullptr);
10386 : 698430 : bool bit1_p = gimple_zero_one_valued_p (treeop1, nullptr);
10387 : :
10388 : : /* Expand X*Y as X&Y when both X and Y must be zero or one. */
10389 : 698430 : if (bit0_p && bit1_p)
10390 : 2 : return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
10391 : :
10392 : 698428 : if (bit0_p || bit1_p)
10393 : : {
10394 : 4291 : bool speed = optimize_insn_for_speed_p ();
10395 : 4291 : int cost = add_cost (speed, mode) + neg_cost (speed, mode);
10396 : 4291 : struct algorithm algorithm;
10397 : 4291 : enum mult_variant variant;
10398 : 4291 : if (CONST_INT_P (op1)
10399 : 4291 : ? !choose_mult_variant (mode, INTVAL (op1),
10400 : : &algorithm, &variant, cost)
10401 : 674 : : cost < mul_cost (speed, mode))
10402 : : {
10403 : 2047 : temp = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
10404 : : op1, target)
10405 : 264 : : expand_and (mode, op0,
10406 : : negate_rtx (mode, op1),
10407 : : target);
10408 : 2047 : return REDUCE_BIT_FIELD (temp);
10409 : : }
10410 : : }
10411 : : }
10412 : :
10413 : 827287 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10414 : :
10415 : 170458 : case TRUNC_MOD_EXPR:
10416 : 170458 : case FLOOR_MOD_EXPR:
10417 : 170458 : case CEIL_MOD_EXPR:
10418 : 170458 : case ROUND_MOD_EXPR:
10419 : :
10420 : 170458 : case TRUNC_DIV_EXPR:
10421 : 170458 : case FLOOR_DIV_EXPR:
10422 : 170458 : case CEIL_DIV_EXPR:
10423 : 170458 : case ROUND_DIV_EXPR:
10424 : 170458 : case EXACT_DIV_EXPR:
10425 : : /* If this is a fixed-point operation, then we cannot use the code
10426 : : below because "expand_divmod" doesn't support sat/no-sat fixed-point
10427 : : divisions. */
10428 : 170458 : if (ALL_FIXED_POINT_MODE_P (mode))
10429 : 0 : goto binop;
10430 : :
10431 : 170458 : if (modifier == EXPAND_STACK_PARM)
10432 : 335 : target = 0;
10433 : : /* Possible optimization: compute the dividend with EXPAND_SUM
10434 : : then if the divisor is constant can optimize the case
10435 : : where some terms of the dividend have coeffs divisible by it. */
10436 : 170458 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10437 : 170458 : return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
10438 : 170458 : target, unsignedp);
10439 : :
10440 : 31122 : case RDIV_EXPR:
10441 : 31122 : goto binop;
10442 : :
10443 : 1620 : case MULT_HIGHPART_EXPR:
10444 : 1620 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10445 : 1620 : temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
10446 : 1620 : gcc_assert (temp);
10447 : : return temp;
10448 : :
10449 : 0 : case FIXED_CONVERT_EXPR:
10450 : 0 : op0 = expand_normal (treeop0);
10451 : 0 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10452 : 0 : target = gen_reg_rtx (mode);
10453 : :
10454 : 0 : if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
10455 : 0 : && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10456 : 0 : || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
10457 : 0 : expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
10458 : : else
10459 : 0 : expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
10460 : : return target;
10461 : :
10462 : 47686 : case FIX_TRUNC_EXPR:
10463 : 47686 : op0 = expand_normal (treeop0);
10464 : 47686 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10465 : 3106 : target = gen_reg_rtx (mode);
10466 : 47686 : expand_fix (target, op0, unsignedp);
10467 : 47686 : return target;
10468 : :
10469 : 132977 : case FLOAT_EXPR:
10470 : 132977 : op0 = expand_normal (treeop0);
10471 : 132977 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10472 : 62645 : target = gen_reg_rtx (mode);
10473 : : /* expand_float can't figure out what to do if FROM has VOIDmode.
10474 : : So give it the correct mode. With -O, cse will optimize this. */
10475 : 132977 : if (GET_MODE (op0) == VOIDmode)
10476 : 108 : op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
10477 : : op0);
10478 : 265954 : expand_float (target, op0,
10479 : 132977 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10480 : 132977 : return target;
10481 : :
10482 : 49347 : case NEGATE_EXPR:
10483 : 49347 : op0 = expand_expr (treeop0, subtarget,
10484 : : VOIDmode, EXPAND_NORMAL);
10485 : 49347 : if (modifier == EXPAND_STACK_PARM)
10486 : 241 : target = 0;
10487 : 49347 : temp = expand_unop (mode,
10488 : : optab_for_tree_code (NEGATE_EXPR, type,
10489 : : optab_default),
10490 : : op0, target, 0);
10491 : 49347 : gcc_assert (temp);
10492 : 49347 : return REDUCE_BIT_FIELD (temp);
10493 : :
10494 : 26028 : case ABS_EXPR:
10495 : 26028 : case ABSU_EXPR:
10496 : 26028 : op0 = expand_expr (treeop0, subtarget,
10497 : : VOIDmode, EXPAND_NORMAL);
10498 : 26028 : if (modifier == EXPAND_STACK_PARM)
10499 : 48 : target = 0;
10500 : :
10501 : : /* ABS_EXPR is not valid for complex arguments. */
10502 : 26028 : gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
10503 : : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
10504 : :
10505 : : /* Unsigned abs is simply the operand. Testing here means we don't
10506 : : risk generating incorrect code below. */
10507 : 26028 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10508 : : return op0;
10509 : :
10510 : 26028 : return expand_abs (mode, op0, target, unsignedp,
10511 : 52056 : safe_from_p (target, treeop0, 1));
10512 : :
10513 : 99846 : case MAX_EXPR:
10514 : 99846 : case MIN_EXPR:
10515 : 99846 : target = original_target;
10516 : 99846 : if (target == 0
10517 : 99846 : || modifier == EXPAND_STACK_PARM
10518 : 56098 : || (MEM_P (target) && MEM_VOLATILE_P (target))
10519 : 56098 : || GET_MODE (target) != mode
10520 : 155944 : || (REG_P (target)
10521 : 49518 : && REGNO (target) < FIRST_PSEUDO_REGISTER))
10522 : 43748 : target = gen_reg_rtx (mode);
10523 : 99846 : expand_operands (treeop0, treeop1,
10524 : : target, &op0, &op1, EXPAND_NORMAL);
10525 : :
10526 : : /* First try to do it with a special MIN or MAX instruction.
10527 : : If that does not win, use a conditional jump to select the proper
10528 : : value. */
10529 : 99846 : this_optab = optab_for_tree_code (code, type, optab_default);
10530 : 99846 : temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
10531 : : OPTAB_WIDEN);
10532 : 99846 : if (temp != 0)
10533 : : return temp;
10534 : :
10535 : 122 : if (VECTOR_TYPE_P (type))
10536 : 0 : gcc_unreachable ();
10537 : :
10538 : : /* At this point, a MEM target is no longer useful; we will get better
10539 : : code without it. */
10540 : :
10541 : 122 : if (! REG_P (target))
10542 : 1 : target = gen_reg_rtx (mode);
10543 : :
10544 : : /* If op1 was placed in target, swap op0 and op1. */
10545 : 122 : if (target != op0 && target == op1)
10546 : 0 : std::swap (op0, op1);
10547 : :
10548 : : /* We generate better code and avoid problems with op1 mentioning
10549 : : target by forcing op1 into a pseudo if it isn't a constant. */
10550 : 122 : if (! CONSTANT_P (op1))
10551 : 42 : op1 = force_reg (mode, op1);
10552 : :
10553 : 122 : {
10554 : 122 : enum rtx_code comparison_code;
10555 : 122 : rtx cmpop1 = op1;
10556 : :
10557 : 122 : if (code == MAX_EXPR)
10558 : 62 : comparison_code = unsignedp ? GEU : GE;
10559 : : else
10560 : 60 : comparison_code = unsignedp ? LEU : LE;
10561 : :
10562 : : /* Canonicalize to comparisons against 0. */
10563 : 122 : if (op1 == const1_rtx)
10564 : : {
10565 : : /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
10566 : : or (a != 0 ? a : 1) for unsigned.
10567 : : For MIN we are safe converting (a <= 1 ? a : 1)
10568 : : into (a <= 0 ? a : 1) */
10569 : 0 : cmpop1 = const0_rtx;
10570 : 0 : if (code == MAX_EXPR)
10571 : 0 : comparison_code = unsignedp ? NE : GT;
10572 : : }
10573 : 122 : if (op1 == constm1_rtx && !unsignedp)
10574 : : {
10575 : : /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
10576 : : and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
10577 : 0 : cmpop1 = const0_rtx;
10578 : 0 : if (code == MIN_EXPR)
10579 : 0 : comparison_code = LT;
10580 : : }
10581 : :
10582 : : /* Use a conditional move if possible. */
10583 : 122 : if (can_conditionally_move_p (mode))
10584 : : {
10585 : 75 : rtx insn;
10586 : :
10587 : 75 : start_sequence ();
10588 : :
10589 : : /* Try to emit the conditional move. */
10590 : 75 : insn = emit_conditional_move (target,
10591 : : { comparison_code,
10592 : : op0, cmpop1, mode },
10593 : : op0, op1, mode,
10594 : : unsignedp);
10595 : :
10596 : : /* If we could do the conditional move, emit the sequence,
10597 : : and return. */
10598 : 75 : if (insn)
10599 : : {
10600 : 41 : rtx_insn *seq = end_sequence ();
10601 : 41 : emit_insn (seq);
10602 : 41 : return target;
10603 : : }
10604 : :
10605 : : /* Otherwise discard the sequence and fall back to code with
10606 : : branches. */
10607 : 34 : end_sequence ();
10608 : : }
10609 : :
10610 : 81 : if (target != op0)
10611 : 52 : emit_move_insn (target, op0);
10612 : :
10613 : 81 : lab = gen_label_rtx ();
10614 : 81 : do_compare_rtx_and_jump (target, cmpop1, comparison_code,
10615 : : unsignedp, mode, NULL_RTX, NULL, lab,
10616 : : profile_probability::uninitialized ());
10617 : : }
10618 : 81 : emit_move_insn (target, op1);
10619 : 81 : emit_label (lab);
10620 : 81 : return target;
10621 : :
10622 : 56396 : case BIT_NOT_EXPR:
10623 : 56396 : op0 = expand_expr (treeop0, subtarget,
10624 : : VOIDmode, EXPAND_NORMAL);
10625 : 56396 : if (modifier == EXPAND_STACK_PARM)
10626 : 88 : target = 0;
10627 : : /* In case we have to reduce the result to bitfield precision
10628 : : for unsigned bitfield expand this as XOR with a proper constant
10629 : : instead. */
10630 : 56396 : if (reduce_bit_field && TYPE_UNSIGNED (type))
10631 : : {
10632 : 20941 : int_mode = SCALAR_INT_TYPE_MODE (type);
10633 : 20941 : wide_int mask = wi::mask (TYPE_PRECISION (type),
10634 : 41882 : false, GET_MODE_PRECISION (int_mode));
10635 : :
10636 : 41882 : temp = expand_binop (int_mode, xor_optab, op0,
10637 : 41882 : immed_wide_int_const (mask, int_mode),
10638 : : target, 1, OPTAB_LIB_WIDEN);
10639 : 20941 : }
10640 : : else
10641 : 35455 : temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
10642 : 56396 : gcc_assert (temp);
10643 : : return temp;
10644 : :
10645 : : /* ??? Can optimize bitwise operations with one arg constant.
10646 : : Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
10647 : : and (a bitwise1 b) bitwise2 b (etc)
10648 : : but that is probably not worth while. */
10649 : :
10650 : 647651 : case BIT_AND_EXPR:
10651 : 647651 : case BIT_IOR_EXPR:
10652 : 647651 : case BIT_XOR_EXPR:
10653 : 647651 : goto binop;
10654 : :
10655 : 7470 : case LROTATE_EXPR:
10656 : 7470 : case RROTATE_EXPR:
10657 : 7470 : gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
10658 : : || type_has_mode_precision_p (type));
10659 : : /* fall through */
10660 : :
10661 : 285675 : case LSHIFT_EXPR:
10662 : 285675 : case RSHIFT_EXPR:
10663 : 285675 : {
10664 : : /* If this is a fixed-point operation, then we cannot use the code
10665 : : below because "expand_shift" doesn't support sat/no-sat fixed-point
10666 : : shifts. */
10667 : 285675 : if (ALL_FIXED_POINT_MODE_P (mode))
10668 : 0 : goto binop;
10669 : :
10670 : 285675 : if (! safe_from_p (subtarget, treeop1, 1))
10671 : 5244 : subtarget = 0;
10672 : 285675 : if (modifier == EXPAND_STACK_PARM)
10673 : 2573 : target = 0;
10674 : 285675 : op0 = expand_expr (treeop0, subtarget,
10675 : : VOIDmode, EXPAND_NORMAL);
10676 : :
10677 : : /* Left shift optimization when shifting across word_size boundary.
10678 : :
10679 : : If mode == GET_MODE_WIDER_MODE (word_mode), then normally
10680 : : there isn't native instruction to support this wide mode
10681 : : left shift. Given below scenario:
10682 : :
10683 : : Type A = (Type) B << C
10684 : :
10685 : : |< T >|
10686 : : | dest_high | dest_low |
10687 : :
10688 : : | word_size |
10689 : :
10690 : : If the shift amount C caused we shift B to across the word
10691 : : size boundary, i.e part of B shifted into high half of
10692 : : destination register, and part of B remains in the low
10693 : : half, then GCC will use the following left shift expand
10694 : : logic:
10695 : :
10696 : : 1. Initialize dest_low to B.
10697 : : 2. Initialize every bit of dest_high to the sign bit of B.
10698 : : 3. Logic left shift dest_low by C bit to finalize dest_low.
10699 : : The value of dest_low before this shift is kept in a temp D.
10700 : : 4. Logic left shift dest_high by C.
10701 : : 5. Logic right shift D by (word_size - C).
10702 : : 6. Or the result of 4 and 5 to finalize dest_high.
10703 : :
10704 : : While, by checking gimple statements, if operand B is
10705 : : coming from signed extension, then we can simplify above
10706 : : expand logic into:
10707 : :
10708 : : 1. dest_high = src_low >> (word_size - C).
10709 : : 2. dest_low = src_low << C.
10710 : :
10711 : : We can use one arithmetic right shift to finish all the
10712 : : purpose of steps 2, 4, 5, 6, thus we reduce the steps
10713 : : needed from 6 into 2.
10714 : :
10715 : : The case is similar for zero extension, except that we
10716 : : initialize dest_high to zero rather than copies of the sign
10717 : : bit from B. Furthermore, we need to use a logical right shift
10718 : : in this case.
10719 : :
10720 : : The choice of sign-extension versus zero-extension is
10721 : : determined entirely by whether or not B is signed and is
10722 : : independent of the current setting of unsignedp. */
10723 : :
10724 : 285675 : temp = NULL_RTX;
10725 : 285675 : if (code == LSHIFT_EXPR
10726 : 285675 : && target
10727 : 33676 : && REG_P (target)
10728 : 316801 : && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
10729 : 31191 : && mode == int_mode
10730 : 1503 : && TREE_CONSTANT (treeop1)
10731 : 286508 : && TREE_CODE (treeop0) == SSA_NAME)
10732 : : {
10733 : 833 : gimple *def = SSA_NAME_DEF_STMT (treeop0);
10734 : 833 : if (is_gimple_assign (def)
10735 : 833 : && gimple_assign_rhs_code (def) == NOP_EXPR)
10736 : : {
10737 : 320 : scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
10738 : : (TREE_TYPE (gimple_assign_rhs1 (def)));
10739 : :
10740 : 640 : if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
10741 : 594 : && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
10742 : 458 : && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
10743 : 69 : >= GET_MODE_BITSIZE (word_mode)))
10744 : : {
10745 : 65 : rtx_insn *seq, *seq_old;
10746 : 65 : poly_uint64 high_off = subreg_highpart_offset (word_mode,
10747 : : int_mode);
10748 : 65 : bool extend_unsigned
10749 : 65 : = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
10750 : 65 : rtx low = lowpart_subreg (word_mode, op0, int_mode);
10751 : 65 : rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
10752 : 65 : rtx dest_high = simplify_gen_subreg (word_mode, target,
10753 : : int_mode, high_off);
10754 : 65 : HOST_WIDE_INT ramount = (BITS_PER_WORD
10755 : 65 : - TREE_INT_CST_LOW (treeop1));
10756 : 65 : tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
10757 : :
10758 : 65 : start_sequence ();
10759 : : /* dest_high = src_low >> (word_size - C). */
10760 : 65 : temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
10761 : : rshift, dest_high,
10762 : : extend_unsigned);
10763 : 65 : if (temp != dest_high)
10764 : 0 : emit_move_insn (dest_high, temp);
10765 : :
10766 : : /* dest_low = src_low << C. */
10767 : 65 : temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
10768 : : treeop1, dest_low, unsignedp);
10769 : 65 : if (temp != dest_low)
10770 : 0 : emit_move_insn (dest_low, temp);
10771 : :
10772 : 65 : seq = end_sequence ();
10773 : 65 : temp = target ;
10774 : :
10775 : 65 : if (have_insn_for (ASHIFT, int_mode))
10776 : : {
10777 : 65 : bool speed_p = optimize_insn_for_speed_p ();
10778 : 65 : start_sequence ();
10779 : 65 : rtx ret_old = expand_variable_shift (code, int_mode,
10780 : : op0, treeop1,
10781 : : target,
10782 : : unsignedp);
10783 : :
10784 : 65 : seq_old = end_sequence ();
10785 : 130 : if (seq_cost (seq, speed_p)
10786 : 65 : >= seq_cost (seq_old, speed_p))
10787 : : {
10788 : 65 : seq = seq_old;
10789 : 65 : temp = ret_old;
10790 : : }
10791 : : }
10792 : 65 : emit_insn (seq);
10793 : : }
10794 : : }
10795 : : }
10796 : :
10797 : 65 : if (temp == NULL_RTX)
10798 : 285610 : temp = expand_variable_shift (code, mode, op0, treeop1, target,
10799 : : unsignedp);
10800 : 285675 : if (code == LSHIFT_EXPR)
10801 : 83711 : temp = REDUCE_BIT_FIELD (temp);
10802 : : return temp;
10803 : : }
10804 : :
10805 : : /* Could determine the answer when only additive constants differ. Also,
10806 : : the addition of one can be handled by changing the condition. */
10807 : 542164 : case LT_EXPR:
10808 : 542164 : case LE_EXPR:
10809 : 542164 : case GT_EXPR:
10810 : 542164 : case GE_EXPR:
10811 : 542164 : case EQ_EXPR:
10812 : 542164 : case NE_EXPR:
10813 : 542164 : case UNORDERED_EXPR:
10814 : 542164 : case ORDERED_EXPR:
10815 : 542164 : case UNLT_EXPR:
10816 : 542164 : case UNLE_EXPR:
10817 : 542164 : case UNGT_EXPR:
10818 : 542164 : case UNGE_EXPR:
10819 : 542164 : case UNEQ_EXPR:
10820 : 542164 : case LTGT_EXPR:
10821 : 542164 : {
10822 : 861522 : temp = do_store_flag (ops,
10823 : : modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
10824 : : tmode != VOIDmode ? tmode : mode);
10825 : 542164 : if (temp)
10826 : : return temp;
10827 : :
10828 : : /* Use a compare and a jump for BLKmode comparisons, or for function
10829 : : type comparisons is have_canonicalize_funcptr_for_compare. */
10830 : :
10831 : 0 : if ((target == 0
10832 : 0 : || modifier == EXPAND_STACK_PARM
10833 : 0 : || ! safe_from_p (target, treeop0, 1)
10834 : 0 : || ! safe_from_p (target, treeop1, 1)
10835 : : /* Make sure we don't have a hard reg (such as function's return
10836 : : value) live across basic blocks, if not optimizing. */
10837 : 0 : || (!optimize && REG_P (target)
10838 : 0 : && REGNO (target) < FIRST_PSEUDO_REGISTER)))
10839 : 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
10840 : :
10841 : 0 : emit_move_insn (target, const0_rtx);
10842 : :
10843 : 0 : rtx_code_label *lab1 = gen_label_rtx ();
10844 : 0 : jumpifnot_1 (code, treeop0, treeop1, lab1,
10845 : : profile_probability::uninitialized ());
10846 : :
10847 : 0 : if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
10848 : 0 : emit_move_insn (target, constm1_rtx);
10849 : : else
10850 : 0 : emit_move_insn (target, const1_rtx);
10851 : :
10852 : 0 : emit_label (lab1);
10853 : 0 : return target;
10854 : : }
10855 : 54210 : case COMPLEX_EXPR:
10856 : : /* Get the rtx code of the operands. */
10857 : 54210 : op0 = expand_normal (treeop0);
10858 : 54210 : op1 = expand_normal (treeop1);
10859 : :
10860 : 54210 : if (!target)
10861 : 2693 : target = gen_reg_rtx (TYPE_MODE (type));
10862 : : else
10863 : : /* If target overlaps with op1, then either we need to force
10864 : : op1 into a pseudo (if target also overlaps with op0),
10865 : : or write the complex parts in reverse order. */
10866 : 51517 : switch (GET_CODE (target))
10867 : : {
10868 : 48835 : case CONCAT:
10869 : 48835 : if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
10870 : : {
10871 : 0 : if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
10872 : : {
10873 : 0 : complex_expr_force_op1:
10874 : 1718 : temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
10875 : 859 : emit_move_insn (temp, op1);
10876 : 859 : op1 = temp;
10877 : 859 : break;
10878 : : }
10879 : 0 : complex_expr_swap_order:
10880 : : /* Move the imaginary (op1) and real (op0) parts to their
10881 : : location. */
10882 : 1 : write_complex_part (target, op1, true, true);
10883 : 1 : write_complex_part (target, op0, false, false);
10884 : :
10885 : 1 : return target;
10886 : : }
10887 : : break;
10888 : 2682 : case MEM:
10889 : 5364 : temp = adjust_address_nv (target,
10890 : : GET_MODE_INNER (GET_MODE (target)), 0);
10891 : 2682 : if (reg_overlap_mentioned_p (temp, op1))
10892 : : {
10893 : 860 : scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
10894 : 1720 : temp = adjust_address_nv (target, imode,
10895 : : GET_MODE_SIZE (imode));
10896 : 860 : if (reg_overlap_mentioned_p (temp, op0))
10897 : 859 : goto complex_expr_force_op1;
10898 : 1 : goto complex_expr_swap_order;
10899 : : }
10900 : : break;
10901 : 0 : default:
10902 : 0 : if (reg_overlap_mentioned_p (target, op1))
10903 : : {
10904 : 0 : if (reg_overlap_mentioned_p (target, op0))
10905 : 0 : goto complex_expr_force_op1;
10906 : 0 : goto complex_expr_swap_order;
10907 : : }
10908 : : break;
10909 : : }
10910 : :
10911 : : /* Move the real (op0) and imaginary (op1) parts to their location. */
10912 : 54209 : write_complex_part (target, op0, false, true);
10913 : 54209 : write_complex_part (target, op1, true, false);
10914 : :
10915 : 54209 : return target;
10916 : :
10917 : 0 : case WIDEN_SUM_EXPR:
10918 : 0 : {
10919 : 0 : tree oprnd0 = treeop0;
10920 : 0 : tree oprnd1 = treeop1;
10921 : :
10922 : 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
10923 : 0 : target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
10924 : : target, unsignedp);
10925 : 0 : return target;
10926 : : }
10927 : :
10928 : 15343 : case VEC_UNPACK_HI_EXPR:
10929 : 15343 : case VEC_UNPACK_LO_EXPR:
10930 : 15343 : case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
10931 : 15343 : case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
10932 : 15343 : {
10933 : 15343 : op0 = expand_normal (treeop0);
10934 : 15343 : temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
10935 : : target, unsignedp);
10936 : 15343 : gcc_assert (temp);
10937 : : return temp;
10938 : : }
10939 : :
10940 : 1758 : case VEC_UNPACK_FLOAT_HI_EXPR:
10941 : 1758 : case VEC_UNPACK_FLOAT_LO_EXPR:
10942 : 1758 : {
10943 : 1758 : op0 = expand_normal (treeop0);
10944 : : /* The signedness is determined from input operand. */
10945 : 1758 : temp = expand_widen_pattern_expr
10946 : 3516 : (ops, op0, NULL_RTX, NULL_RTX,
10947 : 1758 : target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10948 : :
10949 : 1758 : gcc_assert (temp);
10950 : : return temp;
10951 : : }
10952 : :
10953 : 879 : case VEC_WIDEN_MULT_HI_EXPR:
10954 : 879 : case VEC_WIDEN_MULT_LO_EXPR:
10955 : 879 : case VEC_WIDEN_MULT_EVEN_EXPR:
10956 : 879 : case VEC_WIDEN_MULT_ODD_EXPR:
10957 : 879 : case VEC_WIDEN_LSHIFT_HI_EXPR:
10958 : 879 : case VEC_WIDEN_LSHIFT_LO_EXPR:
10959 : 879 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
10960 : 879 : target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
10961 : : target, unsignedp);
10962 : 879 : gcc_assert (target);
10963 : : return target;
10964 : :
10965 : 328 : case VEC_PACK_SAT_EXPR:
10966 : 328 : case VEC_PACK_FIX_TRUNC_EXPR:
10967 : 328 : mode = TYPE_MODE (TREE_TYPE (treeop0));
10968 : 328 : subtarget = NULL_RTX;
10969 : 328 : goto binop;
10970 : :
10971 : 9440 : case VEC_PACK_TRUNC_EXPR:
10972 : 9440 : if (VECTOR_BOOLEAN_TYPE_P (type)
10973 : 962 : && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
10974 : 962 : && mode == TYPE_MODE (TREE_TYPE (treeop0))
10975 : 9640 : && SCALAR_INT_MODE_P (mode))
10976 : : {
10977 : 200 : class expand_operand eops[4];
10978 : 200 : machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
10979 : 200 : expand_operands (treeop0, treeop1,
10980 : : subtarget, &op0, &op1, EXPAND_NORMAL);
10981 : 200 : this_optab = vec_pack_sbool_trunc_optab;
10982 : 200 : enum insn_code icode = optab_handler (this_optab, imode);
10983 : 200 : create_output_operand (&eops[0], target, mode);
10984 : 200 : create_convert_operand_from (&eops[1], op0, imode, false);
10985 : 200 : create_convert_operand_from (&eops[2], op1, imode, false);
10986 : 200 : temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
10987 : 200 : create_input_operand (&eops[3], temp, imode);
10988 : 200 : expand_insn (icode, 4, eops);
10989 : 200 : return eops[0].value;
10990 : : }
10991 : 9240 : mode = TYPE_MODE (TREE_TYPE (treeop0));
10992 : 9240 : subtarget = NULL_RTX;
10993 : 9240 : goto binop;
10994 : :
10995 : 27 : case VEC_PACK_FLOAT_EXPR:
10996 : 27 : mode = TYPE_MODE (TREE_TYPE (treeop0));
10997 : 27 : expand_operands (treeop0, treeop1,
10998 : : subtarget, &op0, &op1, EXPAND_NORMAL);
10999 : 27 : this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
11000 : : optab_default);
11001 : 81 : target = expand_binop (mode, this_optab, op0, op1, target,
11002 : 27 : TYPE_UNSIGNED (TREE_TYPE (treeop0)),
11003 : : OPTAB_LIB_WIDEN);
11004 : 27 : gcc_assert (target);
11005 : : return target;
11006 : :
11007 : 67632 : case VEC_PERM_EXPR:
11008 : 67632 : {
11009 : 67632 : expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL);
11010 : 67632 : vec_perm_builder sel;
11011 : 67632 : if (TREE_CODE (treeop2) == VECTOR_CST
11012 : 67632 : && tree_to_vec_perm_builder (&sel, treeop2))
11013 : : {
11014 : 67622 : machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
11015 : 67622 : temp = expand_vec_perm_const (mode, op0, op1, sel,
11016 : : sel_mode, target);
11017 : : }
11018 : : else
11019 : : {
11020 : 10 : op2 = expand_normal (treeop2);
11021 : 10 : temp = expand_vec_perm_var (mode, op0, op1, op2, target);
11022 : : }
11023 : 67632 : gcc_assert (temp);
11024 : 67632 : return temp;
11025 : 67632 : }
11026 : :
11027 : 230 : case DOT_PROD_EXPR:
11028 : 230 : {
11029 : 230 : tree oprnd0 = treeop0;
11030 : 230 : tree oprnd1 = treeop1;
11031 : 230 : tree oprnd2 = treeop2;
11032 : :
11033 : 230 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11034 : 230 : op2 = expand_normal (oprnd2);
11035 : 230 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11036 : : target, unsignedp);
11037 : 230 : return target;
11038 : : }
11039 : :
11040 : 108 : case SAD_EXPR:
11041 : 108 : {
11042 : 108 : tree oprnd0 = treeop0;
11043 : 108 : tree oprnd1 = treeop1;
11044 : 108 : tree oprnd2 = treeop2;
11045 : :
11046 : 108 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11047 : 108 : op2 = expand_normal (oprnd2);
11048 : 108 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11049 : : target, unsignedp);
11050 : 108 : return target;
11051 : : }
11052 : :
11053 : 0 : case REALIGN_LOAD_EXPR:
11054 : 0 : {
11055 : 0 : tree oprnd0 = treeop0;
11056 : 0 : tree oprnd1 = treeop1;
11057 : 0 : tree oprnd2 = treeop2;
11058 : :
11059 : 0 : this_optab = optab_for_tree_code (code, type, optab_default);
11060 : 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11061 : 0 : op2 = expand_normal (oprnd2);
11062 : 0 : temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
11063 : : target, unsignedp);
11064 : 0 : gcc_assert (temp);
11065 : : return temp;
11066 : : }
11067 : :
11068 : 17545 : case COND_EXPR:
11069 : 17545 : {
11070 : : /* A COND_EXPR with its type being VOID_TYPE represents a
11071 : : conditional jump and is handled in
11072 : : expand_gimple_cond_expr. */
11073 : 17545 : gcc_assert (!VOID_TYPE_P (type));
11074 : :
11075 : : /* Note that COND_EXPRs whose type is a structure or union
11076 : : are required to be constructed to contain assignments of
11077 : : a temporary variable, so that we can evaluate them here
11078 : : for side effect only. If type is void, we must do likewise. */
11079 : :
11080 : 17545 : gcc_assert (!TREE_ADDRESSABLE (type)
11081 : : && !ignore
11082 : : && TREE_TYPE (treeop1) != void_type_node
11083 : : && TREE_TYPE (treeop2) != void_type_node);
11084 : :
11085 : 17545 : temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
11086 : 17545 : if (temp)
11087 : : return temp;
11088 : :
11089 : : /* If we are not to produce a result, we have no target. Otherwise,
11090 : : if a target was specified use it; it will not be used as an
11091 : : intermediate target unless it is safe. If no target, use a
11092 : : temporary. */
11093 : :
11094 : 3567 : if (modifier != EXPAND_STACK_PARM
11095 : 3567 : && original_target
11096 : 1985 : && safe_from_p (original_target, treeop0, 1)
11097 : 0 : && GET_MODE (original_target) == mode
11098 : 3567 : && !MEM_P (original_target))
11099 : : temp = original_target;
11100 : : else
11101 : 3567 : temp = assign_temp (type, 0, 1);
11102 : :
11103 : 3567 : do_pending_stack_adjust ();
11104 : 3567 : NO_DEFER_POP;
11105 : 3567 : rtx_code_label *lab0 = gen_label_rtx ();
11106 : 3567 : rtx_code_label *lab1 = gen_label_rtx ();
11107 : 3567 : jumpifnot (treeop0, lab0,
11108 : : profile_probability::uninitialized ());
11109 : 3567 : store_expr (treeop1, temp,
11110 : : modifier == EXPAND_STACK_PARM,
11111 : : false, false);
11112 : :
11113 : 3567 : emit_jump_insn (targetm.gen_jump (lab1));
11114 : 3567 : emit_barrier ();
11115 : 3567 : emit_label (lab0);
11116 : 3567 : store_expr (treeop2, temp,
11117 : : modifier == EXPAND_STACK_PARM,
11118 : : false, false);
11119 : :
11120 : 3567 : emit_label (lab1);
11121 : 3567 : OK_DEFER_POP;
11122 : 3567 : return temp;
11123 : : }
11124 : :
11125 : 0 : case VEC_DUPLICATE_EXPR:
11126 : 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
11127 : 0 : target = expand_vector_broadcast (mode, op0);
11128 : 0 : gcc_assert (target);
11129 : : return target;
11130 : :
11131 : 0 : case VEC_SERIES_EXPR:
11132 : 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
11133 : 0 : return expand_vec_series_expr (mode, op0, op1, target);
11134 : :
11135 : 911 : case BIT_INSERT_EXPR:
11136 : 911 : {
11137 : 911 : unsigned bitpos = tree_to_uhwi (treeop2);
11138 : 911 : unsigned bitsize;
11139 : 911 : if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
11140 : 570 : bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
11141 : : else
11142 : 341 : bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
11143 : 911 : op0 = expand_normal (treeop0);
11144 : 911 : op1 = expand_normal (treeop1);
11145 : 911 : rtx dst = gen_reg_rtx (mode);
11146 : 911 : emit_move_insn (dst, op0);
11147 : 911 : store_bit_field (dst, bitsize, bitpos, 0, 0,
11148 : 911 : TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
11149 : 911 : return dst;
11150 : : }
11151 : :
11152 : 0 : default:
11153 : 0 : gcc_unreachable ();
11154 : : }
11155 : :
11156 : : /* Here to do an ordinary binary operator. */
11157 : 1202854 : binop:
11158 : 1202854 : expand_operands (treeop0, treeop1,
11159 : : subtarget, &op0, &op1, EXPAND_NORMAL);
11160 : 5545250 : binop2:
11161 : 5545250 : this_optab = optab_for_tree_code (code, type, optab_default);
11162 : 5545250 : binop3:
11163 : 5545250 : if (modifier == EXPAND_STACK_PARM)
11164 : 24852 : target = 0;
11165 : 5545250 : temp = expand_binop (mode, this_optab, op0, op1, target,
11166 : : unsignedp, OPTAB_LIB_WIDEN);
11167 : 5545250 : gcc_assert (temp);
11168 : : /* Bitwise operations do not need bitfield reduction as we expect their
11169 : : operands being properly truncated. */
11170 : 5545250 : if (code == BIT_XOR_EXPR
11171 : : || code == BIT_AND_EXPR
11172 : 5545250 : || code == BIT_IOR_EXPR)
11173 : : return temp;
11174 : 4897599 : return REDUCE_BIT_FIELD (temp);
11175 : : }
11176 : : #undef REDUCE_BIT_FIELD
11177 : :
11178 : :
11179 : : /* Return TRUE if expression STMT is suitable for replacement.
11180 : : Never consider memory loads as replaceable, because those don't ever lead
11181 : : into constant expressions. */
11182 : :
11183 : : static bool
11184 : 8 : stmt_is_replaceable_p (gimple *stmt)
11185 : : {
11186 : 8 : if (ssa_is_replaceable_p (stmt))
11187 : : {
11188 : : /* Don't move around loads. */
11189 : 7 : if (!gimple_assign_single_p (stmt)
11190 : 7 : || is_gimple_val (gimple_assign_rhs1 (stmt)))
11191 : 6 : return true;
11192 : : }
11193 : : return false;
11194 : : }
11195 : :
11196 : : /* A subroutine of expand_expr_real_1. Expand gimple assignment G,
11197 : : which is known to set an SSA_NAME result. The other arguments are
11198 : : as for expand_expr_real_1. */
11199 : :
11200 : : rtx
11201 : 14484178 : expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
11202 : : enum expand_modifier modifier, rtx *alt_rtl,
11203 : : bool inner_reference_p)
11204 : : {
11205 : 14484178 : separate_ops ops;
11206 : 14484178 : rtx r;
11207 : 14484178 : location_t saved_loc = curr_insn_location ();
11208 : 14484178 : auto loc = gimple_location (g);
11209 : 14484178 : if (loc != UNKNOWN_LOCATION)
11210 : 11666450 : set_curr_insn_location (loc);
11211 : 14484178 : tree lhs = gimple_assign_lhs (g);
11212 : 14484178 : ops.code = gimple_assign_rhs_code (g);
11213 : 14484178 : ops.type = TREE_TYPE (lhs);
11214 : 14484178 : switch (get_gimple_rhs_class (ops.code))
11215 : : {
11216 : 86017 : case GIMPLE_TERNARY_RHS:
11217 : 172034 : ops.op2 = gimple_assign_rhs3 (g);
11218 : : /* Fallthru */
11219 : 7738878 : case GIMPLE_BINARY_RHS:
11220 : 7738878 : ops.op1 = gimple_assign_rhs2 (g);
11221 : :
11222 : : /* Try to expand conditonal compare. */
11223 : 7738878 : if (targetm.have_ccmp ())
11224 : : {
11225 : 1098 : gcc_checking_assert (targetm.gen_ccmp_next != NULL);
11226 : 1098 : r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
11227 : 1098 : if (r)
11228 : : break;
11229 : : }
11230 : : /* Fallthru */
11231 : 11123318 : case GIMPLE_UNARY_RHS:
11232 : 11123318 : ops.op0 = gimple_assign_rhs1 (g);
11233 : 11123318 : ops.location = loc;
11234 : 11123318 : r = expand_expr_real_2 (&ops, target, tmode, modifier);
11235 : 11123318 : break;
11236 : 3360842 : case GIMPLE_SINGLE_RHS:
11237 : 3360842 : {
11238 : 3360842 : r = expand_expr_real (gimple_assign_rhs1 (g), target,
11239 : : tmode, modifier, alt_rtl,
11240 : : inner_reference_p);
11241 : 3360842 : break;
11242 : : }
11243 : 0 : default:
11244 : 0 : gcc_unreachable ();
11245 : : }
11246 : 14484178 : set_curr_insn_location (saved_loc);
11247 : 14484178 : if (REG_P (r) && !REG_EXPR (r))
11248 : 3687468 : set_reg_attrs_for_decl_rtl (lhs, r);
11249 : 14484178 : return r;
11250 : : }
11251 : :
11252 : : rtx
11253 : 153870551 : expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
11254 : : enum expand_modifier modifier, rtx *alt_rtl,
11255 : : bool inner_reference_p)
11256 : : {
11257 : 153870551 : rtx op0, op1, temp, decl_rtl;
11258 : 153870551 : tree type;
11259 : 153870551 : int unsignedp;
11260 : 153870551 : machine_mode mode, dmode;
11261 : 153870551 : enum tree_code code = TREE_CODE (exp);
11262 : 153870551 : rtx subtarget, original_target;
11263 : 153870551 : int ignore;
11264 : 153870551 : bool reduce_bit_field;
11265 : 153870551 : location_t loc = EXPR_LOCATION (exp);
11266 : 153870551 : struct separate_ops ops;
11267 : 153870551 : tree treeop0, treeop1, treeop2;
11268 : 153870551 : tree ssa_name = NULL_TREE;
11269 : 153870551 : gimple *g;
11270 : :
11271 : : /* Some ABIs define padding bits in _BitInt uninitialized. Normally, RTL
11272 : : expansion sign/zero extends integral types with less than mode precision
11273 : : when reading from bit-fields and after arithmetic operations (see
11274 : : REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
11275 : : on those extensions to have been already performed, but because of the
11276 : : above for _BitInt they need to be sign/zero extended when reading from
11277 : : locations that could be exposed to ABI boundaries (when loading from
11278 : : objects in memory, or function arguments, return value). Because we
11279 : : internally extend after arithmetic operations, we can avoid doing that
11280 : : when reading from SSA_NAMEs of vars. */
11281 : : #define EXTEND_BITINT(expr) \
11282 : : ((TREE_CODE (type) == BITINT_TYPE \
11283 : : && reduce_bit_field \
11284 : : && mode != BLKmode \
11285 : : && modifier != EXPAND_MEMORY \
11286 : : && modifier != EXPAND_WRITE \
11287 : : && modifier != EXPAND_INITIALIZER \
11288 : : && modifier != EXPAND_CONST_ADDRESS) \
11289 : : ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
11290 : :
11291 : 153870551 : type = TREE_TYPE (exp);
11292 : 153870551 : mode = TYPE_MODE (type);
11293 : 153870551 : unsignedp = TYPE_UNSIGNED (type);
11294 : :
11295 : 153870551 : treeop0 = treeop1 = treeop2 = NULL_TREE;
11296 : 153870551 : if (!VL_EXP_CLASS_P (exp))
11297 : 147282697 : switch (TREE_CODE_LENGTH (code))
11298 : : {
11299 : 5542964 : default:
11300 : 5542964 : case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
11301 : 13299052 : case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
11302 : 27493106 : case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
11303 : : case 0: break;
11304 : : }
11305 : 153870551 : ops.code = code;
11306 : 153870551 : ops.type = type;
11307 : 153870551 : ops.op0 = treeop0;
11308 : 153870551 : ops.op1 = treeop1;
11309 : 153870551 : ops.op2 = treeop2;
11310 : 153870551 : ops.location = loc;
11311 : :
11312 : 307741102 : ignore = (target == const0_rtx
11313 : 153870551 : || ((CONVERT_EXPR_CODE_P (code)
11314 : 148962114 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
11315 : 928254 : && TREE_CODE (type) == VOID_TYPE));
11316 : :
11317 : : /* An operation in what may be a bit-field type needs the
11318 : : result to be reduced to the precision of the bit-field type,
11319 : : which is narrower than that of the type's mode. */
11320 : 307740883 : reduce_bit_field = (!ignore
11321 : 149553278 : && INTEGRAL_TYPE_P (type)
11322 : 78252211 : && !type_has_mode_precision_p (type));
11323 : :
11324 : : /* If we are going to ignore this result, we need only do something
11325 : : if there is a side-effect somewhere in the expression. If there
11326 : : is, short-circuit the most common cases here. Note that we must
11327 : : not call expand_expr with anything but const0_rtx in case this
11328 : : is an initial expansion of a size that contains a PLACEHOLDER_EXPR. */
11329 : :
11330 : 4317273 : if (ignore)
11331 : : {
11332 : 4317273 : if (! TREE_SIDE_EFFECTS (exp))
11333 : : return const0_rtx;
11334 : :
11335 : : /* Ensure we reference a volatile object even if value is ignored, but
11336 : : don't do this if all we are doing is taking its address. */
11337 : 4317054 : if (TREE_THIS_VOLATILE (exp)
11338 : 0 : && TREE_CODE (exp) != FUNCTION_DECL
11339 : 0 : && mode != VOIDmode && mode != BLKmode
11340 : 0 : && modifier != EXPAND_CONST_ADDRESS)
11341 : : {
11342 : 0 : temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
11343 : 0 : if (MEM_P (temp))
11344 : 0 : copy_to_reg (temp);
11345 : 0 : return const0_rtx;
11346 : : }
11347 : :
11348 : 4317054 : if (TREE_CODE_CLASS (code) == tcc_unary
11349 : : || code == BIT_FIELD_REF
11350 : 4317054 : || code == COMPONENT_REF
11351 : 4317054 : || code == INDIRECT_REF)
11352 : 0 : return expand_expr (treeop0, const0_rtx, VOIDmode,
11353 : 0 : modifier);
11354 : :
11355 : 4317054 : else if (TREE_CODE_CLASS (code) == tcc_binary
11356 : 4317054 : || TREE_CODE_CLASS (code) == tcc_comparison
11357 : 4317054 : || code == ARRAY_REF || code == ARRAY_RANGE_REF)
11358 : : {
11359 : 0 : expand_expr (treeop0, const0_rtx, VOIDmode, modifier);
11360 : 0 : expand_expr (treeop1, const0_rtx, VOIDmode, modifier);
11361 : 0 : return const0_rtx;
11362 : : }
11363 : :
11364 : : target = 0;
11365 : : }
11366 : :
11367 : 153870332 : if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
11368 : 37655 : target = 0;
11369 : :
11370 : : /* Use subtarget as the target for operand 0 of a binary operation. */
11371 : 153870332 : subtarget = get_subtarget (target);
11372 : 153870332 : original_target = target;
11373 : :
11374 : 153870332 : switch (code)
11375 : : {
11376 : 10811 : case LABEL_DECL:
11377 : 10811 : {
11378 : 10811 : tree function = decl_function_context (exp);
11379 : :
11380 : 10811 : temp = label_rtx (exp);
11381 : 14755 : temp = gen_rtx_LABEL_REF (Pmode, temp);
11382 : :
11383 : 10811 : if (function != current_function_decl
11384 : 1263 : && function != 0)
11385 : 1263 : LABEL_REF_NONLOCAL_P (temp) = 1;
11386 : :
11387 : 10811 : temp = gen_rtx_MEM (FUNCTION_MODE, temp);
11388 : 10811 : return temp;
11389 : : }
11390 : :
11391 : 55020330 : case SSA_NAME:
11392 : : /* ??? ivopts calls expander, without any preparation from
11393 : : out-of-ssa. So fake instructions as if this was an access to the
11394 : : base variable. This unnecessarily allocates a pseudo, see how we can
11395 : : reuse it, if partition base vars have it set already. */
11396 : 55020330 : if (!currently_expanding_to_rtl)
11397 : : {
11398 : 0 : tree var = SSA_NAME_VAR (exp);
11399 : 0 : if (var && DECL_RTL_SET_P (var))
11400 : 0 : return DECL_RTL (var);
11401 : 0 : return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
11402 : 0 : LAST_VIRTUAL_REGISTER + 1);
11403 : : }
11404 : :
11405 : 55020330 : g = get_gimple_for_ssa_name (exp);
11406 : : /* For EXPAND_INITIALIZER try harder to get something simpler. */
11407 : 55020330 : if (g == NULL
11408 : 55020330 : && modifier == EXPAND_INITIALIZER
11409 : 26 : && !SSA_NAME_IS_DEFAULT_DEF (exp)
11410 : 11 : && (optimize || !SSA_NAME_VAR (exp)
11411 : 1 : || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
11412 : 10 : && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
11413 : 55020338 : && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
11414 : 6 : g = SSA_NAME_DEF_STMT (exp);
11415 : 55020330 : if (safe_is_a <gassign *> (g))
11416 : 8698094 : return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
11417 : 8698094 : modifier, alt_rtl, inner_reference_p);
11418 : 46322236 : else if (safe_is_a <gcall *> (g))
11419 : : {
11420 : : /* ??? internal call expansion doesn't follow the usual API
11421 : : of returning the destination RTX and being passed a desired
11422 : : target. */
11423 : 65750 : if (modifier == EXPAND_WRITE)
11424 : 32879 : return DECL_RTL (SSA_NAME_VAR (exp));
11425 : 32871 : rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11426 : 32871 : tree tmplhs = make_tree (TREE_TYPE (exp), dest);
11427 : 32871 : tree var_or_id = SSA_NAME_VAR (exp);
11428 : : if (!var_or_id)
11429 : 24901 : var_or_id = SSA_NAME_IDENTIFIER (exp);
11430 : 32871 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, tmplhs);
11431 : 32871 : expand_internal_call (as_a <gcall *> (g));
11432 : 32871 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, var_or_id);
11433 : 32871 : return dest;
11434 : : }
11435 : :
11436 : 46256486 : ssa_name = exp;
11437 : 46256486 : decl_rtl = get_rtx_for_ssa_name (ssa_name);
11438 : 46256486 : exp = SSA_NAME_VAR (ssa_name);
11439 : : /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
11440 : : SSA_NAME computed within the current function. In such case the
11441 : : value have been already extended before. While if it is a function
11442 : : parameter, result or some memory location, we need to be prepared
11443 : : for some other compiler leaving the bits uninitialized. */
11444 : 18241911 : if (!exp || VAR_P (exp))
11445 : : reduce_bit_field = false;
11446 : 46256486 : goto expand_decl_rtl;
11447 : :
11448 : 19596832 : case VAR_DECL:
11449 : : /* Allow accel compiler to handle variables that require special
11450 : : treatment, e.g. if they have been modified in some way earlier in
11451 : : compilation by the adjust_private_decl OpenACC hook. */
11452 : 19596832 : if (flag_openacc && targetm.goacc.expand_var_decl)
11453 : : {
11454 : 0 : temp = targetm.goacc.expand_var_decl (exp);
11455 : 0 : if (temp)
11456 : : return temp;
11457 : : }
11458 : : /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
11459 : : have scalar integer modes to a reg via store_constructor. */
11460 : 19596832 : if (TREE_READONLY (exp)
11461 : 3363553 : && !TREE_SIDE_EFFECTS (exp)
11462 : 3341140 : && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
11463 : 18923 : && immediate_const_ctor_p (DECL_INITIAL (exp))
11464 : 132 : && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
11465 : 100 : && crtl->emit.regno_pointer_align_length
11466 : 19596932 : && !target)
11467 : : {
11468 : 73 : target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11469 : 73 : store_constructor (DECL_INITIAL (exp), target, 0,
11470 : 73 : int_expr_size (DECL_INITIAL (exp)), false);
11471 : 73 : return target;
11472 : : }
11473 : : /* ... fall through ... */
11474 : :
11475 : 20145432 : case PARM_DECL:
11476 : : /* If a static var's type was incomplete when the decl was written,
11477 : : but the type is complete now, lay out the decl now. */
11478 : 20145432 : if (DECL_SIZE (exp) == 0
11479 : 44083 : && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
11480 : 20189406 : && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
11481 : 43974 : layout_decl (exp, 0);
11482 : :
11483 : : /* fall through */
11484 : :
11485 : 21569089 : case FUNCTION_DECL:
11486 : 21569089 : case RESULT_DECL:
11487 : 21569089 : decl_rtl = DECL_RTL (exp);
11488 : 67825575 : expand_decl_rtl:
11489 : 67825575 : gcc_assert (decl_rtl);
11490 : :
11491 : : /* DECL_MODE might change when TYPE_MODE depends on attribute target
11492 : : settings for VECTOR_TYPE_P that might switch for the function. */
11493 : 67825575 : if (currently_expanding_to_rtl
11494 : 64175044 : && code == VAR_DECL && MEM_P (decl_rtl)
11495 : 82400388 : && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
11496 : 57 : decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
11497 : : else
11498 : 67825518 : decl_rtl = copy_rtx (decl_rtl);
11499 : :
11500 : : /* Record writes to register variables. */
11501 : 67825575 : if (modifier == EXPAND_WRITE
11502 : 21419665 : && REG_P (decl_rtl)
11503 : 83459725 : && HARD_REGISTER_P (decl_rtl))
11504 : 2028 : add_to_hard_reg_set (&crtl->asm_clobbers,
11505 : 2028 : GET_MODE (decl_rtl), REGNO (decl_rtl));
11506 : :
11507 : : /* Ensure variable marked as used even if it doesn't go through
11508 : : a parser. If it hasn't be used yet, write out an external
11509 : : definition. */
11510 : 67825575 : if (exp)
11511 : 39811000 : TREE_USED (exp) = 1;
11512 : :
11513 : : /* Show we haven't gotten RTL for this yet. */
11514 : 107636575 : temp = 0;
11515 : :
11516 : : /* Variables inherited from containing functions should have
11517 : : been lowered by this point. */
11518 : 39811000 : if (exp)
11519 : : {
11520 : 39811000 : tree context = decl_function_context (exp);
11521 : 39811000 : gcc_assert (SCOPE_FILE_SCOPE_P (context)
11522 : : || context == current_function_decl
11523 : : || TREE_STATIC (exp)
11524 : : || DECL_EXTERNAL (exp)
11525 : : /* ??? C++ creates functions that are not
11526 : : TREE_STATIC. */
11527 : : || TREE_CODE (exp) == FUNCTION_DECL);
11528 : : }
11529 : :
11530 : : /* This is the case of an array whose size is to be determined
11531 : : from its initializer, while the initializer is still being parsed.
11532 : : ??? We aren't parsing while expanding anymore. */
11533 : :
11534 : 67825575 : if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
11535 : 392066 : temp = validize_mem (decl_rtl);
11536 : :
11537 : : /* If DECL_RTL is memory, we are in the normal case and the
11538 : : address is not valid, get the address into a register. */
11539 : :
11540 : 67433509 : else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
11541 : : {
11542 : 18461797 : if (alt_rtl)
11543 : 2026837 : *alt_rtl = decl_rtl;
11544 : 18461797 : decl_rtl = use_anchored_address (decl_rtl);
11545 : 18461797 : if (modifier != EXPAND_CONST_ADDRESS
11546 : 18461797 : && modifier != EXPAND_SUM
11547 : 30628591 : && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
11548 : 17017 : : GET_MODE (decl_rtl),
11549 : : XEXP (decl_rtl, 0),
11550 : 12166794 : MEM_ADDR_SPACE (decl_rtl)))
11551 : 134339 : temp = replace_equiv_address (decl_rtl,
11552 : : copy_rtx (XEXP (decl_rtl, 0)));
11553 : : }
11554 : :
11555 : : /* If we got something, return it. But first, set the alignment
11556 : : if the address is a register. */
11557 : 18853863 : if (temp != 0)
11558 : : {
11559 : 526405 : if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
11560 : 496332 : mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
11561 : : }
11562 : 67299170 : else if (MEM_P (decl_rtl))
11563 : : temp = decl_rtl;
11564 : :
11565 : 45976271 : if (temp != 0)
11566 : : {
11567 : 22345646 : if (MEM_P (temp)
11568 : : && modifier != EXPAND_WRITE
11569 : 22345646 : && modifier != EXPAND_MEMORY
11570 : : && modifier != EXPAND_INITIALIZER
11571 : 16472575 : && modifier != EXPAND_CONST_ADDRESS
11572 : 6836954 : && modifier != EXPAND_SUM
11573 : 6836954 : && !inner_reference_p
11574 : 4453220 : && mode != BLKmode
11575 : 26430068 : && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
11576 : 19793 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11577 : 19793 : MEM_ALIGN (temp), NULL_RTX, NULL);
11578 : :
11579 : 22345646 : return EXTEND_BITINT (temp);
11580 : : }
11581 : :
11582 : 45479929 : if (exp)
11583 : 17482381 : dmode = DECL_MODE (exp);
11584 : : else
11585 : 27997548 : dmode = TYPE_MODE (TREE_TYPE (ssa_name));
11586 : :
11587 : : /* If the mode of DECL_RTL does not match that of the decl,
11588 : : there are two cases: we are dealing with a BLKmode value
11589 : : that is returned in a register, or we are dealing with
11590 : : a promoted value. In the latter case, return a SUBREG
11591 : : of the wanted mode, but mark it so that we know that it
11592 : : was already extended. */
11593 : 45479929 : if (REG_P (decl_rtl)
11594 : 45003215 : && dmode != BLKmode
11595 : 45003215 : && GET_MODE (decl_rtl) != dmode)
11596 : : {
11597 : 70 : machine_mode pmode;
11598 : :
11599 : : /* Get the signedness to be used for this variable. Ensure we get
11600 : : the same mode we got when the variable was declared. */
11601 : 70 : if (code != SSA_NAME)
11602 : 0 : pmode = promote_decl_mode (exp, &unsignedp);
11603 : 70 : else if ((g = SSA_NAME_DEF_STMT (ssa_name))
11604 : 70 : && gimple_code (g) == GIMPLE_CALL
11605 : 72 : && !gimple_call_internal_p (g))
11606 : 2 : pmode = promote_function_mode (type, mode, &unsignedp,
11607 : 2 : gimple_call_fntype (g),
11608 : : 2);
11609 : : else
11610 : 68 : pmode = promote_ssa_mode (ssa_name, &unsignedp);
11611 : 70 : gcc_assert (GET_MODE (decl_rtl) == pmode);
11612 : :
11613 : : /* Some ABIs require scalar floating point modes to be passed
11614 : : in a wider scalar integer mode. We need to explicitly
11615 : : truncate to an integer mode of the correct precision before
11616 : : using a SUBREG to reinterpret as a floating point value. */
11617 : 70 : if (SCALAR_FLOAT_MODE_P (mode)
11618 : 0 : && SCALAR_INT_MODE_P (pmode)
11619 : 70 : && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
11620 : 0 : return convert_wider_int_to_float (mode, pmode, decl_rtl);
11621 : :
11622 : 70 : temp = gen_lowpart_SUBREG (mode, decl_rtl);
11623 : 70 : SUBREG_PROMOTED_VAR_P (temp) = 1;
11624 : 70 : SUBREG_PROMOTED_SET (temp, unsignedp);
11625 : 70 : return EXTEND_BITINT (temp);
11626 : : }
11627 : :
11628 : 45479859 : return EXTEND_BITINT (decl_rtl);
11629 : :
11630 : 41433192 : case INTEGER_CST:
11631 : 41433192 : {
11632 : 41433192 : if (TREE_CODE (type) == BITINT_TYPE)
11633 : : {
11634 : 10586 : unsigned int prec = TYPE_PRECISION (type);
11635 : 10586 : struct bitint_info info;
11636 : 10586 : bool ok = targetm.c.bitint_type_info (prec, &info);
11637 : 10586 : gcc_assert (ok);
11638 : 10586 : scalar_int_mode limb_mode
11639 : 10586 : = as_a <scalar_int_mode> (info.limb_mode);
11640 : 10586 : unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
11641 : 17462 : if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
11642 : : {
11643 : : /* Emit large/huge _BitInt INTEGER_CSTs into memory. */
11644 : 4431 : exp = tree_output_constant_def (exp);
11645 : 4431 : return expand_expr (exp, target, VOIDmode, modifier);
11646 : : }
11647 : : }
11648 : :
11649 : : /* Given that TYPE_PRECISION (type) is not always equal to
11650 : : GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
11651 : : the former to the latter according to the signedness of the
11652 : : type. */
11653 : 41428761 : scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
11654 : 41428761 : temp = immed_wide_int_const
11655 : 41428761 : (wi::to_wide (exp, GET_MODE_PRECISION (int_mode)), int_mode);
11656 : 41428761 : return temp;
11657 : : }
11658 : :
11659 : 540482 : case VECTOR_CST:
11660 : 540482 : {
11661 : 540482 : tree tmp = NULL_TREE;
11662 : 540482 : if (VECTOR_MODE_P (mode))
11663 : 538627 : return const_vector_from_tree (exp);
11664 : 1855 : scalar_int_mode int_mode;
11665 : 1855 : if (is_int_mode (mode, &int_mode))
11666 : : {
11667 : 188 : tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
11668 : 188 : if (type_for_mode)
11669 : 188 : tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
11670 : : type_for_mode, exp);
11671 : : }
11672 : 188 : if (!tmp)
11673 : : {
11674 : 1667 : vec<constructor_elt, va_gc> *v;
11675 : : /* Constructors need to be fixed-length. FIXME. */
11676 : 1667 : unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
11677 : 1667 : vec_alloc (v, nunits);
11678 : 24044 : for (unsigned int i = 0; i < nunits; ++i)
11679 : 22377 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
11680 : 1667 : tmp = build_constructor (type, v);
11681 : : }
11682 : 1855 : return expand_expr (tmp, ignore ? const0_rtx : target,
11683 : 1855 : tmode, modifier);
11684 : : }
11685 : :
11686 : 128 : case CONST_DECL:
11687 : 128 : if (modifier == EXPAND_WRITE)
11688 : : {
11689 : : /* Writing into CONST_DECL is always invalid, but handle it
11690 : : gracefully. */
11691 : 2 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
11692 : 2 : scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
11693 : 2 : op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
11694 : : EXPAND_NORMAL, as);
11695 : 2 : op0 = memory_address_addr_space (mode, op0, as);
11696 : 2 : temp = gen_rtx_MEM (mode, op0);
11697 : 2 : set_mem_addr_space (temp, as);
11698 : 2 : return temp;
11699 : : }
11700 : 126 : return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
11701 : :
11702 : 863900 : case REAL_CST:
11703 : : /* If optimized, generate immediate CONST_DOUBLE
11704 : : which will be turned into memory by reload if necessary.
11705 : :
11706 : : We used to force a register so that loop.c could see it. But
11707 : : this does not allow gen_* patterns to perform optimizations with
11708 : : the constants. It also produces two insns in cases like "x = 1.0;".
11709 : : On most machines, floating-point constants are not permitted in
11710 : : many insns, so we'd end up copying it to a register in any case.
11711 : :
11712 : : Now, we do the copying in expand_binop, if appropriate. */
11713 : 863900 : return const_double_from_real_value (TREE_REAL_CST (exp),
11714 : 1727800 : TYPE_MODE (TREE_TYPE (exp)));
11715 : :
11716 : 0 : case FIXED_CST:
11717 : 0 : return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
11718 : : TYPE_MODE (TREE_TYPE (exp)));
11719 : :
11720 : 18352 : case COMPLEX_CST:
11721 : : /* Handle evaluating a complex constant in a CONCAT target. */
11722 : 18352 : if (original_target && GET_CODE (original_target) == CONCAT)
11723 : : {
11724 : 224 : rtx rtarg, itarg;
11725 : :
11726 : 224 : mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
11727 : 224 : rtarg = XEXP (original_target, 0);
11728 : 224 : itarg = XEXP (original_target, 1);
11729 : :
11730 : : /* Move the real and imaginary parts separately. */
11731 : 224 : op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, EXPAND_NORMAL);
11732 : 224 : op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, EXPAND_NORMAL);
11733 : :
11734 : 224 : if (op0 != rtarg)
11735 : 224 : emit_move_insn (rtarg, op0);
11736 : 224 : if (op1 != itarg)
11737 : 224 : emit_move_insn (itarg, op1);
11738 : :
11739 : 224 : return original_target;
11740 : : }
11741 : :
11742 : : /* fall through */
11743 : :
11744 : 173000 : case STRING_CST:
11745 : 173000 : temp = expand_expr_constant (exp, 1, modifier);
11746 : :
11747 : : /* temp contains a constant address.
11748 : : On RISC machines where a constant address isn't valid,
11749 : : make some insns to get that address into a register. */
11750 : 173000 : if (modifier != EXPAND_CONST_ADDRESS
11751 : : && modifier != EXPAND_INITIALIZER
11752 : 173000 : && modifier != EXPAND_SUM
11753 : 191716 : && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
11754 : 18716 : MEM_ADDR_SPACE (temp)))
11755 : 12 : return replace_equiv_address (temp,
11756 : 12 : copy_rtx (XEXP (temp, 0)));
11757 : : return temp;
11758 : :
11759 : 0 : case POLY_INT_CST:
11760 : 0 : return immed_wide_int_const (poly_int_cst_value (exp), mode);
11761 : :
11762 : 1365 : case SAVE_EXPR:
11763 : 1365 : {
11764 : 1365 : tree val = treeop0;
11765 : 1365 : rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
11766 : : inner_reference_p);
11767 : :
11768 : 1365 : if (!SAVE_EXPR_RESOLVED_P (exp))
11769 : : {
11770 : : /* We can indeed still hit this case, typically via builtin
11771 : : expanders calling save_expr immediately before expanding
11772 : : something. Assume this means that we only have to deal
11773 : : with non-BLKmode values. */
11774 : 1340 : gcc_assert (GET_MODE (ret) != BLKmode);
11775 : :
11776 : 1340 : val = build_decl (curr_insn_location (),
11777 : 1340 : VAR_DECL, NULL, TREE_TYPE (exp));
11778 : 1340 : DECL_ARTIFICIAL (val) = 1;
11779 : 1340 : DECL_IGNORED_P (val) = 1;
11780 : 1340 : treeop0 = val;
11781 : 1340 : TREE_OPERAND (exp, 0) = treeop0;
11782 : 1340 : SAVE_EXPR_RESOLVED_P (exp) = 1;
11783 : :
11784 : 1340 : if (!CONSTANT_P (ret))
11785 : 1340 : ret = copy_to_reg (ret);
11786 : 1340 : SET_DECL_RTL (val, ret);
11787 : : }
11788 : :
11789 : : return ret;
11790 : : }
11791 : :
11792 : :
11793 : 178354 : case CONSTRUCTOR:
11794 : : /* If we don't need the result, just ensure we evaluate any
11795 : : subexpressions. */
11796 : 178354 : if (ignore)
11797 : : {
11798 : : unsigned HOST_WIDE_INT idx;
11799 : : tree value;
11800 : :
11801 : 0 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
11802 : 0 : expand_expr (value, const0_rtx, VOIDmode, EXPAND_NORMAL);
11803 : :
11804 : 0 : return const0_rtx;
11805 : : }
11806 : :
11807 : 178354 : return expand_constructor (exp, target, modifier, false);
11808 : :
11809 : 845258 : case TARGET_MEM_REF:
11810 : 845258 : {
11811 : 845258 : addr_space_t as
11812 : 845258 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
11813 : 845258 : unsigned int align;
11814 : :
11815 : 845258 : op0 = addr_for_mem_ref (exp, as, true);
11816 : 845258 : op0 = memory_address_addr_space (mode, op0, as);
11817 : 845258 : temp = gen_rtx_MEM (mode, op0);
11818 : 845258 : set_mem_attributes (temp, exp, 0);
11819 : 845258 : set_mem_addr_space (temp, as);
11820 : 845258 : align = get_object_alignment (exp);
11821 : 845258 : if (modifier != EXPAND_WRITE
11822 : 845258 : && modifier != EXPAND_MEMORY
11823 : 591891 : && mode != BLKmode
11824 : 1411453 : && align < GET_MODE_ALIGNMENT (mode))
11825 : 59048 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11826 : : align, NULL_RTX, NULL);
11827 : 845258 : return EXTEND_BITINT (temp);
11828 : : }
11829 : :
11830 : 6479270 : case MEM_REF:
11831 : 6479270 : {
11832 : 6479270 : const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
11833 : 6479270 : addr_space_t as
11834 : 6479270 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
11835 : 6479270 : machine_mode address_mode;
11836 : 6479270 : tree base = TREE_OPERAND (exp, 0);
11837 : 6479270 : gimple *def_stmt;
11838 : 6479270 : unsigned align;
11839 : : /* Handle expansion of non-aliased memory with non-BLKmode. That
11840 : : might end up in a register. */
11841 : 6479270 : if (mem_ref_refers_to_non_mem_p (exp))
11842 : : {
11843 : 86820 : poly_int64 offset = mem_ref_offset (exp).force_shwi ();
11844 : 86820 : base = TREE_OPERAND (base, 0);
11845 : 86820 : poly_uint64 type_size;
11846 : 86820 : if (known_eq (offset, 0)
11847 : 51343 : && !reverse
11848 : 51343 : && poly_int_tree_p (TYPE_SIZE (type), &type_size)
11849 : 189506 : && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
11850 : 26201 : return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
11851 : 26201 : target, tmode, modifier);
11852 : 60619 : unsigned align;
11853 : 60619 : if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
11854 : : {
11855 : 197 : temp = assign_stack_temp (DECL_MODE (base),
11856 : 394 : GET_MODE_SIZE (DECL_MODE (base)));
11857 : 197 : store_expr (base, temp, 0, false, false);
11858 : 197 : temp = adjust_address (temp, TYPE_MODE (type), offset);
11859 : 197 : if (TYPE_MODE (type) == BLKmode)
11860 : 182 : set_mem_size (temp, int_size_in_bytes (type));
11861 : : /* When the original ref was misaligned so will be the
11862 : : access to the stack temporary. Not all targets handle
11863 : : this correctly, some will ICE in sanity checking.
11864 : : Handle this by doing bitfield extraction when necessary. */
11865 : 30 : else if ((align = get_object_alignment (exp))
11866 : 15 : < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
11867 : 3 : temp
11868 : 3 : = expand_misaligned_mem_ref (temp, TYPE_MODE (type),
11869 : : unsignedp, align,
11870 : : modifier == EXPAND_STACK_PARM
11871 : : ? NULL_RTX : target, NULL);
11872 : 197 : return temp;
11873 : : }
11874 : : /* When the access is fully outside of the underlying object
11875 : : expand the offset as zero. This avoids out-of-bound
11876 : : BIT_FIELD_REFs and generates smaller code for these cases
11877 : : with UB. */
11878 : 60422 : type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
11879 : 120844 : if (!ranges_maybe_overlap_p (offset, type_size, 0,
11880 : 120844 : GET_MODE_SIZE (DECL_MODE (base))))
11881 : 147 : offset = 0;
11882 : 60422 : exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
11883 : 60422 : bitsize_int (offset * BITS_PER_UNIT));
11884 : 60422 : REF_REVERSE_STORAGE_ORDER (exp) = reverse;
11885 : 60422 : return expand_expr (exp, target, tmode, modifier);
11886 : : }
11887 : 6392450 : address_mode = targetm.addr_space.address_mode (as);
11888 : 6392450 : if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
11889 : : {
11890 : 38 : tree mask = gimple_assign_rhs2 (def_stmt);
11891 : 38 : base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
11892 : : gimple_assign_rhs1 (def_stmt), mask);
11893 : 38 : TREE_OPERAND (exp, 0) = base;
11894 : : }
11895 : 6392450 : align = get_object_alignment (exp);
11896 : 6392450 : op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
11897 : 6392450 : op0 = memory_address_addr_space (mode, op0, as);
11898 : 6392450 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
11899 : : {
11900 : 1953660 : rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
11901 : 1953660 : op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
11902 : 1953660 : op0 = memory_address_addr_space (mode, op0, as);
11903 : : }
11904 : 6392450 : temp = gen_rtx_MEM (mode, op0);
11905 : 6392450 : set_mem_attributes (temp, exp, 0);
11906 : 6392450 : set_mem_addr_space (temp, as);
11907 : 6392450 : if (TREE_THIS_VOLATILE (exp))
11908 : 11478 : MEM_VOLATILE_P (temp) = 1;
11909 : 6392450 : if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
11910 : : return temp;
11911 : 3842916 : if (!inner_reference_p
11912 : 1936715 : && mode != BLKmode
11913 : 5718645 : && align < GET_MODE_ALIGNMENT (mode))
11914 : 132088 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
11915 : : modifier == EXPAND_STACK_PARM
11916 : : ? NULL_RTX : target, alt_rtl);
11917 : 3842916 : if (reverse)
11918 : 7 : temp = flip_storage_order (mode, temp);
11919 : 3842916 : return EXTEND_BITINT (temp);
11920 : : }
11921 : :
11922 : 607305 : case ARRAY_REF:
11923 : :
11924 : 607305 : {
11925 : 607305 : tree array = treeop0;
11926 : 607305 : tree index = treeop1;
11927 : 607305 : tree init;
11928 : :
11929 : : /* Fold an expression like: "foo"[2].
11930 : : This is not done in fold so it won't happen inside &.
11931 : : Don't fold if this is for wide characters since it's too
11932 : : difficult to do correctly and this is a very rare case. */
11933 : :
11934 : 607305 : if (modifier != EXPAND_CONST_ADDRESS
11935 : 607305 : && modifier != EXPAND_INITIALIZER
11936 : 607305 : && modifier != EXPAND_MEMORY)
11937 : : {
11938 : 607196 : tree t = fold_read_from_constant_string (exp);
11939 : :
11940 : 607196 : if (t)
11941 : 0 : return expand_expr (t, target, tmode, modifier);
11942 : : }
11943 : :
11944 : : /* If this is a constant index into a constant array,
11945 : : just get the value from the array. Handle both the cases when
11946 : : we have an explicit constructor and when our operand is a variable
11947 : : that was declared const. */
11948 : :
11949 : 607305 : if (modifier != EXPAND_CONST_ADDRESS
11950 : : && modifier != EXPAND_INITIALIZER
11951 : : && modifier != EXPAND_MEMORY
11952 : 607196 : && TREE_CODE (array) == CONSTRUCTOR
11953 : 0 : && ! TREE_SIDE_EFFECTS (array)
11954 : 607305 : && TREE_CODE (index) == INTEGER_CST)
11955 : : {
11956 : : unsigned HOST_WIDE_INT ix;
11957 : : tree field, value;
11958 : :
11959 : 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
11960 : : field, value)
11961 : 0 : if (tree_int_cst_equal (field, index))
11962 : : {
11963 : 0 : if (!TREE_SIDE_EFFECTS (value)
11964 : 0 : && TREE_CODE (value) != RAW_DATA_CST)
11965 : 0 : return expand_expr (fold (value), target, tmode, modifier);
11966 : : break;
11967 : : }
11968 : : }
11969 : :
11970 : 607305 : else if (optimize >= 1
11971 : : && modifier != EXPAND_CONST_ADDRESS
11972 : 341518 : && modifier != EXPAND_INITIALIZER
11973 : 341518 : && modifier != EXPAND_MEMORY
11974 : 341413 : && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
11975 : 11163 : && TREE_CODE (index) == INTEGER_CST
11976 : 1692 : && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
11977 : 607441 : && (init = ctor_for_folding (array)) != error_mark_node)
11978 : : {
11979 : 98 : if (init == NULL_TREE)
11980 : : {
11981 : 5 : tree value = build_zero_cst (type);
11982 : 5 : if (TREE_CODE (value) == CONSTRUCTOR)
11983 : : {
11984 : : /* If VALUE is a CONSTRUCTOR, this optimization is only
11985 : : useful if this doesn't store the CONSTRUCTOR into
11986 : : memory. If it does, it is more efficient to just
11987 : : load the data from the array directly. */
11988 : 5 : rtx ret = expand_constructor (value, target,
11989 : : modifier, true);
11990 : 5 : if (ret == NULL_RTX)
11991 : : value = NULL_TREE;
11992 : : }
11993 : :
11994 : : if (value)
11995 : 0 : return expand_expr (value, target, tmode, modifier);
11996 : : }
11997 : 93 : else if (TREE_CODE (init) == CONSTRUCTOR)
11998 : : {
11999 : : unsigned HOST_WIDE_INT ix;
12000 : : tree field, value;
12001 : :
12002 : 190 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
12003 : : field, value)
12004 : 165 : if (tree_int_cst_equal (field, index))
12005 : : {
12006 : 67 : if (TREE_SIDE_EFFECTS (value)
12007 : 67 : || TREE_CODE (value) == RAW_DATA_CST)
12008 : : break;
12009 : :
12010 : 67 : if (TREE_CODE (value) == CONSTRUCTOR)
12011 : : {
12012 : : /* If VALUE is a CONSTRUCTOR, this
12013 : : optimization is only useful if
12014 : : this doesn't store the CONSTRUCTOR
12015 : : into memory. If it does, it is more
12016 : : efficient to just load the data from
12017 : : the array directly. */
12018 : 62 : rtx ret = expand_constructor (value, target,
12019 : : modifier, true);
12020 : 62 : if (ret == NULL_RTX)
12021 : : break;
12022 : : }
12023 : :
12024 : 29 : return expand_expr (fold (value), target, tmode,
12025 : 29 : modifier);
12026 : : }
12027 : : }
12028 : 1 : else if (TREE_CODE (init) == STRING_CST)
12029 : : {
12030 : 1 : tree low_bound = array_ref_low_bound (exp);
12031 : 1 : tree index1 = fold_convert_loc (loc, sizetype, treeop1);
12032 : :
12033 : : /* Optimize the special case of a zero lower bound.
12034 : :
12035 : : We convert the lower bound to sizetype to avoid problems
12036 : : with constant folding. E.g. suppose the lower bound is
12037 : : 1 and its mode is QI. Without the conversion
12038 : : (ARRAY + (INDEX - (unsigned char)1))
12039 : : becomes
12040 : : (ARRAY + (-(unsigned char)1) + INDEX)
12041 : : which becomes
12042 : : (ARRAY + 255 + INDEX). Oops! */
12043 : 1 : if (!integer_zerop (low_bound))
12044 : 0 : index1 = size_diffop_loc (loc, index1,
12045 : : fold_convert_loc (loc, sizetype,
12046 : : low_bound));
12047 : :
12048 : 1 : if (tree_fits_uhwi_p (index1)
12049 : 2 : && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
12050 : : {
12051 : 0 : tree char_type = TREE_TYPE (TREE_TYPE (init));
12052 : 0 : scalar_int_mode char_mode;
12053 : :
12054 : 607276 : if (is_int_mode (TYPE_MODE (char_type), &char_mode)
12055 : 0 : && GET_MODE_SIZE (char_mode) == 1)
12056 : 0 : return gen_int_mode (TREE_STRING_POINTER (init)
12057 : 0 : [TREE_INT_CST_LOW (index1)],
12058 : : char_mode);
12059 : : }
12060 : : }
12061 : : }
12062 : : }
12063 : 607276 : goto normal_inner_ref;
12064 : :
12065 : 3757864 : case COMPONENT_REF:
12066 : 3757864 : gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
12067 : : /* Fall through. */
12068 : 4628335 : case BIT_FIELD_REF:
12069 : 4628335 : case ARRAY_RANGE_REF:
12070 : 3757864 : normal_inner_ref:
12071 : 4628335 : {
12072 : 4628335 : machine_mode mode1, mode2;
12073 : 4628335 : poly_int64 bitsize, bitpos, bytepos;
12074 : 4628335 : tree offset;
12075 : 4628335 : int reversep, volatilep = 0;
12076 : 4628335 : tree tem
12077 : 4628335 : = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
12078 : : &unsignedp, &reversep, &volatilep);
12079 : 4628335 : rtx orig_op0, memloc;
12080 : 4628335 : bool clear_mem_expr = false;
12081 : 4628335 : bool must_force_mem;
12082 : :
12083 : : /* If we got back the original object, something is wrong. Perhaps
12084 : : we are evaluating an expression too early. In any event, don't
12085 : : infinitely recurse. */
12086 : 4628335 : gcc_assert (tem != exp);
12087 : :
12088 : : /* Make sure bitpos is not negative, this can wreak havoc later. */
12089 : 4628335 : if (maybe_lt (bitpos, 0))
12090 : : {
12091 : 247 : gcc_checking_assert (offset == NULL_TREE);
12092 : 247 : offset = size_int (bits_to_bytes_round_down (bitpos));
12093 : 247 : bitpos = num_trailing_bits (bitpos);
12094 : : }
12095 : :
12096 : : /* If we have either an offset, a BLKmode result, or a reference
12097 : : outside the underlying object, we must force it to memory.
12098 : : Such a case can occur in Ada if we have unchecked conversion
12099 : : of an expression from a scalar type to an aggregate type or
12100 : : for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
12101 : : passed a partially uninitialized object or a view-conversion
12102 : : to a larger size. */
12103 : 9256670 : must_force_mem = offset != NULL_TREE
12104 : 4350150 : || mode1 == BLKmode
12105 : 8900300 : || (mode == BLKmode
12106 : 0 : && !int_mode_for_size (bitsize, 1).exists ());
12107 : :
12108 : 540149 : const enum expand_modifier tem_modifier
12109 : : = must_force_mem
12110 : : ? EXPAND_MEMORY
12111 : 4271965 : : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
12112 : :
12113 : : /* If TEM's type is a union of variable size, pass TARGET to the inner
12114 : : computation, since it will need a temporary and TARGET is known
12115 : : to have to do. This occurs in unchecked conversion in Ada. */
12116 : 4628335 : const rtx tem_target
12117 : 4628335 : = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12118 : 36375 : && COMPLETE_TYPE_P (TREE_TYPE (tem))
12119 : 36370 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
12120 : 0 : && modifier != EXPAND_STACK_PARM
12121 : 4628335 : ? target
12122 : : : NULL_RTX;
12123 : :
12124 : 9256670 : orig_op0 = op0
12125 : 4628335 : = expand_expr_real (tem, tem_target, VOIDmode, tem_modifier, NULL,
12126 : : true);
12127 : :
12128 : : /* If the field has a mode, we want to access it in the
12129 : : field's mode, not the computed mode.
12130 : : If a MEM has VOIDmode (external with incomplete type),
12131 : : use BLKmode for it instead. */
12132 : 4628335 : if (MEM_P (op0))
12133 : : {
12134 : 4288547 : if (mode1 != VOIDmode)
12135 : 4105263 : op0 = adjust_address (op0, mode1, 0);
12136 : 183284 : else if (GET_MODE (op0) == VOIDmode)
12137 : 0 : op0 = adjust_address (op0, BLKmode, 0);
12138 : : }
12139 : :
12140 : 4628335 : mode2
12141 : 4628335 : = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
12142 : :
12143 : : /* See above for the rationale. */
12144 : 9256670 : if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
12145 : 2908761 : must_force_mem = true;
12146 : :
12147 : : /* Handle CONCAT first. */
12148 : 4628335 : if (GET_CODE (op0) == CONCAT && !must_force_mem)
12149 : : {
12150 : 126 : if (known_eq (bitpos, 0)
12151 : 230 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
12152 : 110 : && COMPLEX_MODE_P (mode1)
12153 : 105 : && COMPLEX_MODE_P (GET_MODE (op0))
12154 : 441 : && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
12155 : 210 : == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
12156 : : {
12157 : 105 : if (reversep)
12158 : 0 : op0 = flip_storage_order (GET_MODE (op0), op0);
12159 : 105 : if (mode1 != GET_MODE (op0))
12160 : : {
12161 : : rtx parts[2];
12162 : 0 : for (int i = 0; i < 2; i++)
12163 : : {
12164 : 0 : rtx op = read_complex_part (op0, i != 0);
12165 : 0 : if (GET_CODE (op) == SUBREG)
12166 : 0 : op = force_reg (GET_MODE (op), op);
12167 : 0 : temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
12168 : 0 : if (temp)
12169 : : op = temp;
12170 : : else
12171 : : {
12172 : 0 : if (!REG_P (op) && !MEM_P (op))
12173 : 0 : op = force_reg (GET_MODE (op), op);
12174 : 0 : op = gen_lowpart (GET_MODE_INNER (mode1), op);
12175 : : }
12176 : 0 : parts[i] = op;
12177 : : }
12178 : 0 : op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
12179 : : }
12180 : 105 : return op0;
12181 : : }
12182 : 21 : if (known_eq (bitpos, 0)
12183 : 20 : && known_eq (bitsize,
12184 : : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12185 : 23 : && maybe_ne (bitsize, 0))
12186 : : {
12187 : : op0 = XEXP (op0, 0);
12188 : : mode2 = GET_MODE (op0);
12189 : : }
12190 : 19 : else if (known_eq (bitpos,
12191 : : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12192 : 4 : && known_eq (bitsize,
12193 : : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
12194 : 0 : && maybe_ne (bitpos, 0)
12195 : 19 : && maybe_ne (bitsize, 0))
12196 : : {
12197 : 0 : op0 = XEXP (op0, 1);
12198 : 0 : bitpos = 0;
12199 : 0 : mode2 = GET_MODE (op0);
12200 : : }
12201 : : else
12202 : : /* Otherwise force into memory. */
12203 : : must_force_mem = true;
12204 : : }
12205 : :
12206 : : /* If this is a constant, put it in a register if it is a legitimate
12207 : : constant and we don't need a memory reference. */
12208 : 4628230 : if (CONSTANT_P (op0)
12209 : 45 : && mode2 != BLKmode
12210 : 45 : && targetm.legitimate_constant_p (mode2, op0)
12211 : 4628263 : && !must_force_mem)
12212 : 33 : op0 = force_reg (mode2, op0);
12213 : :
12214 : : /* Otherwise, if this is a constant, try to force it to the constant
12215 : : pool. Note that back-ends, e.g. MIPS, may refuse to do so if it
12216 : : is a legitimate constant. */
12217 : 4628197 : else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
12218 : 12 : op0 = validize_mem (memloc);
12219 : :
12220 : : /* Otherwise, if this is a constant or the object is not in memory
12221 : : and need be, put it there. */
12222 : 4628185 : else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
12223 : : {
12224 : 1271 : poly_int64 size;
12225 : 1271 : if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
12226 : 0 : size = max_int_size_in_bytes (TREE_TYPE (tem));
12227 : 1271 : memloc = assign_stack_local (TYPE_MODE (TREE_TYPE (tem)), size,
12228 : 1271 : TREE_CODE (tem) == SSA_NAME
12229 : 9 : ? TYPE_ALIGN (TREE_TYPE (tem))
12230 : 1262 : : get_object_alignment (tem));
12231 : 1271 : emit_move_insn (memloc, op0);
12232 : 1271 : op0 = memloc;
12233 : 1271 : clear_mem_expr = true;
12234 : : }
12235 : :
12236 : 4628230 : if (offset)
12237 : : {
12238 : 278185 : machine_mode address_mode;
12239 : 278185 : rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
12240 : : EXPAND_SUM);
12241 : :
12242 : 278185 : gcc_assert (MEM_P (op0));
12243 : :
12244 : 278185 : address_mode = get_address_mode (op0);
12245 : 278185 : if (GET_MODE (offset_rtx) != address_mode)
12246 : : {
12247 : : /* We cannot be sure that the RTL in offset_rtx is valid outside
12248 : : of a memory address context, so force it into a register
12249 : : before attempting to convert it to the desired mode. */
12250 : 414 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
12251 : 414 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
12252 : : }
12253 : :
12254 : : /* See the comment in expand_assignment for the rationale. */
12255 : 278185 : if (mode1 != VOIDmode
12256 : 277951 : && maybe_ne (bitpos, 0)
12257 : 69014 : && maybe_gt (bitsize, 0)
12258 : 347199 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12259 : 346647 : && multiple_p (bitpos, bitsize)
12260 : 136924 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
12261 : 346647 : && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
12262 : : {
12263 : 68435 : op0 = adjust_address (op0, mode1, bytepos);
12264 : 68435 : bitpos = 0;
12265 : : }
12266 : :
12267 : 278185 : op0 = offset_address (op0, offset_rtx,
12268 : : highest_pow2_factor (offset));
12269 : : }
12270 : :
12271 : : /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
12272 : : record its alignment as BIGGEST_ALIGNMENT. */
12273 : 4628230 : if (MEM_P (op0)
12274 : 4289830 : && known_eq (bitpos, 0)
12275 : 1462837 : && offset != 0
12276 : 4905670 : && is_aligning_offset (offset, tem))
12277 : 0 : set_mem_align (op0, BIGGEST_ALIGNMENT);
12278 : :
12279 : : /* Don't forget about volatility even if this is a bitfield. */
12280 : 4628230 : if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
12281 : : {
12282 : 375 : if (op0 == orig_op0)
12283 : 123 : op0 = copy_rtx (op0);
12284 : :
12285 : 375 : MEM_VOLATILE_P (op0) = 1;
12286 : : }
12287 : :
12288 : 4628230 : if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
12289 : : {
12290 : 6 : if (op0 == orig_op0)
12291 : 0 : op0 = copy_rtx (op0);
12292 : :
12293 : 6 : set_mem_align (op0, BITS_PER_UNIT);
12294 : : }
12295 : :
12296 : : /* In cases where an aligned union has an unaligned object
12297 : : as a field, we might be extracting a BLKmode value from
12298 : : an integer-mode (e.g., SImode) object. Handle this case
12299 : : by doing the extract into an object as wide as the field
12300 : : (which we know to be the width of a basic mode), then
12301 : : storing into memory, and changing the mode to BLKmode. */
12302 : 4628230 : if (mode1 == VOIDmode
12303 : 4369204 : || REG_P (op0) || GET_CODE (op0) == SUBREG
12304 : 4106440 : || (mode1 != BLKmode && ! direct_load[(int) mode1]
12305 : 26627 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
12306 : 22477 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
12307 : : && modifier != EXPAND_CONST_ADDRESS
12308 : 15491 : && modifier != EXPAND_INITIALIZER
12309 : 15491 : && modifier != EXPAND_MEMORY)
12310 : : /* If the bitfield is volatile and the bitsize
12311 : : is narrower than the access size of the bitfield,
12312 : : we need to extract bitfields from the access. */
12313 : 4090949 : || (volatilep && TREE_CODE (exp) == COMPONENT_REF
12314 : 1301 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
12315 : 10 : && mode1 != BLKmode
12316 : 20 : && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
12317 : : /* If the field isn't aligned enough to fetch as a memref,
12318 : : fetch it as a bit field. */
12319 : 4090940 : || (mode1 != BLKmode
12320 : 4011928 : && (((MEM_P (op0)
12321 : 4011928 : ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
12322 : 7869885 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
12323 : 0 : : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
12324 : 0 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
12325 : 79606 : && modifier != EXPAND_MEMORY
12326 : 79606 : && ((modifier == EXPAND_CONST_ADDRESS
12327 : 79606 : || modifier == EXPAND_INITIALIZER)
12328 : 79606 : ? STRICT_ALIGNMENT
12329 : 79606 : : targetm.slow_unaligned_access (mode1,
12330 : 79606 : MEM_ALIGN (op0))))
12331 : 4011928 : || !multiple_p (bitpos, BITS_PER_UNIT)))
12332 : : /* If the type and the field are a constant size and the
12333 : : size of the type isn't the same size as the bitfield,
12334 : : we must use bitfield operations. */
12335 : 12731098 : || (known_size_p (bitsize)
12336 : 4090940 : && TYPE_SIZE (TREE_TYPE (exp))
12337 : 4090940 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
12338 : 4090940 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
12339 : : bitsize)))
12340 : : {
12341 : 537303 : machine_mode ext_mode = mode;
12342 : :
12343 : 537303 : if (ext_mode == BLKmode
12344 : 537303 : && ! (target != 0 && MEM_P (op0)
12345 : 6 : && MEM_P (target)
12346 : 6 : && multiple_p (bitpos, BITS_PER_UNIT)))
12347 : 3 : ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
12348 : :
12349 : 537303 : if (ext_mode == BLKmode)
12350 : : {
12351 : 9 : if (target == 0)
12352 : 3 : target = assign_temp (type, 1, 1);
12353 : :
12354 : : /* ??? Unlike the similar test a few lines below, this one is
12355 : : very likely obsolete. */
12356 : 9 : if (known_eq (bitsize, 0))
12357 : : return target;
12358 : :
12359 : : /* In this case, BITPOS must start at a byte boundary and
12360 : : TARGET, if specified, must be a MEM. */
12361 : 9 : gcc_assert (MEM_P (op0)
12362 : : && (!target || MEM_P (target)));
12363 : :
12364 : 9 : bytepos = exact_div (bitpos, BITS_PER_UNIT);
12365 : 9 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
12366 : 18 : emit_block_move (target,
12367 : : adjust_address (op0, VOIDmode, bytepos),
12368 : 9 : gen_int_mode (bytesize, Pmode),
12369 : : (modifier == EXPAND_STACK_PARM
12370 : : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
12371 : :
12372 : 9 : return target;
12373 : : }
12374 : :
12375 : : /* If we have nothing to extract, the result will be 0 for targets
12376 : : with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise. Always
12377 : : return 0 for the sake of consistency, as reading a zero-sized
12378 : : bitfield is valid in Ada and the value is fully specified. */
12379 : 537294 : if (known_eq (bitsize, 0))
12380 : 0 : return const0_rtx;
12381 : :
12382 : 537294 : op0 = validize_mem (op0);
12383 : :
12384 : 537294 : if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
12385 : 70018 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12386 : :
12387 : : /* If the result has aggregate type and the extraction is done in
12388 : : an integral mode, then the field may be not aligned on a byte
12389 : : boundary; in this case, if it has reverse storage order, it
12390 : : needs to be extracted as a scalar field with reverse storage
12391 : : order and put back into memory order afterwards. */
12392 : 537294 : if (AGGREGATE_TYPE_P (type)
12393 : 1550 : && GET_MODE_CLASS (ext_mode) == MODE_INT)
12394 : 1471 : reversep = TYPE_REVERSE_STORAGE_ORDER (type);
12395 : :
12396 : 537294 : gcc_checking_assert (known_ge (bitpos, 0));
12397 : 549785 : op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
12398 : : (modifier == EXPAND_STACK_PARM
12399 : : ? NULL_RTX : target),
12400 : : ext_mode, ext_mode, reversep, alt_rtl);
12401 : :
12402 : : /* If the result has aggregate type and the mode of OP0 is an
12403 : : integral mode then, if BITSIZE is narrower than this mode
12404 : : and this is for big-endian data, we must put the field
12405 : : into the high-order bits. And we must also put it back
12406 : : into memory order if it has been previously reversed. */
12407 : 537294 : scalar_int_mode op0_mode;
12408 : 537294 : if (AGGREGATE_TYPE_P (type)
12409 : 537294 : && is_int_mode (GET_MODE (op0), &op0_mode))
12410 : : {
12411 : 1471 : HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
12412 : :
12413 : 1471 : gcc_checking_assert (known_le (bitsize, size));
12414 : 1471 : if (maybe_lt (bitsize, size)
12415 : 1471 : && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
12416 : 0 : op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
12417 : : size - bitsize, op0, 1);
12418 : :
12419 : 1471 : if (reversep)
12420 : 0 : op0 = flip_storage_order (op0_mode, op0);
12421 : : }
12422 : :
12423 : : /* If the result type is BLKmode, store the data into a temporary
12424 : : of the appropriate type, but with the mode corresponding to the
12425 : : mode for the data we have (op0's mode). */
12426 : 537294 : if (mode == BLKmode)
12427 : : {
12428 : 0 : rtx new_rtx
12429 : 0 : = assign_stack_temp_for_type (ext_mode,
12430 : 0 : GET_MODE_BITSIZE (ext_mode),
12431 : : type);
12432 : 0 : emit_move_insn (new_rtx, op0);
12433 : 0 : op0 = copy_rtx (new_rtx);
12434 : 0 : PUT_MODE (op0, BLKmode);
12435 : : }
12436 : :
12437 : 537294 : return op0;
12438 : : }
12439 : :
12440 : : /* If the result is BLKmode, use that to access the object
12441 : : now as well. */
12442 : 4090927 : if (mode == BLKmode)
12443 : 79003 : mode1 = BLKmode;
12444 : :
12445 : : /* Get a reference to just this component. */
12446 : 4090927 : bytepos = bits_to_bytes_round_down (bitpos);
12447 : 4090927 : if (modifier == EXPAND_CONST_ADDRESS
12448 : 4090927 : || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
12449 : 174953 : op0 = adjust_address_nv (op0, mode1, bytepos);
12450 : : else
12451 : 3915974 : op0 = adjust_address (op0, mode1, bytepos);
12452 : :
12453 : 4090927 : if (op0 == orig_op0)
12454 : 137550 : op0 = copy_rtx (op0);
12455 : :
12456 : : /* Don't set memory attributes if the base expression is
12457 : : SSA_NAME that got expanded as a MEM or a CONSTANT. In that case,
12458 : : we should just honor its original memory attributes. */
12459 : 4090927 : if (!(TREE_CODE (tem) == SSA_NAME
12460 : 8535 : && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
12461 : 4082392 : set_mem_attributes (op0, exp, 0);
12462 : :
12463 : 4090927 : if (REG_P (XEXP (op0, 0)))
12464 : 657364 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12465 : :
12466 : : /* If op0 is a temporary because the original expressions was forced
12467 : : to memory, clear MEM_EXPR so that the original expression cannot
12468 : : be marked as addressable through MEM_EXPR of the temporary. */
12469 : 4090927 : if (clear_mem_expr)
12470 : 1165 : set_mem_expr (op0, NULL_TREE);
12471 : :
12472 : 4090927 : MEM_VOLATILE_P (op0) |= volatilep;
12473 : :
12474 : 4090927 : if (reversep
12475 : : && modifier != EXPAND_MEMORY
12476 : 483 : && modifier != EXPAND_WRITE)
12477 : 483 : op0 = flip_storage_order (mode1, op0);
12478 : :
12479 : 4090927 : op0 = EXTEND_BITINT (op0);
12480 : :
12481 : 4090927 : if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
12482 : : || modifier == EXPAND_CONST_ADDRESS
12483 : 0 : || modifier == EXPAND_INITIALIZER)
12484 : : return op0;
12485 : :
12486 : 0 : if (target == 0)
12487 : 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
12488 : :
12489 : 0 : convert_move (target, op0, unsignedp);
12490 : 0 : return target;
12491 : : }
12492 : :
12493 : 68933 : case OBJ_TYPE_REF:
12494 : 68933 : return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
12495 : :
12496 : 6587643 : case CALL_EXPR:
12497 : : /* All valid uses of __builtin_va_arg_pack () are removed during
12498 : : inlining. */
12499 : 6587643 : if (CALL_EXPR_VA_ARG_PACK (exp))
12500 : 6 : error ("invalid use of %<__builtin_va_arg_pack ()%>");
12501 : 6587643 : {
12502 : 6587643 : tree fndecl = get_callee_fndecl (exp), attr;
12503 : :
12504 : 6587643 : if (fndecl
12505 : : /* Don't diagnose the error attribute in thunks, those are
12506 : : artificially created. */
12507 : 6398538 : && !CALL_FROM_THUNK_P (exp)
12508 : 12982284 : && (attr = lookup_attribute ("error",
12509 : 6394641 : DECL_ATTRIBUTES (fndecl))) != NULL)
12510 : : {
12511 : 5 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12512 : 10 : error ("call to %qs declared with attribute error: %s",
12513 : : identifier_to_locale (ident),
12514 : 5 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12515 : : }
12516 : 6587643 : if (fndecl
12517 : : /* Don't diagnose the warning attribute in thunks, those are
12518 : : artificially created. */
12519 : 6398538 : && !CALL_FROM_THUNK_P (exp)
12520 : 12982284 : && (attr = lookup_attribute ("warning",
12521 : 6394641 : DECL_ATTRIBUTES (fndecl))) != NULL)
12522 : : {
12523 : 17 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12524 : 34 : warning_at (EXPR_LOCATION (exp),
12525 : 17 : OPT_Wattribute_warning,
12526 : : "call to %qs declared with attribute warning: %s",
12527 : : identifier_to_locale (ident),
12528 : 17 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12529 : : }
12530 : :
12531 : : /* Check for a built-in function. */
12532 : 6587643 : if (fndecl && fndecl_built_in_p (fndecl))
12533 : : {
12534 : 1959672 : gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
12535 : 1959672 : return expand_builtin (exp, target, subtarget, tmode, ignore);
12536 : : }
12537 : : }
12538 : 4627971 : temp = expand_call (exp, target, ignore);
12539 : 4627971 : return EXTEND_BITINT (temp);
12540 : :
12541 : 336681 : case VIEW_CONVERT_EXPR:
12542 : 336681 : op0 = NULL_RTX;
12543 : :
12544 : : /* If we are converting to BLKmode, try to avoid an intermediate
12545 : : temporary by fetching an inner memory reference. */
12546 : 336681 : if (mode == BLKmode
12547 : 73712 : && poly_int_tree_p (TYPE_SIZE (type))
12548 : 73712 : && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
12549 : 336681 : && handled_component_p (treeop0))
12550 : : {
12551 : 0 : machine_mode mode1;
12552 : 0 : poly_int64 bitsize, bitpos, bytepos;
12553 : 0 : tree offset;
12554 : 0 : int reversep, volatilep = 0;
12555 : 0 : tree tem
12556 : 0 : = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
12557 : : &unsignedp, &reversep, &volatilep);
12558 : :
12559 : : /* ??? We should work harder and deal with non-zero offsets. */
12560 : 0 : if (!offset
12561 : 0 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12562 : 0 : && !reversep
12563 : 0 : && known_size_p (bitsize)
12564 : 0 : && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
12565 : : {
12566 : : /* See the normal_inner_ref case for the rationale. */
12567 : 0 : rtx orig_op0
12568 : 0 : = expand_expr_real (tem,
12569 : 0 : (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12570 : 0 : && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
12571 : : != INTEGER_CST)
12572 : 0 : && modifier != EXPAND_STACK_PARM
12573 : : ? target : NULL_RTX),
12574 : : VOIDmode,
12575 : : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
12576 : : NULL, true);
12577 : :
12578 : 0 : if (MEM_P (orig_op0))
12579 : : {
12580 : 0 : op0 = orig_op0;
12581 : :
12582 : : /* Get a reference to just this component. */
12583 : 0 : if (modifier == EXPAND_CONST_ADDRESS
12584 : : || modifier == EXPAND_SUM
12585 : 0 : || modifier == EXPAND_INITIALIZER)
12586 : 0 : op0 = adjust_address_nv (op0, mode, bytepos);
12587 : : else
12588 : 0 : op0 = adjust_address (op0, mode, bytepos);
12589 : :
12590 : 0 : if (op0 == orig_op0)
12591 : 0 : op0 = copy_rtx (op0);
12592 : :
12593 : 0 : set_mem_attributes (op0, treeop0, 0);
12594 : 0 : if (REG_P (XEXP (op0, 0)))
12595 : 0 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12596 : :
12597 : 0 : MEM_VOLATILE_P (op0) |= volatilep;
12598 : : }
12599 : : }
12600 : : }
12601 : :
12602 : 0 : if (!op0)
12603 : 336681 : op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
12604 : 336681 : NULL, inner_reference_p || mode == BLKmode);
12605 : :
12606 : : /* If the input and output modes are both the same, we are done. */
12607 : 336681 : if (mode == GET_MODE (op0))
12608 : : ;
12609 : : /* Similarly if the output mode is BLKmode and input is a MEM,
12610 : : adjust_address done below is all we need. */
12611 : 145244 : else if (mode == BLKmode && MEM_P (op0))
12612 : : ;
12613 : : /* If neither mode is BLKmode, and both modes are the same size
12614 : : then we can use gen_lowpart. */
12615 : : else if (mode != BLKmode
12616 : 145211 : && GET_MODE (op0) != BLKmode
12617 : 143892 : && known_eq (GET_MODE_PRECISION (mode),
12618 : : GET_MODE_PRECISION (GET_MODE (op0)))
12619 : 140000 : && !COMPLEX_MODE_P (GET_MODE (op0)))
12620 : : {
12621 : 138599 : if (GET_CODE (op0) == SUBREG)
12622 : 99 : op0 = force_reg (GET_MODE (op0), op0);
12623 : 138599 : temp = gen_lowpart_common (mode, op0);
12624 : 138599 : if (temp)
12625 : : op0 = temp;
12626 : : else
12627 : : {
12628 : 27439 : if (!REG_P (op0) && !MEM_P (op0))
12629 : 18 : op0 = force_reg (GET_MODE (op0), op0);
12630 : 27439 : op0 = gen_lowpart (mode, op0);
12631 : : }
12632 : : }
12633 : : /* If both types are integral, convert from one mode to the other. */
12634 : 6643 : else if (INTEGRAL_TYPE_P (type)
12635 : 3140 : && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
12636 : 0 : && mode != BLKmode
12637 : 6643 : && GET_MODE (op0) != BLKmode)
12638 : 0 : op0 = convert_modes (mode, GET_MODE (op0), op0,
12639 : 0 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
12640 : : /* If the output type is a bit-field type, do an extraction. */
12641 : 6643 : else if (reduce_bit_field
12642 : 1 : && mode != BLKmode
12643 : 1 : && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
12644 : 0 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12645 : 0 : TYPE_UNSIGNED (type), NULL_RTX,
12646 : : mode, mode, false, NULL);
12647 : : /* As a last resort, spill op0 to memory, and reload it in a
12648 : : different mode. */
12649 : 6643 : else if (!MEM_P (op0))
12650 : : {
12651 : : /* If the operand is not a MEM, force it into memory. Since we
12652 : : are going to be changing the mode of the MEM, don't call
12653 : : force_const_mem for constants because we don't allow pool
12654 : : constants to change mode. */
12655 : 5319 : tree inner_type = TREE_TYPE (treeop0);
12656 : :
12657 : 5319 : gcc_assert (!TREE_ADDRESSABLE (exp));
12658 : :
12659 : 5319 : if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
12660 : 5313 : target
12661 : : = assign_stack_temp_for_type
12662 : 5313 : (TYPE_MODE (inner_type),
12663 : 10626 : GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
12664 : :
12665 : 5319 : emit_move_insn (target, op0);
12666 : 5319 : op0 = target;
12667 : :
12668 : 5319 : if (reduce_bit_field && mode != BLKmode)
12669 : 1 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12670 : 1 : TYPE_UNSIGNED (type), NULL_RTX,
12671 : : mode, mode, false, NULL);
12672 : : }
12673 : :
12674 : : /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the
12675 : : output type is such that the operand is known to be aligned, indicate
12676 : : that it is. Otherwise, we need only be concerned about alignment for
12677 : : non-BLKmode results. */
12678 : 336680 : if (MEM_P (op0))
12679 : : {
12680 : 124623 : enum insn_code icode;
12681 : :
12682 : 124623 : if (modifier != EXPAND_WRITE
12683 : 124623 : && modifier != EXPAND_MEMORY
12684 : 124623 : && !inner_reference_p
12685 : 124623 : && mode != BLKmode
12686 : 175534 : && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
12687 : : {
12688 : : /* If the target does have special handling for unaligned
12689 : : loads of mode then use them. */
12690 : 14340 : if ((icode = optab_handler (movmisalign_optab, mode))
12691 : : != CODE_FOR_nothing)
12692 : : {
12693 : 1912 : rtx reg;
12694 : :
12695 : 1912 : op0 = adjust_address (op0, mode, 0);
12696 : : /* We've already validated the memory, and we're creating a
12697 : : new pseudo destination. The predicates really can't
12698 : : fail. */
12699 : 1912 : reg = gen_reg_rtx (mode);
12700 : :
12701 : : /* Nor can the insn generator. */
12702 : 1912 : rtx_insn *insn = GEN_FCN (icode) (reg, op0);
12703 : 1912 : emit_insn (insn);
12704 : 1912 : return reg;
12705 : : }
12706 : : else if (STRICT_ALIGNMENT)
12707 : : {
12708 : : poly_uint64 mode_size = GET_MODE_SIZE (mode);
12709 : : poly_uint64 temp_size = mode_size;
12710 : : if (GET_MODE (op0) != BLKmode)
12711 : : temp_size = upper_bound (temp_size,
12712 : : GET_MODE_SIZE (GET_MODE (op0)));
12713 : : rtx new_rtx
12714 : : = assign_stack_temp_for_type (mode, temp_size, type);
12715 : : rtx new_with_op0_mode
12716 : : = adjust_address (new_rtx, GET_MODE (op0), 0);
12717 : :
12718 : : gcc_assert (!TREE_ADDRESSABLE (exp));
12719 : :
12720 : : if (GET_MODE (op0) == BLKmode)
12721 : : {
12722 : : rtx size_rtx = gen_int_mode (mode_size, Pmode);
12723 : : emit_block_move (new_with_op0_mode, op0, size_rtx,
12724 : : (modifier == EXPAND_STACK_PARM
12725 : : ? BLOCK_OP_CALL_PARM
12726 : : : BLOCK_OP_NORMAL));
12727 : : }
12728 : : else
12729 : : emit_move_insn (new_with_op0_mode, op0);
12730 : :
12731 : : op0 = new_rtx;
12732 : : }
12733 : : }
12734 : :
12735 : 122711 : op0 = adjust_address (op0, mode, 0);
12736 : : }
12737 : :
12738 : : return op0;
12739 : :
12740 : 62377 : case MODIFY_EXPR:
12741 : 62377 : {
12742 : 62377 : tree lhs = treeop0;
12743 : 62377 : tree rhs = treeop1;
12744 : 62377 : gcc_assert (ignore);
12745 : :
12746 : : /* Check for |= or &= of a bitfield of size one into another bitfield
12747 : : of size 1. In this case, (unless we need the result of the
12748 : : assignment) we can do this more efficiently with a
12749 : : test followed by an assignment, if necessary.
12750 : :
12751 : : ??? At this point, we can't get a BIT_FIELD_REF here. But if
12752 : : things change so we do, this code should be enhanced to
12753 : : support it. */
12754 : 62377 : if (TREE_CODE (lhs) == COMPONENT_REF
12755 : 59724 : && (TREE_CODE (rhs) == BIT_IOR_EXPR
12756 : 59724 : || TREE_CODE (rhs) == BIT_AND_EXPR)
12757 : 0 : && TREE_OPERAND (rhs, 0) == lhs
12758 : 0 : && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
12759 : 0 : && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
12760 : 62377 : && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
12761 : : {
12762 : 0 : rtx_code_label *label = gen_label_rtx ();
12763 : 0 : int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
12764 : 0 : profile_probability prob = profile_probability::uninitialized ();
12765 : 0 : if (value)
12766 : 0 : jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
12767 : : else
12768 : 0 : jumpif (TREE_OPERAND (rhs, 1), label, prob);
12769 : 0 : expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value),
12770 : : false);
12771 : 0 : do_pending_stack_adjust ();
12772 : 0 : emit_label (label);
12773 : 0 : return const0_rtx;
12774 : : }
12775 : :
12776 : 62377 : expand_assignment (lhs, rhs, false);
12777 : 62377 : return const0_rtx;
12778 : : }
12779 : :
12780 : 12931795 : case ADDR_EXPR:
12781 : 12931795 : return expand_expr_addr_expr (exp, target, tmode, modifier);
12782 : :
12783 : 154153 : case REALPART_EXPR:
12784 : 154153 : op0 = expand_normal (treeop0);
12785 : 154153 : return read_complex_part (op0, false);
12786 : :
12787 : 178167 : case IMAGPART_EXPR:
12788 : 178167 : op0 = expand_normal (treeop0);
12789 : 178167 : return read_complex_part (op0, true);
12790 : :
12791 : 0 : case RETURN_EXPR:
12792 : 0 : case LABEL_EXPR:
12793 : 0 : case GOTO_EXPR:
12794 : 0 : case SWITCH_EXPR:
12795 : 0 : case ASM_EXPR:
12796 : : /* Expanded in cfgexpand.cc. */
12797 : 0 : gcc_unreachable ();
12798 : :
12799 : 0 : case TRY_CATCH_EXPR:
12800 : 0 : case CATCH_EXPR:
12801 : 0 : case EH_FILTER_EXPR:
12802 : 0 : case TRY_FINALLY_EXPR:
12803 : 0 : case EH_ELSE_EXPR:
12804 : : /* Lowered by tree-eh.cc. */
12805 : 0 : gcc_unreachable ();
12806 : :
12807 : 0 : case WITH_CLEANUP_EXPR:
12808 : 0 : case CLEANUP_POINT_EXPR:
12809 : 0 : case TARGET_EXPR:
12810 : 0 : case CASE_LABEL_EXPR:
12811 : 0 : case VA_ARG_EXPR:
12812 : 0 : case BIND_EXPR:
12813 : 0 : case INIT_EXPR:
12814 : 0 : case CONJ_EXPR:
12815 : 0 : case COMPOUND_EXPR:
12816 : 0 : case PREINCREMENT_EXPR:
12817 : 0 : case PREDECREMENT_EXPR:
12818 : 0 : case POSTINCREMENT_EXPR:
12819 : 0 : case POSTDECREMENT_EXPR:
12820 : 0 : case LOOP_EXPR:
12821 : 0 : case EXIT_EXPR:
12822 : 0 : case COMPOUND_LITERAL_EXPR:
12823 : : /* Lowered by gimplify.cc. */
12824 : 0 : gcc_unreachable ();
12825 : :
12826 : 0 : case FDESC_EXPR:
12827 : : /* Function descriptors are not valid except for as
12828 : : initialization constants, and should not be expanded. */
12829 : 0 : gcc_unreachable ();
12830 : :
12831 : 256 : case WITH_SIZE_EXPR:
12832 : : /* WITH_SIZE_EXPR expands to its first argument. The caller should
12833 : : have pulled out the size to use in whatever context it needed. */
12834 : 256 : return expand_expr_real (treeop0, original_target, tmode,
12835 : 256 : modifier, alt_rtl, inner_reference_p);
12836 : :
12837 : 1806487 : default:
12838 : 1806487 : return expand_expr_real_2 (&ops, target, tmode, modifier);
12839 : : }
12840 : : }
12841 : : #undef EXTEND_BITINT
12842 : :
12843 : : /* Subroutine of above: reduce EXP to the precision of TYPE (in the
12844 : : signedness of TYPE), possibly returning the result in TARGET.
12845 : : TYPE is known to be a partial integer type. */
12846 : : static rtx
12847 : 85895 : reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
12848 : : {
12849 : 85895 : scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
12850 : 85895 : HOST_WIDE_INT prec = TYPE_PRECISION (type);
12851 : 85895 : gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
12852 : : && (!target || GET_MODE (target) == mode));
12853 : :
12854 : : /* For constant values, reduce using wide_int_to_tree. */
12855 : 85895 : if (poly_int_rtx_p (exp))
12856 : : {
12857 : 2 : auto value = wi::to_poly_wide (exp, mode);
12858 : 2 : tree t = wide_int_to_tree (type, value);
12859 : 2 : return expand_expr (t, target, VOIDmode, EXPAND_NORMAL);
12860 : : }
12861 : 85893 : else if (TYPE_UNSIGNED (type))
12862 : : {
12863 : 67800 : rtx mask = immed_wide_int_const
12864 : 67800 : (wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
12865 : 67800 : return expand_and (mode, exp, mask, target);
12866 : : }
12867 : : else
12868 : : {
12869 : 18093 : int count = GET_MODE_PRECISION (mode) - prec;
12870 : 18093 : exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
12871 : 18093 : return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
12872 : : }
12873 : : }
12874 : :
12875 : : /* Subroutine of above: returns true if OFFSET corresponds to an offset that
12876 : : when applied to the address of EXP produces an address known to be
12877 : : aligned more than BIGGEST_ALIGNMENT. */
12878 : :
12879 : : static bool
12880 : 277440 : is_aligning_offset (const_tree offset, const_tree exp)
12881 : : {
12882 : : /* Strip off any conversions. */
12883 : 300392 : while (CONVERT_EXPR_P (offset))
12884 : 22952 : offset = TREE_OPERAND (offset, 0);
12885 : :
12886 : : /* We must now have a BIT_AND_EXPR with a constant that is one less than
12887 : : power of 2 and which is larger than BIGGEST_ALIGNMENT. */
12888 : 277440 : if (TREE_CODE (offset) != BIT_AND_EXPR
12889 : 0 : || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
12890 : 0 : || compare_tree_int (TREE_OPERAND (offset, 1),
12891 : 0 : BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
12892 : 277440 : || !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
12893 : 277440 : return false;
12894 : :
12895 : : /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
12896 : : It must be NEGATE_EXPR. Then strip any more conversions. */
12897 : 0 : offset = TREE_OPERAND (offset, 0);
12898 : 0 : while (CONVERT_EXPR_P (offset))
12899 : 0 : offset = TREE_OPERAND (offset, 0);
12900 : :
12901 : 0 : if (TREE_CODE (offset) != NEGATE_EXPR)
12902 : : return false;
12903 : :
12904 : 0 : offset = TREE_OPERAND (offset, 0);
12905 : 0 : while (CONVERT_EXPR_P (offset))
12906 : 0 : offset = TREE_OPERAND (offset, 0);
12907 : :
12908 : : /* This must now be the address of EXP. */
12909 : 0 : return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
12910 : : }
12911 : :
12912 : : /* Return a STRING_CST corresponding to ARG's constant initializer either
12913 : : if it's a string constant, or, when VALREP is set, any other constant,
12914 : : or null otherwise.
12915 : : On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
12916 : : within the byte string that ARG is references. If nonnull set *MEM_SIZE
12917 : : to the size of the byte string. If nonnull, set *DECL to the constant
12918 : : declaration ARG refers to. */
12919 : :
12920 : : static tree
12921 : 15722644 : constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
12922 : : bool valrep = false)
12923 : : {
12924 : 15722644 : tree dummy = NULL_TREE;
12925 : 15722644 : if (!mem_size)
12926 : 10423 : mem_size = &dummy;
12927 : :
12928 : : /* Store the type of the original expression before conversions
12929 : : via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
12930 : : removed. */
12931 : 15722644 : tree argtype = TREE_TYPE (arg);
12932 : :
12933 : 15722644 : tree array;
12934 : 15722644 : STRIP_NOPS (arg);
12935 : :
12936 : : /* Non-constant index into the character array in an ARRAY_REF
12937 : : expression or null. */
12938 : 15722644 : tree varidx = NULL_TREE;
12939 : :
12940 : 15722644 : poly_int64 base_off = 0;
12941 : :
12942 : 15722644 : if (TREE_CODE (arg) == ADDR_EXPR)
12943 : : {
12944 : 6551886 : arg = TREE_OPERAND (arg, 0);
12945 : 6551886 : tree ref = arg;
12946 : 6551886 : if (TREE_CODE (arg) == ARRAY_REF)
12947 : : {
12948 : 563775 : tree idx = TREE_OPERAND (arg, 1);
12949 : 563775 : if (TREE_CODE (idx) != INTEGER_CST)
12950 : : {
12951 : : /* From a pointer (but not array) argument extract the variable
12952 : : index to prevent get_addr_base_and_unit_offset() from failing
12953 : : due to it. Use it later to compute the non-constant offset
12954 : : into the string and return it to the caller. */
12955 : 168032 : varidx = idx;
12956 : 168032 : ref = TREE_OPERAND (arg, 0);
12957 : :
12958 : 168032 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
12959 : : return NULL_TREE;
12960 : :
12961 : 27959 : if (!integer_zerop (array_ref_low_bound (arg)))
12962 : : return NULL_TREE;
12963 : :
12964 : 27203 : if (!integer_onep (array_ref_element_size (arg)))
12965 : : return NULL_TREE;
12966 : : }
12967 : : }
12968 : 6409985 : array = get_addr_base_and_unit_offset (ref, &base_off);
12969 : 6409985 : if (!array
12970 : 6363274 : || (TREE_CODE (array) != VAR_DECL
12971 : 6363274 : && TREE_CODE (array) != CONST_DECL
12972 : 3892028 : && TREE_CODE (array) != STRING_CST))
12973 : : return NULL_TREE;
12974 : : }
12975 : 9170758 : else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
12976 : : {
12977 : 26398 : tree arg0 = TREE_OPERAND (arg, 0);
12978 : 26398 : tree arg1 = TREE_OPERAND (arg, 1);
12979 : :
12980 : 26398 : tree offset;
12981 : 26398 : tree str = string_constant (arg0, &offset, mem_size, decl);
12982 : 26398 : if (!str)
12983 : : {
12984 : 17141 : str = string_constant (arg1, &offset, mem_size, decl);
12985 : 17141 : arg1 = arg0;
12986 : : }
12987 : :
12988 : 17141 : if (str)
12989 : : {
12990 : : /* Avoid pointers to arrays (see bug 86622). */
12991 : 9257 : if (POINTER_TYPE_P (TREE_TYPE (arg))
12992 : 9257 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
12993 : 2100 : && !(decl && !*decl)
12994 : 12057 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
12995 : 1400 : && tree_fits_uhwi_p (*mem_size)
12996 : 1400 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
12997 : 2100 : return NULL_TREE;
12998 : :
12999 : 7157 : tree type = TREE_TYPE (offset);
13000 : 7157 : arg1 = fold_convert (type, arg1);
13001 : 7157 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
13002 : 7157 : return str;
13003 : : }
13004 : : return NULL_TREE;
13005 : : }
13006 : 9144360 : else if (TREE_CODE (arg) == SSA_NAME)
13007 : : {
13008 : 3945263 : gimple *stmt = SSA_NAME_DEF_STMT (arg);
13009 : 3945263 : if (!is_gimple_assign (stmt))
13010 : : return NULL_TREE;
13011 : :
13012 : 1022972 : tree rhs1 = gimple_assign_rhs1 (stmt);
13013 : 1022972 : tree_code code = gimple_assign_rhs_code (stmt);
13014 : 1022972 : if (code == ADDR_EXPR)
13015 : 224824 : return string_constant (rhs1, ptr_offset, mem_size, decl);
13016 : 798148 : else if (code != POINTER_PLUS_EXPR)
13017 : : return NULL_TREE;
13018 : :
13019 : 197559 : tree offset;
13020 : 197559 : if (tree str = string_constant (rhs1, &offset, mem_size, decl))
13021 : : {
13022 : : /* Avoid pointers to arrays (see bug 86622). */
13023 : 29816 : if (POINTER_TYPE_P (TREE_TYPE (rhs1))
13024 : 29816 : && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
13025 : 27035 : && !(decl && !*decl)
13026 : 46022 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
13027 : 8103 : && tree_fits_uhwi_p (*mem_size)
13028 : 8103 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
13029 : 19618 : return NULL_TREE;
13030 : :
13031 : 10198 : tree rhs2 = gimple_assign_rhs2 (stmt);
13032 : 10198 : tree type = TREE_TYPE (offset);
13033 : 10198 : rhs2 = fold_convert (type, rhs2);
13034 : 10198 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
13035 : 10198 : return str;
13036 : : }
13037 : : return NULL_TREE;
13038 : : }
13039 : 5199097 : else if (DECL_P (arg))
13040 : : array = arg;
13041 : : else
13042 : : return NULL_TREE;
13043 : :
13044 : 8750126 : tree offset = wide_int_to_tree (sizetype, base_off);
13045 : 8750126 : if (varidx)
13046 : : {
13047 : 2146 : if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
13048 : : return NULL_TREE;
13049 : :
13050 : 1635 : gcc_assert (TREE_CODE (arg) == ARRAY_REF);
13051 : 1635 : tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
13052 : 1635 : if (TREE_CODE (chartype) != INTEGER_TYPE)
13053 : : return NULL;
13054 : :
13055 : 1478 : offset = fold_convert (sizetype, varidx);
13056 : : }
13057 : :
13058 : 8749458 : if (TREE_CODE (array) == STRING_CST)
13059 : : {
13060 : 3515901 : *ptr_offset = fold_convert (sizetype, offset);
13061 : 3515901 : *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
13062 : 3515901 : if (decl)
13063 : 774395 : *decl = NULL_TREE;
13064 : 3515901 : gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
13065 : : >= TREE_STRING_LENGTH (array));
13066 : : return array;
13067 : : }
13068 : :
13069 : 5233557 : tree init = ctor_for_folding (array);
13070 : 5233557 : if (!init || init == error_mark_node)
13071 : : return NULL_TREE;
13072 : :
13073 : 156637 : if (valrep)
13074 : : {
13075 : 59070 : HOST_WIDE_INT cstoff;
13076 : 59070 : if (!base_off.is_constant (&cstoff))
13077 : : return NULL_TREE;
13078 : :
13079 : : /* Check that the host and target are sane. */
13080 : 59070 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13081 : : return NULL_TREE;
13082 : :
13083 : 59070 : HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
13084 : 59070 : if (typesz <= 0 || (int) typesz != typesz)
13085 : : return NULL_TREE;
13086 : :
13087 : 58900 : HOST_WIDE_INT size = typesz;
13088 : 58900 : if (VAR_P (array)
13089 : 58888 : && DECL_SIZE_UNIT (array)
13090 : 117788 : && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
13091 : : {
13092 : 58888 : size = tree_to_shwi (DECL_SIZE_UNIT (array));
13093 : 58888 : gcc_checking_assert (size >= typesz);
13094 : : }
13095 : :
13096 : : /* If value representation was requested convert the initializer
13097 : : for the whole array or object into a string of bytes forming
13098 : : its value representation and return it. */
13099 : 58900 : unsigned char *bytes = XNEWVEC (unsigned char, size);
13100 : 58900 : int r = native_encode_initializer (init, bytes, size);
13101 : 58900 : if (r < typesz)
13102 : : {
13103 : 56 : XDELETEVEC (bytes);
13104 : 56 : return NULL_TREE;
13105 : : }
13106 : :
13107 : 58844 : if (r < size)
13108 : 0 : memset (bytes + r, '\0', size - r);
13109 : :
13110 : 58844 : const char *p = reinterpret_cast<const char *>(bytes);
13111 : 58844 : init = build_string_literal (size, p, char_type_node);
13112 : 58844 : init = TREE_OPERAND (init, 0);
13113 : 58844 : init = TREE_OPERAND (init, 0);
13114 : 58844 : XDELETE (bytes);
13115 : :
13116 : 58844 : *mem_size = size_int (TREE_STRING_LENGTH (init));
13117 : 58844 : *ptr_offset = wide_int_to_tree (ssizetype, base_off);
13118 : :
13119 : 58844 : if (decl)
13120 : 0 : *decl = array;
13121 : :
13122 : 58844 : return init;
13123 : : }
13124 : :
13125 : 97567 : if (TREE_CODE (init) == CONSTRUCTOR)
13126 : : {
13127 : : /* Convert the 64-bit constant offset to a wider type to avoid
13128 : : overflow and use it to obtain the initializer for the subobject
13129 : : it points into. */
13130 : 79413 : offset_int wioff;
13131 : 79413 : if (!base_off.is_constant (&wioff))
13132 : 158 : return NULL_TREE;
13133 : :
13134 : 79413 : wioff *= BITS_PER_UNIT;
13135 : 79413 : if (!wi::fits_uhwi_p (wioff))
13136 : : return NULL_TREE;
13137 : :
13138 : 79305 : base_off = wioff.to_uhwi ();
13139 : 79305 : unsigned HOST_WIDE_INT fieldoff = 0;
13140 : 79305 : init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
13141 : : &fieldoff);
13142 : 79305 : if (!init || init == error_mark_node)
13143 : : return NULL_TREE;
13144 : :
13145 : 79255 : HOST_WIDE_INT cstoff;
13146 : 79255 : if (!base_off.is_constant (&cstoff))
13147 : : return NULL_TREE;
13148 : :
13149 : 79255 : cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
13150 : 79255 : tree off = build_int_cst (sizetype, cstoff);
13151 : 79255 : if (varidx)
13152 : 944 : offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
13153 : : else
13154 : : offset = off;
13155 : : }
13156 : :
13157 : 97409 : *ptr_offset = offset;
13158 : :
13159 : 97409 : tree inittype = TREE_TYPE (init);
13160 : :
13161 : 97409 : if (TREE_CODE (init) == INTEGER_CST
13162 : 97409 : && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
13163 : 1277 : || TYPE_MAIN_VARIANT (inittype) == char_type_node))
13164 : : {
13165 : : /* Check that the host and target are sane. */
13166 : 899 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13167 : : return NULL_TREE;
13168 : :
13169 : : /* For a reference to (address of) a single constant character,
13170 : : store the native representation of the character in CHARBUF.
13171 : : If the reference is to an element of an array or a member
13172 : : of a struct, only consider narrow characters until ctors
13173 : : for wide character arrays are transformed to STRING_CSTs
13174 : : like those for narrow arrays. */
13175 : 899 : unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
13176 : 899 : int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
13177 : 899 : if (len > 0)
13178 : : {
13179 : : /* Construct a string literal with elements of INITTYPE and
13180 : : the representation above. Then strip
13181 : : the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
13182 : 899 : init = build_string_literal (len, (char *)charbuf, inittype);
13183 : 899 : init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
13184 : : }
13185 : : }
13186 : :
13187 : 97409 : tree initsize = TYPE_SIZE_UNIT (inittype);
13188 : :
13189 : 97409 : if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
13190 : : {
13191 : : /* Fold an empty/zero constructor for an implicitly initialized
13192 : : object or subobject into the empty string. */
13193 : :
13194 : : /* Determine the character type from that of the original
13195 : : expression. */
13196 : 9546 : tree chartype = argtype;
13197 : 9546 : if (POINTER_TYPE_P (chartype))
13198 : 9539 : chartype = TREE_TYPE (chartype);
13199 : 15388 : while (TREE_CODE (chartype) == ARRAY_TYPE)
13200 : 5842 : chartype = TREE_TYPE (chartype);
13201 : :
13202 : 9546 : if (INTEGRAL_TYPE_P (chartype)
13203 : 9546 : && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
13204 : : {
13205 : : /* Convert a char array to an empty STRING_CST having an array
13206 : : of the expected type and size. */
13207 : 9145 : if (!initsize)
13208 : 3090 : initsize = integer_zero_node;
13209 : :
13210 : 9145 : unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
13211 : 9145 : if (size > (unsigned HOST_WIDE_INT) INT_MAX)
13212 : : return NULL_TREE;
13213 : :
13214 : 9145 : init = build_string_literal (size, NULL, chartype, size);
13215 : 9145 : init = TREE_OPERAND (init, 0);
13216 : 9145 : init = TREE_OPERAND (init, 0);
13217 : :
13218 : 9145 : *ptr_offset = integer_zero_node;
13219 : : }
13220 : : }
13221 : :
13222 : 97409 : if (decl)
13223 : 55509 : *decl = array;
13224 : :
13225 : 97409 : if (TREE_CODE (init) != STRING_CST)
13226 : : return NULL_TREE;
13227 : :
13228 : 67398 : *mem_size = initsize;
13229 : :
13230 : 67398 : gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
13231 : :
13232 : : return init;
13233 : : }
13234 : :
13235 : : /* Return STRING_CST if an ARG corresponds to a string constant or zero
13236 : : if it doesn't. If we return nonzero, set *PTR_OFFSET to the (possibly
13237 : : non-constant) offset in bytes within the string that ARG is accessing.
13238 : : If MEM_SIZE is non-zero the storage size of the memory is returned.
13239 : : If DECL is non-zero the constant declaration is returned if available. */
13240 : :
13241 : : tree
13242 : 10865682 : string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13243 : : {
13244 : 10865682 : return constant_byte_string (arg, ptr_offset, mem_size, decl, false);
13245 : : }
13246 : :
13247 : : /* Similar to string_constant, return a STRING_CST corresponding
13248 : : to the value representation of the first argument if it's
13249 : : a constant. */
13250 : :
13251 : : tree
13252 : 4856962 : byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13253 : : {
13254 : 4856962 : return constant_byte_string (arg, ptr_offset, mem_size, decl, true);
13255 : : }
13256 : :
13257 : : /* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
13258 : : is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
13259 : : for C2 > 0 to x & C3 == C2
13260 : : for C2 < 0 to x & C3 == (C2 & C3). */
13261 : : enum tree_code
13262 : 35 : maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13263 : : {
13264 : 35 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13265 : 35 : tree treeop0 = gimple_assign_rhs1 (stmt);
13266 : 35 : tree treeop1 = gimple_assign_rhs2 (stmt);
13267 : 35 : tree type = TREE_TYPE (*arg0);
13268 : 35 : scalar_int_mode mode;
13269 : 35 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13270 : : return code;
13271 : 70 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13272 : 35 : || TYPE_PRECISION (type) <= 1
13273 : 35 : || TYPE_UNSIGNED (type)
13274 : : /* Signed x % c == 0 should have been optimized into unsigned modulo
13275 : : earlier. */
13276 : 35 : || integer_zerop (*arg1)
13277 : : /* If c is known to be non-negative, modulo will be expanded as unsigned
13278 : : modulo. */
13279 : 70 : || get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1)
13280 : 0 : return code;
13281 : :
13282 : : /* x % c == d where d < 0 && d <= -c should be always false. */
13283 : 35 : if (tree_int_cst_sgn (*arg1) == -1
13284 : 51 : && -wi::to_widest (treeop1) >= wi::to_widest (*arg1))
13285 : : return code;
13286 : :
13287 : 35 : int prec = TYPE_PRECISION (type);
13288 : 35 : wide_int w = wi::to_wide (treeop1) - 1;
13289 : 35 : w |= wi::shifted_mask (0, prec - 1, true, prec);
13290 : 35 : tree c3 = wide_int_to_tree (type, w);
13291 : 35 : tree c4 = *arg1;
13292 : 35 : if (tree_int_cst_sgn (*arg1) == -1)
13293 : 16 : c4 = wide_int_to_tree (type, w & wi::to_wide (*arg1));
13294 : :
13295 : 35 : rtx op0 = expand_normal (treeop0);
13296 : 35 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13297 : :
13298 : 35 : bool speed_p = optimize_insn_for_speed_p ();
13299 : :
13300 : 35 : do_pending_stack_adjust ();
13301 : :
13302 : 35 : location_t loc = gimple_location (stmt);
13303 : 35 : struct separate_ops ops;
13304 : 35 : ops.code = TRUNC_MOD_EXPR;
13305 : 35 : ops.location = loc;
13306 : 35 : ops.type = TREE_TYPE (treeop0);
13307 : 35 : ops.op0 = treeop0;
13308 : 35 : ops.op1 = treeop1;
13309 : 35 : ops.op2 = NULL_TREE;
13310 : 35 : start_sequence ();
13311 : 35 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13312 : : EXPAND_NORMAL);
13313 : 35 : rtx_insn *moinsns = end_sequence ();
13314 : :
13315 : 35 : unsigned mocost = seq_cost (moinsns, speed_p);
13316 : 35 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13317 : 35 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13318 : :
13319 : 35 : ops.code = BIT_AND_EXPR;
13320 : 35 : ops.location = loc;
13321 : 35 : ops.type = TREE_TYPE (treeop0);
13322 : 35 : ops.op0 = treeop0;
13323 : 35 : ops.op1 = c3;
13324 : 35 : ops.op2 = NULL_TREE;
13325 : 35 : start_sequence ();
13326 : 35 : rtx mur = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13327 : : EXPAND_NORMAL);
13328 : 35 : rtx_insn *muinsns = end_sequence ();
13329 : :
13330 : 35 : unsigned mucost = seq_cost (muinsns, speed_p);
13331 : 35 : mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
13332 : 35 : mucost += rtx_cost (expand_normal (c4), mode, EQ, 1, speed_p);
13333 : :
13334 : 35 : if (mocost <= mucost)
13335 : : {
13336 : 0 : emit_insn (moinsns);
13337 : 0 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13338 : 0 : return code;
13339 : : }
13340 : :
13341 : 35 : emit_insn (muinsns);
13342 : 35 : *arg0 = make_tree (TREE_TYPE (*arg0), mur);
13343 : 35 : *arg1 = c4;
13344 : 35 : return code;
13345 : 35 : }
13346 : :
13347 : : /* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
13348 : : If C1 is odd to:
13349 : : (X - C2) * C3 <= C4 (or >), where
13350 : : C3 is modular multiplicative inverse of C1 and 1<<prec and
13351 : : C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
13352 : : if C2 > ((1<<prec) - 1) % C1).
13353 : : If C1 is even, S = ctz (C1) and C2 is 0, use
13354 : : ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
13355 : : inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
13356 : :
13357 : : For signed (X % C1) == 0 if C1 is odd to (all operations in it
13358 : : unsigned):
13359 : : (X * C3) + C4 <= 2 * C4, where
13360 : : C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
13361 : : C4 is ((1<<(prec - 1) - 1) / C1).
13362 : : If C1 is even, S = ctz(C1), use
13363 : : ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
13364 : : where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
13365 : : and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
13366 : :
13367 : : See the Hacker's Delight book, section 10-17. */
13368 : : enum tree_code
13369 : 3274049 : maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13370 : : {
13371 : 3274049 : gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
13372 : 3274049 : gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
13373 : :
13374 : 3274049 : if (optimize < 2)
13375 : : return code;
13376 : :
13377 : 2481896 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13378 : 2481896 : if (stmt == NULL)
13379 : : return code;
13380 : :
13381 : 2500 : tree treeop0 = gimple_assign_rhs1 (stmt);
13382 : 2500 : tree treeop1 = gimple_assign_rhs2 (stmt);
13383 : 2500 : if (TREE_CODE (treeop0) != SSA_NAME
13384 : 2411 : || TREE_CODE (treeop1) != INTEGER_CST
13385 : : /* Don't optimize the undefined behavior case x % 0;
13386 : : x % 1 should have been optimized into zero, punt if
13387 : : it makes it here for whatever reason;
13388 : : x % -c should have been optimized into x % c. */
13389 : 2056 : || compare_tree_int (treeop1, 2) <= 0
13390 : : /* Likewise x % c == d where d >= c should be always false. */
13391 : 4475 : || tree_int_cst_le (treeop1, *arg1))
13392 : 525 : return code;
13393 : :
13394 : : /* Unsigned x % pow2 is handled right already, for signed
13395 : : modulo handle it in maybe_optimize_pow2p_mod_cmp. */
13396 : 1975 : if (integer_pow2p (treeop1))
13397 : 35 : return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
13398 : :
13399 : 1940 : tree type = TREE_TYPE (*arg0);
13400 : 1940 : scalar_int_mode mode;
13401 : 3274021 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13402 : : return code;
13403 : 3880 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13404 : 1940 : || TYPE_PRECISION (type) <= 1)
13405 : : return code;
13406 : :
13407 : 1940 : signop sgn = UNSIGNED;
13408 : : /* If both operands are known to have the sign bit clear, handle
13409 : : even the signed modulo case as unsigned. treeop1 is always
13410 : : positive >= 2, checked above. */
13411 : 1940 : if (!TYPE_UNSIGNED (type)
13412 : 1940 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) != 1)
13413 : : sgn = SIGNED;
13414 : :
13415 : 1940 : if (!TYPE_UNSIGNED (type))
13416 : : {
13417 : 1715 : if (tree_int_cst_sgn (*arg1) == -1)
13418 : : return code;
13419 : 1708 : type = unsigned_type_for (type);
13420 : 1708 : if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
13421 : 0 : return code;
13422 : : }
13423 : :
13424 : 1933 : int prec = TYPE_PRECISION (type);
13425 : 1933 : wide_int w = wi::to_wide (treeop1);
13426 : 1933 : int shift = wi::ctz (w);
13427 : : /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
13428 : : C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
13429 : : If C1 is odd, we can handle all cases by subtracting
13430 : : C4 below. We could handle even the even C1 and C2 > -1U % C1 cases
13431 : : e.g. by testing for overflow on the subtraction, punt on that for now
13432 : : though. */
13433 : 1933 : if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
13434 : : {
13435 : 183 : if (sgn == SIGNED)
13436 : 168 : return code;
13437 : 26 : wide_int x = wi::umod_trunc (wi::mask (prec, false, prec), w);
13438 : 26 : if (wi::gtu_p (wi::to_wide (*arg1), x))
13439 : 11 : return code;
13440 : 26 : }
13441 : :
13442 : 1765 : imm_use_iterator imm_iter;
13443 : 1765 : use_operand_p use_p;
13444 : 12994 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
13445 : : {
13446 : 11230 : gimple *use_stmt = USE_STMT (use_p);
13447 : : /* Punt if treeop0 is used in the same bb in a division
13448 : : or another modulo with the same divisor. We should expect
13449 : : the division and modulo combined together. */
13450 : 22140 : if (use_stmt == stmt
13451 : 11230 : || gimple_bb (use_stmt) != gimple_bb (stmt))
13452 : 10910 : continue;
13453 : 320 : if (!is_gimple_assign (use_stmt)
13454 : 320 : || (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR
13455 : 313 : && gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR))
13456 : 310 : continue;
13457 : 10 : if (gimple_assign_rhs1 (use_stmt) != treeop0
13458 : 10 : || !operand_equal_p (gimple_assign_rhs2 (use_stmt), treeop1, 0))
13459 : 9 : continue;
13460 : : return code;
13461 : : }
13462 : :
13463 : 1764 : w = wi::lrshift (w, shift);
13464 : 1764 : wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
13465 : 1764 : wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
13466 : 1764 : wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
13467 : 1764 : tree c3 = wide_int_to_tree (type, m);
13468 : 1764 : tree c5 = NULL_TREE;
13469 : 1764 : wide_int d, e;
13470 : 1764 : if (sgn == UNSIGNED)
13471 : : {
13472 : 962 : d = wi::divmod_trunc (wi::mask (prec, false, prec), w, UNSIGNED, &e);
13473 : : /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
13474 : : otherwise use < or subtract one from C4. E.g. for
13475 : : x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
13476 : : x % 3U == 1 already needs to be
13477 : : (x - 1) * 0xaaaaaaabU <= 0x55555554. */
13478 : 962 : if (!shift && wi::gtu_p (wi::to_wide (*arg1), e))
13479 : 19 : d -= 1;
13480 : 962 : if (shift)
13481 : 444 : d = wi::lrshift (d, shift);
13482 : : }
13483 : : else
13484 : : {
13485 : 802 : e = wi::udiv_trunc (wi::mask (prec - 1, false, prec), w);
13486 : 802 : if (!shift)
13487 : 605 : d = wi::lshift (e, 1);
13488 : : else
13489 : : {
13490 : 197 : e = wi::bit_and (e, wi::mask (shift, true, prec));
13491 : 197 : d = wi::lrshift (e, shift - 1);
13492 : : }
13493 : 802 : c5 = wide_int_to_tree (type, e);
13494 : : }
13495 : 1764 : tree c4 = wide_int_to_tree (type, d);
13496 : :
13497 : 1764 : rtx op0 = expand_normal (treeop0);
13498 : 1764 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13499 : :
13500 : 1764 : bool speed_p = optimize_insn_for_speed_p ();
13501 : :
13502 : 1764 : do_pending_stack_adjust ();
13503 : :
13504 : 1764 : location_t loc = gimple_location (stmt);
13505 : 1764 : struct separate_ops ops;
13506 : 1764 : ops.code = TRUNC_MOD_EXPR;
13507 : 1764 : ops.location = loc;
13508 : 1764 : ops.type = TREE_TYPE (treeop0);
13509 : 1764 : ops.op0 = treeop0;
13510 : 1764 : ops.op1 = treeop1;
13511 : 1764 : ops.op2 = NULL_TREE;
13512 : 1764 : start_sequence ();
13513 : 1764 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13514 : : EXPAND_NORMAL);
13515 : 1764 : rtx_insn *moinsns = end_sequence ();
13516 : :
13517 : 1764 : unsigned mocost = seq_cost (moinsns, speed_p);
13518 : 1764 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13519 : 1764 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13520 : :
13521 : 1764 : tree t = fold_convert_loc (loc, type, treeop0);
13522 : 1764 : if (!integer_zerop (*arg1))
13523 : 44 : t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
13524 : 1764 : t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
13525 : 1764 : if (sgn == SIGNED)
13526 : 802 : t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
13527 : 1764 : if (shift)
13528 : : {
13529 : 641 : tree s = build_int_cst (NULL_TREE, shift);
13530 : 641 : t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
13531 : : }
13532 : :
13533 : 1764 : start_sequence ();
13534 : 1764 : rtx mur = expand_normal (t);
13535 : 1764 : rtx_insn *muinsns = end_sequence ();
13536 : :
13537 : 1764 : unsigned mucost = seq_cost (muinsns, speed_p);
13538 : 1764 : mucost += rtx_cost (mur, mode, LE, 0, speed_p);
13539 : 1764 : mucost += rtx_cost (expand_normal (c4), mode, LE, 1, speed_p);
13540 : :
13541 : 1764 : if (mocost <= mucost)
13542 : : {
13543 : 312 : emit_insn (moinsns);
13544 : 312 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13545 : 312 : return code;
13546 : : }
13547 : :
13548 : 1452 : emit_insn (muinsns);
13549 : 1452 : *arg0 = make_tree (type, mur);
13550 : 1452 : *arg1 = c4;
13551 : 1452 : return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
13552 : 3697 : }
13553 : :
13554 : : /* Optimize x - y < 0 into x < 0 if x - y has undefined overflow. */
13555 : :
13556 : : void
13557 : 237037 : maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
13558 : : {
13559 : 237037 : gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
13560 : : || code == LT_EXPR || code == LE_EXPR);
13561 : 237037 : gcc_checking_assert (integer_zerop (*arg1));
13562 : :
13563 : 237037 : if (!optimize)
13564 : : return;
13565 : :
13566 : 203844 : gimple *stmt = get_def_for_expr (*arg0, MINUS_EXPR);
13567 : 203844 : if (stmt == NULL)
13568 : : return;
13569 : :
13570 : 1283 : tree treeop0 = gimple_assign_rhs1 (stmt);
13571 : 1283 : tree treeop1 = gimple_assign_rhs2 (stmt);
13572 : 1283 : if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
13573 : : return;
13574 : :
13575 : 1186 : if (issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_COMPARISON))
13576 : 1 : warning_at (gimple_location (stmt), OPT_Wstrict_overflow,
13577 : : "assuming signed overflow does not occur when "
13578 : : "simplifying %<X - Y %s 0%> to %<X %s Y%>",
13579 : : op_symbol_code (code), op_symbol_code (code));
13580 : :
13581 : 1186 : *arg0 = treeop0;
13582 : 1186 : *arg1 = treeop1;
13583 : : }
13584 : :
13585 : :
13586 : : /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
13587 : : a single bit equality/inequality test, returns where the result is located. */
13588 : :
13589 : : static rtx
13590 : 11076 : expand_single_bit_test (location_t loc, enum tree_code code,
13591 : : tree inner, int bitnum,
13592 : : tree result_type, rtx target,
13593 : : machine_mode mode)
13594 : : {
13595 : 11076 : gcc_assert (code == NE_EXPR || code == EQ_EXPR);
13596 : :
13597 : 11076 : tree type = TREE_TYPE (inner);
13598 : 11076 : scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
13599 : 11076 : int ops_unsigned;
13600 : 11076 : tree signed_type, unsigned_type, intermediate_type;
13601 : 11076 : gimple *inner_def;
13602 : :
13603 : : /* First, see if we can fold the single bit test into a sign-bit
13604 : : test. */
13605 : 11076 : if (bitnum == TYPE_PRECISION (type) - 1
13606 : 11076 : && type_has_mode_precision_p (type))
13607 : : {
13608 : 231 : tree stype = signed_type_for (type);
13609 : 428 : tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
13610 : : result_type,
13611 : : fold_convert_loc (loc, stype, inner),
13612 : : build_int_cst (stype, 0));
13613 : 231 : return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
13614 : : }
13615 : :
13616 : : /* Otherwise we have (A & C) != 0 where C is a single bit,
13617 : : convert that into ((A >> C2) & 1). Where C2 = log2(C).
13618 : : Similarly for (A & C) == 0. */
13619 : :
13620 : : /* If INNER is a right shift of a constant and it plus BITNUM does
13621 : : not overflow, adjust BITNUM and INNER. */
13622 : 10845 : if ((inner_def = get_def_for_expr (inner, RSHIFT_EXPR))
13623 : 13 : && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
13624 : 0 : && bitnum < TYPE_PRECISION (type)
13625 : 10845 : && wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (inner_def)),
13626 : 10845 : TYPE_PRECISION (type) - bitnum))
13627 : : {
13628 : 0 : bitnum += tree_to_uhwi (gimple_assign_rhs2 (inner_def));
13629 : 0 : inner = gimple_assign_rhs1 (inner_def);
13630 : : }
13631 : :
13632 : : /* If we are going to be able to omit the AND below, we must do our
13633 : : operations as unsigned. If we must use the AND, we have a choice.
13634 : : Normally unsigned is faster, but for some machines signed is. */
13635 : 10845 : ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
13636 : : && !flag_syntax_only) ? 0 : 1;
13637 : :
13638 : 10845 : signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
13639 : 10845 : unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
13640 : 10845 : intermediate_type = ops_unsigned ? unsigned_type : signed_type;
13641 : 10845 : inner = fold_convert_loc (loc, intermediate_type, inner);
13642 : :
13643 : 10845 : rtx inner0 = expand_expr (inner, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13644 : :
13645 : 10845 : if (CONST_SCALAR_INT_P (inner0))
13646 : : {
13647 : 0 : wide_int t = rtx_mode_t (inner0, operand_mode);
13648 : 0 : bool setp = (wi::lrshift (t, bitnum) & 1) != 0;
13649 : 0 : return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
13650 : 0 : }
13651 : 10845 : int bitpos = bitnum;
13652 : :
13653 : 10845 : if (BYTES_BIG_ENDIAN)
13654 : : bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
13655 : :
13656 : 10845 : inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
13657 : : operand_mode, mode, 0, NULL);
13658 : :
13659 : 10845 : if (code == EQ_EXPR)
13660 : 3846 : inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
13661 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
13662 : 10845 : if (GET_MODE (inner0) != mode)
13663 : : {
13664 : 0 : rtx t = gen_reg_rtx (mode);
13665 : 0 : convert_move (t, inner0, 0);
13666 : 0 : return t;
13667 : : }
13668 : : return inner0;
13669 : : }
13670 : :
13671 : : /* Generate code to calculate OPS, and exploded expression
13672 : : using a store-flag instruction and return an rtx for the result.
13673 : : OPS reflects a comparison.
13674 : :
13675 : : If TARGET is nonzero, store the result there if convenient.
13676 : :
13677 : : Return zero if there is no suitable set-flag instruction
13678 : : available on this machine.
13679 : :
13680 : : Once expand_expr has been called on the arguments of the comparison,
13681 : : we are committed to doing the store flag, since it is not safe to
13682 : : re-evaluate the expression. We emit the store-flag insn by calling
13683 : : emit_store_flag, but only expand the arguments if we have a reason
13684 : : to believe that emit_store_flag will be successful. If we think that
13685 : : it will, but it isn't, we have to simulate the store-flag with a
13686 : : set/jump/set sequence. */
13687 : :
13688 : : static rtx
13689 : 542239 : do_store_flag (const_sepops ops, rtx target, machine_mode mode)
13690 : : {
13691 : 542239 : enum rtx_code code;
13692 : 542239 : tree arg0, arg1, type;
13693 : 542239 : machine_mode operand_mode;
13694 : 542239 : int unsignedp;
13695 : 542239 : rtx op0, op1;
13696 : 542239 : rtx subtarget = target;
13697 : 542239 : location_t loc = ops->location;
13698 : 542239 : unsigned HOST_WIDE_INT nunits;
13699 : :
13700 : 542239 : arg0 = ops->op0;
13701 : 542239 : arg1 = ops->op1;
13702 : :
13703 : : /* Don't crash if the comparison was erroneous. */
13704 : 542239 : if (arg0 == error_mark_node || arg1 == error_mark_node)
13705 : 0 : return const0_rtx;
13706 : :
13707 : 542239 : type = TREE_TYPE (arg0);
13708 : 542239 : operand_mode = TYPE_MODE (type);
13709 : 542239 : unsignedp = TYPE_UNSIGNED (type);
13710 : :
13711 : : /* We won't bother with BLKmode store-flag operations because it would mean
13712 : : passing a lot of information to emit_store_flag. */
13713 : 542239 : if (operand_mode == BLKmode)
13714 : : return 0;
13715 : :
13716 : : /* We won't bother with store-flag operations involving function pointers
13717 : : when function pointers must be canonicalized before comparisons. */
13718 : 542239 : if (targetm.have_canonicalize_funcptr_for_compare ()
13719 : 542239 : && ((POINTER_TYPE_P (TREE_TYPE (arg0))
13720 : 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
13721 : 0 : || (POINTER_TYPE_P (TREE_TYPE (arg1))
13722 : 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
13723 : : return 0;
13724 : :
13725 : 542239 : STRIP_NOPS (arg0);
13726 : 542239 : STRIP_NOPS (arg1);
13727 : :
13728 : : /* For vector typed comparisons emit code to generate the desired
13729 : : all-ones or all-zeros mask. */
13730 : 542239 : if (VECTOR_TYPE_P (ops->type))
13731 : : {
13732 : 19970 : tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
13733 : 19970 : if (VECTOR_BOOLEAN_TYPE_P (ops->type)
13734 : 39940 : && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
13735 : 19970 : return expand_vec_cmp_expr (ops->type, ifexp, target);
13736 : : else
13737 : 0 : gcc_unreachable ();
13738 : : }
13739 : :
13740 : : /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
13741 : : into (x - C2) * C3 < C4. */
13742 : 522269 : if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
13743 : 322782 : && TREE_CODE (arg0) == SSA_NAME
13744 : 322267 : && TREE_CODE (arg1) == INTEGER_CST)
13745 : : {
13746 : 190618 : enum tree_code new_code = maybe_optimize_mod_cmp (ops->code,
13747 : : &arg0, &arg1);
13748 : 190618 : if (new_code != ops->code)
13749 : : {
13750 : 75 : struct separate_ops nops = *ops;
13751 : 75 : nops.code = new_code;
13752 : 75 : nops.op0 = arg0;
13753 : 75 : nops.op1 = arg1;
13754 : 75 : nops.type = TREE_TYPE (arg0);
13755 : 75 : return do_store_flag (&nops, target, mode);
13756 : : }
13757 : : }
13758 : :
13759 : : /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow. */
13760 : 522194 : if (!unsignedp
13761 : 341561 : && (ops->code == LT_EXPR || ops->code == LE_EXPR
13762 : 341561 : || ops->code == GT_EXPR || ops->code == GE_EXPR)
13763 : 122906 : && integer_zerop (arg1)
13764 : 561934 : && TREE_CODE (arg0) == SSA_NAME)
13765 : 39736 : maybe_optimize_sub_cmp_0 (ops->code, &arg0, &arg1);
13766 : :
13767 : : /* Get the rtx comparison code to use. We know that EXP is a comparison
13768 : : operation of some type. Some comparisons against 1 and -1 can be
13769 : : converted to comparisons with zero. Do so here so that the tests
13770 : : below will be aware that we have a comparison with zero. These
13771 : : tests will not catch constants in the first operand, but constants
13772 : : are rarely passed as the first operand. */
13773 : :
13774 : 522194 : switch (ops->code)
13775 : : {
13776 : : case EQ_EXPR:
13777 : : code = EQ;
13778 : : break;
13779 : 193743 : case NE_EXPR:
13780 : 193743 : code = NE;
13781 : 193743 : break;
13782 : 41440 : case LT_EXPR:
13783 : 41440 : if (integer_onep (arg1))
13784 : 0 : arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
13785 : : else
13786 : 41440 : code = unsignedp ? LTU : LT;
13787 : : break;
13788 : 33374 : case LE_EXPR:
13789 : 33374 : if (! unsignedp && integer_all_onesp (arg1))
13790 : 0 : arg1 = integer_zero_node, code = LT;
13791 : : else
13792 : 33374 : code = unsignedp ? LEU : LE;
13793 : : break;
13794 : 57109 : case GT_EXPR:
13795 : 57109 : if (! unsignedp && integer_all_onesp (arg1))
13796 : 0 : arg1 = integer_zero_node, code = GE;
13797 : : else
13798 : 57109 : code = unsignedp ? GTU : GT;
13799 : : break;
13800 : 44084 : case GE_EXPR:
13801 : 44084 : if (integer_onep (arg1))
13802 : 29427 : arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
13803 : : else
13804 : 44084 : code = unsignedp ? GEU : GE;
13805 : : break;
13806 : :
13807 : 674 : case UNORDERED_EXPR:
13808 : 674 : code = UNORDERED;
13809 : 674 : break;
13810 : 678 : case ORDERED_EXPR:
13811 : 678 : code = ORDERED;
13812 : 678 : break;
13813 : 482 : case UNLT_EXPR:
13814 : 482 : code = UNLT;
13815 : 482 : break;
13816 : 10782 : case UNLE_EXPR:
13817 : 10782 : code = UNLE;
13818 : 10782 : break;
13819 : 825 : case UNGT_EXPR:
13820 : 825 : code = UNGT;
13821 : 825 : break;
13822 : 9818 : case UNGE_EXPR:
13823 : 9818 : code = UNGE;
13824 : 9818 : break;
13825 : 141 : case UNEQ_EXPR:
13826 : 141 : code = UNEQ;
13827 : 141 : break;
13828 : 80 : case LTGT_EXPR:
13829 : 80 : code = LTGT;
13830 : 80 : break;
13831 : :
13832 : 0 : default:
13833 : 0 : gcc_unreachable ();
13834 : : }
13835 : :
13836 : : /* Put a constant second. */
13837 : 522194 : if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
13838 : 521187 : || TREE_CODE (arg0) == FIXED_CST)
13839 : : {
13840 : 1007 : std::swap (arg0, arg1);
13841 : 1007 : code = swap_condition (code);
13842 : : }
13843 : :
13844 : : /* If this is an equality or inequality test of a single bit, we can
13845 : : do this by shifting the bit being tested to the low-order bit and
13846 : : masking the result with the constant 1. If the condition was EQ,
13847 : : we xor it with 1. This does not require an scc insn and is faster
13848 : : than an scc insn even if we have it. */
13849 : :
13850 : 522194 : if ((code == NE || code == EQ)
13851 : 322707 : && (integer_zerop (arg1)
13852 : 205908 : || integer_pow2p (arg1))
13853 : : /* vector types are not handled here. */
13854 : 147111 : && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE
13855 : 669296 : && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
13856 : : {
13857 : 147102 : tree narg0 = arg0;
13858 : 147102 : wide_int nz = tree_nonzero_bits (narg0);
13859 : 147102 : gimple *srcstmt = get_def_for_expr (narg0, BIT_AND_EXPR);
13860 : : /* If the defining statement was (x & POW2), then use that instead of
13861 : : the non-zero bits. */
13862 : 147102 : if (srcstmt && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
13863 : : {
13864 : 6714 : nz = wi::to_wide (gimple_assign_rhs2 (srcstmt));
13865 : 6714 : narg0 = gimple_assign_rhs1 (srcstmt);
13866 : : }
13867 : :
13868 : 147102 : if (wi::popcount (nz) == 1
13869 : 147102 : && (integer_zerop (arg1)
13870 : 136060 : || wi::to_wide (arg1) == nz))
13871 : : {
13872 : 11076 : int bitnum = wi::exact_log2 (nz);
13873 : 11076 : enum tree_code tcode = EQ_EXPR;
13874 : 11076 : if ((code == NE) ^ !integer_zerop (arg1))
13875 : 7196 : tcode = NE_EXPR;
13876 : :
13877 : 11076 : type = lang_hooks.types.type_for_mode (mode, unsignedp);
13878 : 11076 : return expand_single_bit_test (loc, tcode,
13879 : : narg0,
13880 : : bitnum, type, target, mode);
13881 : : }
13882 : 147102 : }
13883 : :
13884 : :
13885 : 511118 : if (! get_subtarget (target)
13886 : 511118 : || GET_MODE (subtarget) != operand_mode)
13887 : : subtarget = 0;
13888 : :
13889 : 511118 : expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
13890 : :
13891 : : /* For boolean vectors with less than mode precision
13892 : : make sure to fill padding with consistent values. */
13893 : 9 : if (VECTOR_BOOLEAN_TYPE_P (type)
13894 : 0 : && SCALAR_INT_MODE_P (operand_mode)
13895 : 511118 : && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
13896 : 511118 : && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
13897 : : {
13898 : 0 : gcc_assert (code == EQ || code == NE);
13899 : 0 : op0 = expand_binop (mode, and_optab, op0,
13900 : 0 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
13901 : : NULL_RTX, true, OPTAB_WIDEN);
13902 : 0 : op1 = expand_binop (mode, and_optab, op1,
13903 : : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
13904 : : NULL_RTX, true, OPTAB_WIDEN);
13905 : : }
13906 : :
13907 : 511118 : if (target == 0)
13908 : 327306 : target = gen_reg_rtx (mode);
13909 : :
13910 : : /* Try a cstore if possible. */
13911 : 511118 : return emit_store_flag_force (target, code, op0, op1,
13912 : : operand_mode, unsignedp,
13913 : 511118 : (TYPE_PRECISION (ops->type) == 1
13914 : 1021626 : && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
13915 : : }
13916 : :
13917 : : /* Attempt to generate a casesi instruction. Returns true if successful,
13918 : : false otherwise (i.e. if there is no casesi instruction).
13919 : :
13920 : : DEFAULT_PROBABILITY is the probability of jumping to the default
13921 : : label. */
13922 : : bool
13923 : 9843 : try_casesi (tree index_type, tree index_expr, tree minval, tree range,
13924 : : rtx table_label, rtx default_label, rtx fallback_label,
13925 : : profile_probability default_probability)
13926 : : {
13927 : 9843 : class expand_operand ops[5];
13928 : 9843 : scalar_int_mode index_mode = SImode;
13929 : 9843 : rtx op1, op2, index;
13930 : :
13931 : 9843 : if (! targetm.have_casesi ())
13932 : : return false;
13933 : :
13934 : : /* The index must be some form of integer. Convert it to SImode. */
13935 : 0 : scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
13936 : 0 : if (GET_MODE_BITSIZE (omode) > GET_MODE_BITSIZE (index_mode))
13937 : : {
13938 : 0 : rtx rangertx = expand_normal (range);
13939 : :
13940 : : /* We must handle the endpoints in the original mode. */
13941 : 0 : index_expr = build2 (MINUS_EXPR, index_type,
13942 : : index_expr, minval);
13943 : 0 : minval = integer_zero_node;
13944 : 0 : index = expand_normal (index_expr);
13945 : 0 : if (default_label)
13946 : 0 : emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
13947 : : omode, 1, default_label,
13948 : : default_probability);
13949 : : /* Now we can safely truncate. */
13950 : 0 : index = convert_to_mode (index_mode, index, 0);
13951 : : }
13952 : : else
13953 : : {
13954 : 0 : if (omode != index_mode)
13955 : : {
13956 : 0 : index_type = lang_hooks.types.type_for_mode (index_mode, 0);
13957 : 0 : index_expr = fold_convert (index_type, index_expr);
13958 : : }
13959 : :
13960 : 0 : index = expand_normal (index_expr);
13961 : : }
13962 : :
13963 : 0 : do_pending_stack_adjust ();
13964 : :
13965 : 0 : op1 = expand_normal (minval);
13966 : 0 : op2 = expand_normal (range);
13967 : :
13968 : 0 : create_input_operand (&ops[0], index, index_mode);
13969 : 0 : create_convert_operand_from_type (&ops[1], op1, TREE_TYPE (minval));
13970 : 0 : create_convert_operand_from_type (&ops[2], op2, TREE_TYPE (range));
13971 : 0 : create_fixed_operand (&ops[3], table_label);
13972 : 0 : create_fixed_operand (&ops[4], (default_label
13973 : : ? default_label
13974 : : : fallback_label));
13975 : 0 : expand_jump_insn (targetm.code_for_casesi, 5, ops);
13976 : 0 : return true;
13977 : : }
13978 : :
13979 : : /* Attempt to generate a tablejump instruction; same concept. */
13980 : : /* Subroutine of the next function.
13981 : :
13982 : : INDEX is the value being switched on, with the lowest value
13983 : : in the table already subtracted.
13984 : : MODE is its expected mode (needed if INDEX is constant).
13985 : : RANGE is the length of the jump table.
13986 : : TABLE_LABEL is a CODE_LABEL rtx for the table itself.
13987 : :
13988 : : DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
13989 : : index value is out of range.
13990 : : DEFAULT_PROBABILITY is the probability of jumping to
13991 : : the default label. */
13992 : :
13993 : : static void
13994 : 9843 : do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
13995 : : rtx default_label, profile_probability default_probability)
13996 : : {
13997 : 9843 : rtx temp, vector;
13998 : :
13999 : 9843 : if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
14000 : 7920 : cfun->cfg->max_jumptable_ents = INTVAL (range);
14001 : :
14002 : : /* Do an unsigned comparison (in the proper mode) between the index
14003 : : expression and the value which represents the length of the range.
14004 : : Since we just finished subtracting the lower bound of the range
14005 : : from the index expression, this comparison allows us to simultaneously
14006 : : check that the original index expression value is both greater than
14007 : : or equal to the minimum value of the range and less than or equal to
14008 : : the maximum value of the range. */
14009 : :
14010 : 9843 : if (default_label)
14011 : 5601 : emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
14012 : : default_label, default_probability);
14013 : :
14014 : : /* If index is in range, it must fit in Pmode.
14015 : : Convert to Pmode so we can index with it. */
14016 : 10810 : if (mode != Pmode)
14017 : : {
14018 : 8853 : unsigned int width;
14019 : :
14020 : : /* We know the value of INDEX is between 0 and RANGE. If we have a
14021 : : sign-extended subreg, and RANGE does not have the sign bit set, then
14022 : : we have a value that is valid for both sign and zero extension. In
14023 : : this case, we get better code if we sign extend. */
14024 : 8853 : if (GET_CODE (index) == SUBREG
14025 : 9 : && SUBREG_PROMOTED_VAR_P (index)
14026 : 0 : && SUBREG_PROMOTED_SIGNED_P (index)
14027 : 0 : && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode)))
14028 : : <= HOST_BITS_PER_WIDE_INT)
14029 : 8853 : && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
14030 : 0 : index = convert_to_mode (Pmode, index, 0);
14031 : : else
14032 : 8853 : index = convert_to_mode (Pmode, index, 1);
14033 : : }
14034 : :
14035 : : /* Don't let a MEM slip through, because then INDEX that comes
14036 : : out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
14037 : : and break_out_memory_refs will go to work on it and mess it up. */
14038 : : #ifdef PIC_CASE_VECTOR_ADDRESS
14039 : : if (flag_pic && !REG_P (index))
14040 : : index = copy_to_mode_reg (Pmode, index);
14041 : : #endif
14042 : :
14043 : : /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
14044 : : GET_MODE_SIZE, because this indicates how large insns are. The other
14045 : : uses should all be Pmode, because they are addresses. This code
14046 : : could fail if addresses and insns are not the same size. */
14047 : 10810 : index = simplify_gen_binary (MULT, Pmode, index,
14048 : 19686 : gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
14049 : 9843 : Pmode));
14050 : 10810 : index = simplify_gen_binary (PLUS, Pmode, index,
14051 : 9843 : gen_rtx_LABEL_REF (Pmode, table_label));
14052 : :
14053 : : #ifdef PIC_CASE_VECTOR_ADDRESS
14054 : : if (flag_pic)
14055 : : index = PIC_CASE_VECTOR_ADDRESS (index);
14056 : : else
14057 : : #endif
14058 : 11311 : index = memory_address (CASE_VECTOR_MODE, index);
14059 : 11311 : temp = gen_reg_rtx (CASE_VECTOR_MODE);
14060 : 11311 : vector = gen_const_mem (CASE_VECTOR_MODE, index);
14061 : 9843 : convert_move (temp, vector, 0);
14062 : :
14063 : 9843 : emit_jump_insn (targetm.gen_tablejump (temp, table_label));
14064 : :
14065 : : /* If we are generating PIC code or if the table is PC-relative, the
14066 : : table and JUMP_INSN must be adjacent, so don't output a BARRIER. */
14067 : 9843 : if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
14068 : 8874 : emit_barrier ();
14069 : 9843 : }
14070 : :
14071 : : bool
14072 : 9843 : try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
14073 : : rtx table_label, rtx default_label,
14074 : : profile_probability default_probability)
14075 : : {
14076 : 9843 : rtx index;
14077 : :
14078 : 9843 : if (! targetm.have_tablejump ())
14079 : : return false;
14080 : :
14081 : 9843 : index_expr = fold_build2 (MINUS_EXPR, index_type,
14082 : : fold_convert (index_type, index_expr),
14083 : : fold_convert (index_type, minval));
14084 : 9843 : index = expand_normal (index_expr);
14085 : 9843 : do_pending_stack_adjust ();
14086 : :
14087 : 9843 : do_tablejump (index, TYPE_MODE (index_type),
14088 : 9843 : convert_modes (TYPE_MODE (index_type),
14089 : 9843 : TYPE_MODE (TREE_TYPE (range)),
14090 : : expand_normal (range),
14091 : 9843 : TYPE_UNSIGNED (TREE_TYPE (range))),
14092 : : table_label, default_label, default_probability);
14093 : 9843 : return true;
14094 : : }
14095 : :
14096 : : /* Return a CONST_VECTOR rtx representing vector mask for
14097 : : a VECTOR_CST of booleans. */
14098 : : static rtx
14099 : 33 : const_vector_mask_from_tree (tree exp)
14100 : : {
14101 : 33 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14102 : 33 : machine_mode inner = GET_MODE_INNER (mode);
14103 : :
14104 : 33 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14105 : 33 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14106 : 33 : unsigned int count = builder.encoded_nelts ();
14107 : 131 : for (unsigned int i = 0; i < count; ++i)
14108 : : {
14109 : 98 : tree elt = VECTOR_CST_ELT (exp, i);
14110 : 98 : gcc_assert (TREE_CODE (elt) == INTEGER_CST);
14111 : 98 : if (integer_zerop (elt))
14112 : 43 : builder.quick_push (CONST0_RTX (inner));
14113 : 55 : else if (integer_onep (elt)
14114 : 55 : || integer_minus_onep (elt))
14115 : 55 : builder.quick_push (CONSTM1_RTX (inner));
14116 : : else
14117 : 0 : gcc_unreachable ();
14118 : : }
14119 : 33 : return builder.build ();
14120 : 33 : }
14121 : :
14122 : : /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
14123 : : static rtx
14124 : 538627 : const_vector_from_tree (tree exp)
14125 : : {
14126 : 538627 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14127 : :
14128 : 538627 : if (initializer_zerop (exp))
14129 : 158473 : return CONST0_RTX (mode);
14130 : :
14131 : 380154 : if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
14132 : 33 : return const_vector_mask_from_tree (exp);
14133 : :
14134 : 380121 : machine_mode inner = GET_MODE_INNER (mode);
14135 : :
14136 : 380121 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14137 : 380121 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14138 : 380121 : unsigned int count = builder.encoded_nelts ();
14139 : 1227233 : for (unsigned int i = 0; i < count; ++i)
14140 : : {
14141 : 847112 : tree elt = VECTOR_CST_ELT (exp, i);
14142 : 847112 : if (TREE_CODE (elt) == REAL_CST)
14143 : 132791 : builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt),
14144 : : inner));
14145 : 714321 : else if (TREE_CODE (elt) == FIXED_CST)
14146 : 0 : builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
14147 : : inner));
14148 : : else
14149 : 714321 : builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt),
14150 : : inner));
14151 : : }
14152 : 380121 : return builder.build ();
14153 : 380121 : }
14154 : :
14155 : : /* Build a decl for a personality function given a language prefix. */
14156 : :
14157 : : tree
14158 : 31621 : build_personality_function (const char *lang)
14159 : : {
14160 : 31621 : const char *unwind_and_version;
14161 : 31621 : tree decl, type;
14162 : 31621 : char *name;
14163 : :
14164 : 31621 : switch (targetm_common.except_unwind_info (&global_options))
14165 : : {
14166 : : case UI_NONE:
14167 : : return NULL;
14168 : : case UI_SJLJ:
14169 : : unwind_and_version = "_sj0";
14170 : : break;
14171 : 31621 : case UI_DWARF2:
14172 : 31621 : case UI_TARGET:
14173 : 31621 : unwind_and_version = "_v0";
14174 : 31621 : break;
14175 : 0 : case UI_SEH:
14176 : 0 : unwind_and_version = "_seh0";
14177 : 0 : break;
14178 : 0 : default:
14179 : 0 : gcc_unreachable ();
14180 : : }
14181 : :
14182 : 31621 : name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
14183 : :
14184 : 31621 : type = build_function_type_list (unsigned_type_node,
14185 : : integer_type_node, integer_type_node,
14186 : : long_long_unsigned_type_node,
14187 : : ptr_type_node, ptr_type_node, NULL_TREE);
14188 : 31621 : decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
14189 : : get_identifier (name), type);
14190 : 31621 : DECL_ARTIFICIAL (decl) = 1;
14191 : 31621 : DECL_EXTERNAL (decl) = 1;
14192 : 31621 : TREE_PUBLIC (decl) = 1;
14193 : :
14194 : : /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
14195 : : are the flags assigned by targetm.encode_section_info. */
14196 : 31621 : SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
14197 : :
14198 : 31621 : return decl;
14199 : : }
14200 : :
14201 : : /* Extracts the personality function of DECL and returns the corresponding
14202 : : libfunc. */
14203 : :
14204 : : rtx
14205 : 1595955 : get_personality_function (tree decl)
14206 : : {
14207 : 1595955 : tree personality = DECL_FUNCTION_PERSONALITY (decl);
14208 : 1595955 : enum eh_personality_kind pk;
14209 : :
14210 : 1595955 : pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
14211 : 1595955 : if (pk == eh_personality_none)
14212 : : return NULL;
14213 : :
14214 : 157783 : if (!personality
14215 : 157783 : && pk == eh_personality_any)
14216 : 74945 : personality = lang_hooks.eh_personality ();
14217 : :
14218 : 157783 : if (pk == eh_personality_lang)
14219 : 82838 : gcc_assert (personality != NULL_TREE);
14220 : :
14221 : 157783 : return XEXP (DECL_RTL (personality), 0);
14222 : : }
14223 : :
14224 : : /* Returns a tree for the size of EXP in bytes. */
14225 : :
14226 : : static tree
14227 : 14480760 : tree_expr_size (const_tree exp)
14228 : : {
14229 : 14480760 : if (DECL_P (exp)
14230 : 14480760 : && DECL_SIZE_UNIT (exp) != 0)
14231 : 1962535 : return DECL_SIZE_UNIT (exp);
14232 : : else
14233 : 12518225 : return size_in_bytes (TREE_TYPE (exp));
14234 : : }
14235 : :
14236 : : /* Return an rtx for the size in bytes of the value of EXP. */
14237 : :
14238 : : rtx
14239 : 14291721 : expr_size (tree exp)
14240 : : {
14241 : 14291721 : tree size;
14242 : :
14243 : 14291721 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14244 : 767 : size = TREE_OPERAND (exp, 1);
14245 : : else
14246 : : {
14247 : 14290954 : size = tree_expr_size (exp);
14248 : 14290954 : gcc_assert (size);
14249 : 14290954 : gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
14250 : : }
14251 : :
14252 : 14291721 : return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
14253 : : }
14254 : :
14255 : : /* Return a wide integer for the size in bytes of the value of EXP, or -1
14256 : : if the size can vary or is larger than an integer. */
14257 : :
14258 : : HOST_WIDE_INT
14259 : 189806 : int_expr_size (const_tree exp)
14260 : : {
14261 : 189806 : tree size;
14262 : :
14263 : 189806 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14264 : 0 : size = TREE_OPERAND (exp, 1);
14265 : : else
14266 : : {
14267 : 189806 : size = tree_expr_size (exp);
14268 : 189806 : gcc_assert (size);
14269 : : }
14270 : :
14271 : 189806 : if (size == 0 || !tree_fits_shwi_p (size))
14272 : 0 : return -1;
14273 : :
14274 : 189806 : return tree_to_shwi (size);
14275 : : }
14276 : :
14277 : : /* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
14278 : : in GF (2^N).
14279 : : Author: Richard Sandiford <richard.sandiford@arm.com> */
14280 : :
14281 : : unsigned HOST_WIDE_INT
14282 : 0 : gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
14283 : : unsigned short n)
14284 : : {
14285 : : /* The result has degree N, so needs N + 1 bits. */
14286 : 0 : gcc_assert (n < 64);
14287 : :
14288 : : /* Perform a division step for the x^2N coefficient. At this point the
14289 : : quotient and remainder have N implicit trailing zeros. */
14290 : : unsigned HOST_WIDE_INT quotient = 1;
14291 : : unsigned HOST_WIDE_INT remainder = polynomial;
14292 : :
14293 : : /* Process the coefficients for x^(2N-1) down to x^N, with each step
14294 : : reducing the number of implicit trailing zeros by one. */
14295 : 0 : for (unsigned int i = 0; i < n; ++i)
14296 : : {
14297 : 0 : bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
14298 : 0 : quotient = (quotient << 1) | coeff;
14299 : 0 : remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
14300 : : }
14301 : 0 : return quotient;
14302 : : }
14303 : :
14304 : : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
14305 : : CRC_BITS is CRC size. */
14306 : :
14307 : : static unsigned HOST_WIDE_INT
14308 : 68096 : calculate_crc (unsigned HOST_WIDE_INT crc,
14309 : : unsigned HOST_WIDE_INT polynomial,
14310 : : unsigned short crc_bits)
14311 : : {
14312 : 68096 : unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
14313 : 68096 : crc = crc << (crc_bits - 8);
14314 : 612864 : for (short i = 8; i > 0; --i)
14315 : : {
14316 : 544768 : if (crc & msb)
14317 : 272384 : crc = (crc << 1) ^ polynomial;
14318 : : else
14319 : 272384 : crc <<= 1;
14320 : : }
14321 : : /* Zero out bits in crc beyond the specified number of crc_bits. */
14322 : 68096 : if (crc_bits < sizeof (crc) * CHAR_BIT)
14323 : 59648 : crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
14324 : 68096 : return crc;
14325 : : }
14326 : :
14327 : : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
14328 : : POLYNOM is the polynomial used to calculate the CRC table's elements.
14329 : : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14330 : :
14331 : : static rtx
14332 : 266 : assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14333 : : {
14334 : 266 : unsigned table_el_n = 0x100;
14335 : 266 : tree ar = build_array_type (make_unsigned_type (crc_bits),
14336 : 266 : build_index_type (size_int (table_el_n - 1)));
14337 : :
14338 : : /* Initialize the table. */
14339 : 266 : vec<tree, va_gc> *initial_values;
14340 : 266 : vec_alloc (initial_values, table_el_n);
14341 : 68362 : for (size_t i = 0; i < table_el_n; ++i)
14342 : : {
14343 : 68096 : unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
14344 : 68096 : tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
14345 : 68096 : vec_safe_push (initial_values, element);
14346 : : }
14347 : 266 : tree ctor = build_constructor_from_vec (ar, initial_values);
14348 : 266 : rtx mem = output_constant_def (ctor, 1);
14349 : 266 : gcc_assert (MEM_P (mem));
14350 : 266 : if (dump_file && (dump_flags & TDF_DETAILS))
14351 : : {
14352 : 32 : fprintf (dump_file,
14353 : : ";; emitting crc table crc_%u_polynomial_"
14354 : : HOST_WIDE_INT_PRINT_HEX " ",
14355 : : crc_bits, polynom);
14356 : 32 : print_rtl_single (dump_file, XEXP (mem, 0));
14357 : 32 : fprintf (dump_file, "\n");
14358 : : }
14359 : :
14360 : 266 : return XEXP (mem, 0);
14361 : : }
14362 : :
14363 : : /* Generate CRC lookup table by calculating CRC for all possible
14364 : : 8-bit data values. The table is stored with a specific name in the read-only
14365 : : static data section.
14366 : : POLYNOM is the polynomial used to calculate the CRC table's elements.
14367 : : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14368 : :
14369 : : static rtx
14370 : 266 : generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14371 : : {
14372 : 266 : gcc_assert (crc_bits <= 64);
14373 : :
14374 : 266 : return assemble_crc_table (polynom, crc_bits);
14375 : : }
14376 : :
14377 : : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14378 : : POLYNOMIAL (without leading 1).
14379 : :
14380 : : First, using POLYNOMIAL's value generates CRC table of 256 elements,
14381 : : then generates the assembly for the following code,
14382 : : where crc_bit_size and data_bit_size may be 8, 16, 32, 64, depending on CRC:
14383 : :
14384 : : for (int i = 0; i < data_bit_size / 8; i++)
14385 : : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14386 : : ^ (data >> (data_bit_size - (i + 1) * 8)
14387 : : & 0xFF))];
14388 : :
14389 : : So to take values from the table, we need 8-bit data.
14390 : : If input data size is not 8, then first we extract upper 8 bits,
14391 : : then the other 8 bits, and so on. */
14392 : :
14393 : : static void
14394 : 266 : calculate_table_based_CRC (rtx *crc, const rtx &input_data,
14395 : : const rtx &polynomial,
14396 : : machine_mode data_mode)
14397 : : {
14398 : 266 : machine_mode mode = GET_MODE (*crc);
14399 : 266 : unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
14400 : 266 : unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
14401 : 266 : rtx tab = generate_crc_table (UINTVAL (polynomial), crc_bit_size);
14402 : :
14403 : 732 : for (unsigned short i = 0; i < data_size; i++)
14404 : : {
14405 : : /* crc >> (crc_bit_size - 8). */
14406 : 466 : *crc = force_reg (mode, *crc);
14407 : 466 : rtx op1 = expand_shift (RSHIFT_EXPR, mode, *crc, crc_bit_size - 8,
14408 : : NULL_RTX, 1);
14409 : :
14410 : : /* data >> (8 * (GET_MODE_SIZE (data_mode).to_constant () - i - 1)). */
14411 : 466 : unsigned range_8 = 8 * (data_size - i - 1);
14412 : : /* CRC's mode is always at least as wide as INPUT_DATA. Convert
14413 : : INPUT_DATA into CRC's mode. */
14414 : 466 : rtx data = gen_reg_rtx (mode);
14415 : 466 : convert_move (data, input_data, 1);
14416 : 466 : data = expand_shift (RSHIFT_EXPR, mode, data, range_8, NULL_RTX, 1);
14417 : :
14418 : : /* data >> (8 * (GET_MODE_SIZE (mode)
14419 : : .to_constant () - i - 1)) & 0xFF. */
14420 : 466 : rtx data_final = expand_and (mode, data,
14421 : : gen_int_mode (255, mode), NULL_RTX);
14422 : :
14423 : : /* (crc >> (crc_bit_size - 8)) ^ data_8bit. */
14424 : 466 : rtx in = expand_binop (mode, xor_optab, op1, data_final,
14425 : : NULL_RTX, 1, OPTAB_WIDEN);
14426 : :
14427 : : /* ((crc >> (crc_bit_size - 8)) ^ data_8bit) & 0xFF. */
14428 : 466 : rtx index = expand_and (mode, in, gen_int_mode (255, mode),
14429 : : NULL_RTX);
14430 : 932 : int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
14431 : 466 : index = expand_shift (LSHIFT_EXPR, mode, index,
14432 : 466 : log_crc_size, NULL_RTX, 0);
14433 : :
14434 : 484 : rtx addr = gen_reg_rtx (Pmode);
14435 : 466 : convert_move (addr, index, 1);
14436 : 484 : addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
14437 : : 0, OPTAB_DIRECT);
14438 : :
14439 : : /* crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit] */
14440 : 466 : rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
14441 : :
14442 : : /* (crc << 8) if CRC is larger than 8, otherwise crc = 0. */
14443 : 466 : rtx high = NULL_RTX;
14444 : 466 : if (crc_bit_size != 8)
14445 : 427 : high = expand_shift (LSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 0);
14446 : : else
14447 : 39 : high = gen_int_mode (0, mode);
14448 : :
14449 : : /* crc = (crc << 8)
14450 : : ^ crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit]; */
14451 : 466 : *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
14452 : : OPTAB_WIDEN);
14453 : : }
14454 : 266 : }
14455 : :
14456 : : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14457 : : POLYNOMIAL (without leading 1).
14458 : :
14459 : : CRC is OP1, data is OP2 and the polynomial is OP3.
14460 : : This must generate a CRC table and an assembly for the following code,
14461 : : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
14462 : : uint_crc_bit_size_t
14463 : : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
14464 : : uint_data_bit_size_t data, size_t size)
14465 : : {
14466 : : uint_crc_bit_size_t crc = crc_init;
14467 : : for (int i = 0; i < data_bit_size / 8; i++)
14468 : : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14469 : : ^ (data >> (data_bit_size - (i + 1) * 8)
14470 : : & 0xFF))];
14471 : : return crc;
14472 : : } */
14473 : :
14474 : : void
14475 : 135 : expand_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
14476 : : machine_mode data_mode)
14477 : : {
14478 : 135 : gcc_assert (!CONST_INT_P (op0));
14479 : 135 : gcc_assert (CONST_INT_P (op3));
14480 : 135 : machine_mode crc_mode = GET_MODE (op0);
14481 : 135 : rtx crc = gen_reg_rtx (crc_mode);
14482 : 135 : convert_move (crc, op1, 0);
14483 : 135 : calculate_table_based_CRC (&crc, op2, op3, data_mode);
14484 : 135 : convert_move (op0, crc, 0);
14485 : 135 : }
14486 : :
14487 : : /* Generate the common operation for reflecting values:
14488 : : *OP = (*OP & AND1_VALUE) << SHIFT_VAL | (*OP & AND2_VALUE) >> SHIFT_VAL; */
14489 : :
14490 : : void
14491 : 1666 : gen_common_operation_to_reflect (rtx *op,
14492 : : unsigned HOST_WIDE_INT and1_value,
14493 : : unsigned HOST_WIDE_INT and2_value,
14494 : : unsigned shift_val)
14495 : : {
14496 : 1666 : rtx op1 = expand_and (GET_MODE (*op), *op,
14497 : 1666 : gen_int_mode (and1_value, GET_MODE (*op)), NULL_RTX);
14498 : 1666 : op1 = expand_shift (LSHIFT_EXPR, GET_MODE (*op), op1, shift_val, op1, 0);
14499 : 1666 : rtx op2 = expand_and (GET_MODE (*op), *op,
14500 : 1666 : gen_int_mode (and2_value, GET_MODE (*op)), NULL_RTX);
14501 : 1666 : op2 = expand_shift (RSHIFT_EXPR, GET_MODE (*op), op2, shift_val, op2, 1);
14502 : 1666 : *op = expand_binop (GET_MODE (*op), ior_optab, op1,
14503 : : op2, *op, 0, OPTAB_LIB_WIDEN);
14504 : 1666 : }
14505 : :
14506 : : /* Reflect 64-bit value for the 64-bit target. */
14507 : :
14508 : : void
14509 : 47 : reflect_64_bit_value (rtx *op)
14510 : : {
14511 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00000000FFFFFFFF),
14512 : : HOST_WIDE_INT_C (0xFFFFFFFF00000000), 32);
14513 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF0000FFFF),
14514 : : HOST_WIDE_INT_C (0xFFFF0000FFFF0000), 16);
14515 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF00FF00FF),
14516 : : HOST_WIDE_INT_C (0xFF00FF00FF00FF00), 8);
14517 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F0F0F0F0F),
14518 : : HOST_WIDE_INT_C (0xF0F0F0F0F0F0F0F0), 4);
14519 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333333333333333),
14520 : : HOST_WIDE_INT_C (0xCCCCCCCCCCCCCCCC), 2);
14521 : 47 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555555555555555),
14522 : : HOST_WIDE_INT_C (0xAAAAAAAAAAAAAAAA), 1);
14523 : 47 : }
14524 : :
14525 : : /* Reflect 32-bit value for the 32-bit target. */
14526 : :
14527 : : void
14528 : 119 : reflect_32_bit_value (rtx *op)
14529 : : {
14530 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF),
14531 : : HOST_WIDE_INT_C (0xFFFF0000), 16);
14532 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF),
14533 : : HOST_WIDE_INT_C (0xFF00FF00), 8);
14534 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F),
14535 : : HOST_WIDE_INT_C (0xF0F0F0F0), 4);
14536 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33333333),
14537 : : HOST_WIDE_INT_C (0xCCCCCCCC), 2);
14538 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55555555),
14539 : : HOST_WIDE_INT_C (0xAAAAAAAA), 1);
14540 : 119 : }
14541 : :
14542 : : /* Reflect 16-bit value for the 16-bit target. */
14543 : :
14544 : : void
14545 : 108 : reflect_16_bit_value (rtx *op)
14546 : : {
14547 : 108 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF),
14548 : : HOST_WIDE_INT_C (0xFF00), 8);
14549 : 108 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F),
14550 : : HOST_WIDE_INT_C (0xF0F0), 4);
14551 : 108 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333),
14552 : : HOST_WIDE_INT_C (0xCCCC), 2);
14553 : 108 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555),
14554 : : HOST_WIDE_INT_C (0xAAAA), 1);
14555 : 108 : }
14556 : :
14557 : : /* Reflect 8-bit value for the 8-bit target. */
14558 : :
14559 : : void
14560 : 119 : reflect_8_bit_value (rtx *op)
14561 : : {
14562 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F),
14563 : : HOST_WIDE_INT_C (0xF0), 4);
14564 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33),
14565 : : HOST_WIDE_INT_C (0xCC), 2);
14566 : 119 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55),
14567 : : HOST_WIDE_INT_C (0xAA), 1);
14568 : 119 : }
14569 : :
14570 : : /* Generate instruction sequence which reflects the value of the OP
14571 : : using shift, and, or operations. OP's mode may be less than word_mode. */
14572 : :
14573 : : void
14574 : 393 : generate_reflecting_code_standard (rtx *op)
14575 : : {
14576 : 1179 : gcc_assert (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () >= 8
14577 : : && GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () <= 64);
14578 : :
14579 : 786 : if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 64)
14580 : 47 : reflect_64_bit_value (op);
14581 : 692 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 32)
14582 : 119 : reflect_32_bit_value (op);
14583 : 454 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 16)
14584 : 108 : reflect_16_bit_value (op);
14585 : : else
14586 : 119 : reflect_8_bit_value (op);
14587 : 393 : }
14588 : :
14589 : : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA and
14590 : : the POLYNOMIAL (without leading 1).
14591 : :
14592 : : CRC is OP1, data is OP2 and the polynomial is OP3.
14593 : : This must generate CRC table and assembly for the following code,
14594 : : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
14595 : : uint_crc_bit_size_t
14596 : : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
14597 : : uint_data_bit_size_t data, size_t size)
14598 : : {
14599 : : reflect (crc_init)
14600 : : uint_crc_bit_size_t crc = crc_init;
14601 : : reflect (data);
14602 : : for (int i = 0; i < data_bit_size / 8; i++)
14603 : : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14604 : : ^ (data >> (data_bit_size - (i + 1) * 8) & 0xFF))];
14605 : : reflect (crc);
14606 : : return crc;
14607 : : } */
14608 : :
14609 : : void
14610 : 131 : expand_reversed_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
14611 : : machine_mode data_mode,
14612 : : void (*gen_reflecting_code) (rtx *op))
14613 : : {
14614 : 131 : gcc_assert (!CONST_INT_P (op0));
14615 : 131 : gcc_assert (CONST_INT_P (op3));
14616 : 131 : machine_mode crc_mode = GET_MODE (op0);
14617 : :
14618 : 131 : rtx crc = gen_reg_rtx (crc_mode);
14619 : 131 : convert_move (crc, op1, 0);
14620 : 131 : gen_reflecting_code (&crc);
14621 : :
14622 : 131 : rtx data = gen_reg_rtx (data_mode);
14623 : 131 : convert_move (data, op2, 0);
14624 : 131 : gen_reflecting_code (&data);
14625 : :
14626 : 131 : calculate_table_based_CRC (&crc, data, op3, data_mode);
14627 : :
14628 : 131 : gen_reflecting_code (&crc);
14629 : 131 : convert_move (op0, crc, 0);
14630 : 131 : }
|