Line data Source code
1 : /* Convert tree expression to rtl instructions, for GNU compiler.
2 : Copyright (C) 1988-2026 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 : /* Cache of the "extended" flag in the target's _BitInt description
80 : for use during expand. */
81 : int bitint_extended = -1;
82 :
83 : static bool block_move_libcall_safe_for_call_parm (void);
84 : static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
85 : HOST_WIDE_INT, unsigned HOST_WIDE_INT,
86 : unsigned HOST_WIDE_INT,
87 : unsigned HOST_WIDE_INT, bool);
88 : static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned, int);
89 : static void emit_block_move_via_sized_loop (rtx, rtx, rtx, unsigned, unsigned);
90 : static void emit_block_move_via_oriented_loop (rtx, rtx, rtx, unsigned, unsigned);
91 : static rtx emit_block_cmp_via_loop (rtx, rtx, rtx, tree, rtx, bool,
92 : unsigned, unsigned);
93 : static rtx_insn *compress_float_constant (rtx, rtx);
94 : static rtx get_subtarget (rtx);
95 : static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
96 : machine_mode, tree, alias_set_type, bool, bool);
97 :
98 : static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
99 :
100 : static bool is_aligning_offset (const_tree, const_tree);
101 : static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
102 : static rtx do_store_flag (const_sepops, rtx, machine_mode);
103 : #ifdef PUSH_ROUNDING
104 : static void emit_single_push_insn (machine_mode, rtx, tree);
105 : #endif
106 : static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
107 : profile_probability);
108 : static rtx const_vector_from_tree (tree);
109 : static tree tree_expr_size (const_tree);
110 : static void convert_mode_scalar (rtx, rtx, int);
111 :
112 :
113 : /* This is run to set up which modes can be used
114 : directly in memory and to initialize the block move optab. It is run
115 : at the beginning of compilation and when the target is reinitialized. */
116 :
117 : void
118 218789 : init_expr_target (void)
119 : {
120 218789 : rtx pat;
121 218789 : int num_clobbers;
122 218789 : rtx mem, mem1;
123 218789 : rtx reg;
124 :
125 : /* Try indexing by frame ptr and try by stack ptr.
126 : It is known that on the Convex the stack ptr isn't a valid index.
127 : With luck, one or the other is valid on any machine. */
128 218789 : mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
129 218789 : mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
130 :
131 : /* A scratch register we can modify in-place below to avoid
132 : useless RTL allocations. */
133 218789 : reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
134 :
135 218789 : rtx_insn *insn = as_a<rtx_insn *> (rtx_alloc (INSN));
136 218789 : pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
137 218789 : PATTERN (insn) = pat;
138 :
139 27348625 : for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
140 27129836 : mode = (machine_mode) ((int) mode + 1))
141 : {
142 27129836 : int regno;
143 :
144 27129836 : direct_load[(int) mode] = direct_store[(int) mode] = 0;
145 27129836 : PUT_MODE (mem, mode);
146 27129836 : PUT_MODE (mem1, mode);
147 :
148 : /* See if there is some register that can be used in this mode and
149 : directly loaded or stored from memory. */
150 :
151 27129836 : if (mode != VOIDmode && mode != BLKmode)
152 1828750140 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER
153 1855442398 : && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
154 : regno++)
155 : {
156 1828750140 : if (!targetm.hard_regno_mode_ok (regno, mode))
157 1709006478 : continue;
158 :
159 119743662 : set_mode_and_regno (reg, mode, regno);
160 :
161 119743662 : SET_SRC (pat) = mem;
162 119743662 : SET_DEST (pat) = reg;
163 119743662 : if (recog (pat, insn, &num_clobbers) >= 0)
164 7355308 : direct_load[(int) mode] = 1;
165 :
166 119743662 : SET_SRC (pat) = mem1;
167 119743662 : SET_DEST (pat) = reg;
168 119743662 : if (recog (pat, insn, &num_clobbers) >= 0)
169 7355308 : direct_load[(int) mode] = 1;
170 :
171 119743662 : SET_SRC (pat) = reg;
172 119743662 : SET_DEST (pat) = mem;
173 119743662 : if (recog (pat, insn, &num_clobbers) >= 0)
174 7355308 : direct_store[(int) mode] = 1;
175 :
176 119743662 : SET_SRC (pat) = reg;
177 119743662 : SET_DEST (pat) = mem1;
178 119743662 : if (recog (pat, insn, &num_clobbers) >= 0)
179 7355308 : direct_store[(int) mode] = 1;
180 : }
181 : }
182 :
183 224497 : mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
184 :
185 218789 : opt_scalar_float_mode mode_iter;
186 1531523 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
187 : {
188 1312734 : scalar_float_mode mode = mode_iter.require ();
189 1312734 : scalar_float_mode srcmode;
190 4594569 : FOR_EACH_MODE_UNTIL (srcmode, mode)
191 : {
192 3281835 : enum insn_code ic;
193 :
194 3281835 : ic = can_extend_p (mode, srcmode, 0);
195 3281835 : if (ic == CODE_FOR_nothing)
196 2620820 : continue;
197 :
198 661015 : PUT_MODE (mem, srcmode);
199 :
200 661015 : if (insn_operand_matches (ic, 1, mem))
201 658876 : float_extend_from_mem[mode][srcmode] = true;
202 : }
203 : }
204 218789 : }
205 :
206 : /* This is run at the start of compiling a function. */
207 :
208 : void
209 1730071 : init_expr (void)
210 : {
211 1730071 : memset (&crtl->expr, 0, sizeof (crtl->expr));
212 1730071 : }
213 :
214 : /* Copy data from FROM to TO, where the machine modes are not the same.
215 : Both modes may be integer, or both may be floating, or both may be
216 : fixed-point.
217 : UNSIGNEDP should be nonzero if FROM is an unsigned type.
218 : This causes zero-extension instead of sign-extension. */
219 :
220 : void
221 2152874 : convert_move (rtx to, rtx from, int unsignedp)
222 : {
223 2152874 : machine_mode to_mode = GET_MODE (to);
224 2152874 : machine_mode from_mode = GET_MODE (from);
225 :
226 2152874 : gcc_assert (to_mode != BLKmode);
227 2152874 : gcc_assert (from_mode != BLKmode);
228 :
229 : /* If the source and destination are already the same, then there's
230 : nothing to do. */
231 2152874 : if (to == from)
232 2152874 : return;
233 :
234 : /* If FROM is a SUBREG that indicates that we have already done at least
235 : the required extension, strip it. We don't handle such SUBREGs as
236 : TO here. */
237 :
238 2152874 : scalar_int_mode to_int_mode;
239 2152874 : if (GET_CODE (from) == SUBREG
240 177988 : && SUBREG_PROMOTED_VAR_P (from)
241 2152874 : && is_a <scalar_int_mode> (to_mode, &to_int_mode)
242 2152874 : && (GET_MODE_PRECISION (subreg_promoted_mode (from))
243 0 : >= GET_MODE_PRECISION (to_int_mode))
244 2152874 : && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
245 : {
246 0 : scalar_int_mode int_orig_mode;
247 0 : scalar_int_mode int_inner_mode;
248 0 : machine_mode orig_mode = GET_MODE (from);
249 :
250 0 : from = gen_lowpart (to_int_mode, SUBREG_REG (from));
251 0 : from_mode = to_int_mode;
252 :
253 : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
254 : the original mode, but narrower than the inner mode. */
255 0 : if (GET_CODE (from) == SUBREG
256 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
257 0 : && GET_MODE_PRECISION (to_int_mode)
258 0 : > GET_MODE_PRECISION (int_orig_mode)
259 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
260 : &int_inner_mode)
261 0 : && GET_MODE_PRECISION (int_inner_mode)
262 0 : > GET_MODE_PRECISION (to_int_mode))
263 : {
264 0 : SUBREG_PROMOTED_VAR_P (from) = 1;
265 0 : SUBREG_PROMOTED_SET (from, unsignedp);
266 : }
267 : }
268 :
269 2152874 : gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
270 :
271 2152874 : if (to_mode == from_mode
272 2105893 : || (from_mode == VOIDmode && CONSTANT_P (from)))
273 : {
274 47252 : emit_move_insn (to, from);
275 47252 : return;
276 : }
277 :
278 2105622 : if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
279 : {
280 30046 : if (GET_MODE_UNIT_PRECISION (to_mode)
281 15023 : > GET_MODE_UNIT_PRECISION (from_mode))
282 : {
283 4607 : optab op = unsignedp ? zext_optab : sext_optab;
284 4607 : insn_code icode = convert_optab_handler (op, to_mode, from_mode);
285 4607 : if (icode != CODE_FOR_nothing)
286 : {
287 777 : emit_unop_insn (icode, to, from,
288 : unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
289 777 : return;
290 : }
291 : }
292 :
293 28492 : if (GET_MODE_UNIT_PRECISION (to_mode)
294 14246 : < GET_MODE_UNIT_PRECISION (from_mode))
295 : {
296 2381 : insn_code icode = convert_optab_handler (trunc_optab,
297 : to_mode, from_mode);
298 2381 : if (icode != CODE_FOR_nothing)
299 : {
300 880 : emit_unop_insn (icode, to, from, TRUNCATE);
301 880 : return;
302 : }
303 : }
304 :
305 40098 : gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
306 : GET_MODE_BITSIZE (to_mode)));
307 :
308 13366 : if (VECTOR_MODE_P (to_mode))
309 13366 : from = force_subreg (to_mode, from, GET_MODE (from), 0);
310 : else
311 0 : to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
312 :
313 13366 : emit_move_insn (to, from);
314 13366 : return;
315 : }
316 :
317 2090599 : if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
318 : {
319 0 : convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
320 0 : convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
321 0 : return;
322 : }
323 :
324 2090599 : convert_mode_scalar (to, from, unsignedp);
325 : }
326 :
327 : /* Like convert_move, but deals only with scalar modes. */
328 :
329 : static void
330 2090661 : convert_mode_scalar (rtx to, rtx from, int unsignedp)
331 : {
332 : /* Both modes should be scalar types. */
333 2090666 : scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
334 2090666 : scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
335 2090666 : bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
336 2090666 : bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
337 2090666 : enum insn_code code;
338 2090666 : rtx libcall;
339 :
340 2090666 : gcc_assert (to_real == from_real);
341 :
342 : /* rtx code for making an equivalent value. */
343 3193193 : enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
344 2090666 : : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
345 :
346 2090666 : auto acceptable_same_precision_modes
347 580 : = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
348 : {
349 580 : if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
350 : return true;
351 :
352 : /* arm_bfloat_half_format <-> ieee_half_format */
353 2 : if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
354 1 : && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
355 2 : || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
356 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
357 : return true;
358 :
359 : /* ibm_extended_format <-> ieee_quad_format */
360 0 : if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
361 0 : && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
362 0 : || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
363 0 : && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
364 0 : return true;
365 :
366 : return false;
367 : };
368 :
369 2090666 : if (to_real)
370 : {
371 186182 : rtx value;
372 186182 : rtx_insn *insns;
373 186182 : convert_optab tab;
374 :
375 186182 : gcc_assert ((GET_MODE_PRECISION (from_mode)
376 : != GET_MODE_PRECISION (to_mode))
377 : || acceptable_same_precision_modes (from_mode, to_mode));
378 :
379 186182 : if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
380 : {
381 580 : if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
382 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
383 580 : || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
384 0 : && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
385 : /* libgcc implements just __trunchfbf2, not __extendhfbf2;
386 : and __trunctfkf2, not __extendtfkf2. */
387 : tab = trunc_optab;
388 : else
389 : /* Conversion between decimal float and binary float, same
390 : size. */
391 579 : tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
392 : }
393 185602 : else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
394 : tab = sext_optab;
395 : else
396 18584 : tab = trunc_optab;
397 :
398 : /* Try converting directly if the insn is supported. */
399 :
400 186182 : code = convert_optab_handler (tab, to_mode, from_mode);
401 186182 : if (code != CODE_FOR_nothing)
402 : {
403 160976 : emit_unop_insn (code, to, from,
404 : tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
405 160976 : return;
406 : }
407 :
408 : #ifdef HAVE_SFmode
409 25206 : if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
410 25206 : && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
411 : {
412 2462 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
413 : {
414 : /* To cut down on libgcc size, implement
415 : BFmode -> {DF,XF,TF}mode conversions by
416 : BFmode -> SFmode -> {DF,XF,TF}mode conversions. */
417 4 : rtx temp = gen_reg_rtx (SFmode);
418 4 : convert_mode_scalar (temp, from, unsignedp);
419 4 : convert_mode_scalar (to, temp, unsignedp);
420 4 : return;
421 : }
422 2458 : if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
423 : {
424 : /* Similarly, implement BFmode -> HFmode as
425 : BFmode -> SFmode -> HFmode conversion where SFmode
426 : has superset of BFmode values. We don't need
427 : to handle sNaNs by raising exception and turning
428 : it into qNaN though, as that can be done in the
429 : SFmode -> HFmode conversion too. */
430 1 : rtx temp = gen_reg_rtx (SFmode);
431 1 : int save_flag_finite_math_only = flag_finite_math_only;
432 1 : flag_finite_math_only = true;
433 1 : convert_mode_scalar (temp, from, unsignedp);
434 1 : flag_finite_math_only = save_flag_finite_math_only;
435 1 : convert_mode_scalar (to, temp, unsignedp);
436 1 : return;
437 : }
438 2457 : if (to_mode == SFmode
439 2457 : && !HONOR_NANS (from_mode)
440 58 : && !HONOR_NANS (to_mode)
441 2515 : && optimize_insn_for_speed_p ())
442 : {
443 : /* If we don't expect sNaNs, for BFmode -> SFmode we can just
444 : shift the bits up. */
445 57 : machine_mode fromi_mode, toi_mode;
446 114 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
447 57 : 0).exists (&fromi_mode)
448 57 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
449 0 : 0).exists (&toi_mode))
450 : {
451 57 : start_sequence ();
452 57 : rtx fromi = force_lowpart_subreg (fromi_mode, from,
453 : from_mode);
454 57 : rtx tof = NULL_RTX;
455 57 : if (fromi)
456 : {
457 57 : rtx toi;
458 57 : if (GET_MODE (fromi) == VOIDmode)
459 0 : toi = simplify_unary_operation (ZERO_EXTEND, toi_mode,
460 : fromi, fromi_mode);
461 : else
462 : {
463 57 : toi = gen_reg_rtx (toi_mode);
464 57 : convert_mode_scalar (toi, fromi, 1);
465 : }
466 57 : toi
467 114 : = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
468 57 : GET_MODE_PRECISION (to_mode)
469 57 : - GET_MODE_PRECISION (from_mode),
470 : NULL_RTX, 1);
471 57 : if (toi)
472 : {
473 57 : tof = force_lowpart_subreg (to_mode, toi, toi_mode);
474 57 : if (tof)
475 57 : emit_move_insn (to, tof);
476 : }
477 : }
478 57 : insns = end_sequence ();
479 57 : if (tof)
480 : {
481 57 : emit_insn (insns);
482 57 : return;
483 : }
484 : }
485 : }
486 : }
487 25144 : if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
488 4274 : && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
489 1572 : && !HONOR_NANS (from_mode)
490 0 : && !HONOR_NANS (to_mode)
491 0 : && !flag_rounding_math
492 25144 : && optimize_insn_for_speed_p ())
493 : {
494 : /* If we don't expect qNaNs nor sNaNs and can assume rounding
495 : to nearest, we can expand the conversion inline as
496 : (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16. */
497 0 : machine_mode fromi_mode, toi_mode;
498 0 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
499 0 : 0).exists (&fromi_mode)
500 0 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
501 0 : 0).exists (&toi_mode))
502 : {
503 0 : start_sequence ();
504 0 : rtx fromi = force_lowpart_subreg (fromi_mode, from, from_mode);
505 0 : rtx tof = NULL_RTX;
506 0 : do
507 : {
508 0 : if (!fromi)
509 : break;
510 0 : int shift = (GET_MODE_PRECISION (from_mode)
511 0 : - GET_MODE_PRECISION (to_mode));
512 0 : rtx temp1
513 0 : = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
514 : shift, NULL_RTX, 1);
515 0 : if (!temp1)
516 : break;
517 0 : rtx temp2
518 0 : = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
519 : NULL_RTX, 1, OPTAB_DIRECT);
520 0 : if (!temp2)
521 : break;
522 0 : rtx temp3
523 0 : = expand_binop (fromi_mode, add_optab, fromi,
524 : gen_int_mode ((HOST_WIDE_INT_1U
525 0 : << (shift - 1)) - 1,
526 : fromi_mode), NULL_RTX,
527 : 1, OPTAB_DIRECT);
528 0 : if (!temp3)
529 : break;
530 0 : rtx temp4
531 0 : = expand_binop (fromi_mode, add_optab, temp3, temp2,
532 : NULL_RTX, 1, OPTAB_DIRECT);
533 0 : if (!temp4)
534 : break;
535 0 : rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
536 : temp4, shift, NULL_RTX, 1);
537 0 : if (!temp5)
538 : break;
539 0 : rtx temp6 = force_lowpart_subreg (toi_mode, temp5,
540 : fromi_mode);
541 0 : if (!temp6)
542 : break;
543 0 : tof = force_lowpart_subreg (to_mode, temp6, toi_mode);
544 0 : if (tof)
545 0 : emit_move_insn (to, tof);
546 : }
547 : while (0);
548 0 : insns = end_sequence ();
549 0 : if (tof)
550 : {
551 0 : emit_insn (insns);
552 0 : return;
553 : }
554 : }
555 : }
556 : #endif
557 :
558 : /* Otherwise use a libcall. */
559 25144 : libcall = convert_optab_libfunc (tab, to_mode, from_mode);
560 :
561 : /* Is this conversion implemented yet? */
562 25144 : gcc_assert (libcall);
563 :
564 25144 : start_sequence ();
565 25144 : value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
566 : from, from_mode);
567 25144 : insns = end_sequence ();
568 25144 : emit_libcall_block (insns, to, value,
569 6795 : tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
570 : from)
571 18349 : : gen_rtx_FLOAT_EXTEND (to_mode, from));
572 25144 : return;
573 : }
574 :
575 : /* Handle pointer conversion. */ /* SPEE 900220. */
576 : /* If the target has a converter from FROM_MODE to TO_MODE, use it. */
577 1904484 : {
578 1904484 : convert_optab ctab;
579 :
580 1904484 : if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
581 : ctab = trunc_optab;
582 1711972 : else if (unsignedp)
583 : ctab = zext_optab;
584 : else
585 831090 : ctab = sext_optab;
586 :
587 1904484 : if (convert_optab_handler (ctab, to_mode, from_mode)
588 : != CODE_FOR_nothing)
589 : {
590 1641493 : emit_unop_insn (convert_optab_handler (ctab, to_mode, from_mode),
591 : to, from, UNKNOWN);
592 1641493 : return;
593 : }
594 : }
595 :
596 : /* Targets are expected to provide conversion insns between PxImode and
597 : xImode for all MODE_PARTIAL_INT modes they use, but no others. */
598 262991 : if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
599 : {
600 0 : scalar_int_mode full_mode
601 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (to_mode)).require ();
602 :
603 0 : gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
604 : != CODE_FOR_nothing);
605 :
606 0 : if (full_mode != from_mode)
607 0 : from = convert_to_mode (full_mode, from, unsignedp);
608 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, full_mode),
609 : to, from, UNKNOWN);
610 0 : return;
611 : }
612 262991 : if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
613 : {
614 0 : rtx new_from;
615 0 : scalar_int_mode full_mode
616 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (from_mode)).require ();
617 0 : convert_optab ctab = unsignedp ? zext_optab : sext_optab;
618 0 : enum insn_code icode;
619 :
620 0 : icode = convert_optab_handler (ctab, full_mode, from_mode);
621 0 : gcc_assert (icode != CODE_FOR_nothing);
622 :
623 0 : if (to_mode == full_mode)
624 : {
625 0 : emit_unop_insn (icode, to, from, UNKNOWN);
626 0 : return;
627 : }
628 :
629 0 : new_from = gen_reg_rtx (full_mode);
630 0 : emit_unop_insn (icode, new_from, from, UNKNOWN);
631 :
632 : /* else proceed to integer conversions below. */
633 0 : from_mode = full_mode;
634 0 : from = new_from;
635 : }
636 :
637 : /* Make sure both are fixed-point modes or both are not. */
638 262991 : gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
639 : ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
640 262991 : if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
641 : {
642 : /* If we widen from_mode to to_mode and they are in the same class,
643 : we won't saturate the result.
644 : Otherwise, always saturate the result to play safe. */
645 0 : if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
646 0 : && GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
647 0 : expand_fixed_convert (to, from, 0, 0);
648 : else
649 0 : expand_fixed_convert (to, from, 0, 1);
650 0 : return;
651 : }
652 :
653 : /* Now both modes are integers. */
654 :
655 : /* Handle expanding beyond a word. */
656 262991 : if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)
657 265425 : && GET_MODE_PRECISION (to_mode) > BITS_PER_WORD)
658 : {
659 70479 : rtx_insn *insns;
660 70479 : rtx lowpart;
661 70479 : rtx fill_value;
662 70479 : rtx lowfrom;
663 70479 : int i;
664 70479 : scalar_mode lowpart_mode;
665 140958 : int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
666 :
667 : /* Try converting directly if the insn is supported. */
668 70479 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
669 : != CODE_FOR_nothing)
670 : {
671 : /* If FROM is a SUBREG, put it into a register. Do this
672 : so that we always generate the same set of insns for
673 : better cse'ing; if an intermediate assignment occurred,
674 : we won't be doing the operation directly on the SUBREG. */
675 0 : if (optimize > 0 && GET_CODE (from) == SUBREG)
676 0 : from = force_reg (from_mode, from);
677 0 : emit_unop_insn (code, to, from, equiv_code);
678 0 : return;
679 : }
680 : /* Next, try converting via full word. */
681 70479 : else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD
682 70479 : && ((code = can_extend_p (to_mode, word_mode, unsignedp))
683 : != CODE_FOR_nothing))
684 : {
685 70479 : rtx word_to = gen_reg_rtx (word_mode);
686 70479 : if (REG_P (to))
687 : {
688 70406 : if (reg_overlap_mentioned_p (to, from))
689 0 : from = force_reg (from_mode, from);
690 70406 : emit_clobber (to);
691 : }
692 70479 : convert_move (word_to, from, unsignedp);
693 70479 : emit_unop_insn (code, to, word_to, equiv_code);
694 70479 : return;
695 : }
696 :
697 : /* No special multiword conversion insn; do it by hand. */
698 0 : start_sequence ();
699 :
700 : /* Since we will turn this into a no conflict block, we must ensure
701 : the source does not overlap the target so force it into an isolated
702 : register when maybe so. Likewise for any MEM input, since the
703 : conversion sequence might require several references to it and we
704 : must ensure we're getting the same value every time. */
705 :
706 0 : if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
707 0 : from = force_reg (from_mode, from);
708 :
709 : /* Get a copy of FROM widened to a word, if necessary. */
710 0 : if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD)
711 0 : lowpart_mode = word_mode;
712 : else
713 : lowpart_mode = from_mode;
714 :
715 0 : lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
716 :
717 0 : lowpart = gen_lowpart (lowpart_mode, to);
718 0 : emit_move_insn (lowpart, lowfrom);
719 :
720 : /* Compute the value to put in each remaining word. */
721 0 : if (unsignedp)
722 0 : fill_value = const0_rtx;
723 : else
724 0 : fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
725 : LT, lowfrom, const0_rtx,
726 : lowpart_mode, 0, -1);
727 :
728 : /* Fill the remaining words. */
729 0 : for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
730 : {
731 0 : int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
732 0 : rtx subword = operand_subword (to, index, 1, to_mode);
733 :
734 0 : gcc_assert (subword);
735 :
736 0 : if (fill_value != subword)
737 0 : emit_move_insn (subword, fill_value);
738 : }
739 :
740 0 : insns = end_sequence ();
741 :
742 0 : emit_insn (insns);
743 0 : return;
744 : }
745 :
746 : /* Truncating multi-word to a word or less. */
747 192512 : if (GET_MODE_PRECISION (from_mode) > BITS_PER_WORD
748 192512 : && GET_MODE_PRECISION (to_mode) <= BITS_PER_WORD)
749 : {
750 69210 : if (!((MEM_P (from)
751 568 : && ! MEM_VOLATILE_P (from)
752 568 : && direct_load[(int) to_mode]
753 568 : && ! mode_dependent_address_p (XEXP (from, 0),
754 568 : MEM_ADDR_SPACE (from)))
755 38951 : || REG_P (from)
756 : || GET_CODE (from) == SUBREG))
757 0 : from = force_reg (from_mode, from);
758 39519 : convert_move (to, gen_lowpart (word_mode, from), 0);
759 39519 : return;
760 : }
761 :
762 : /* Now follow all the conversions between integers
763 : no more than a word long. */
764 :
765 : /* For truncation, usually we can just refer to FROM in a narrower mode. */
766 305986 : if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
767 152993 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
768 : {
769 164802 : if (!((MEM_P (from)
770 13867 : && ! MEM_VOLATILE_P (from)
771 13808 : && direct_load[(int) to_mode]
772 13808 : && ! mode_dependent_address_p (XEXP (from, 0),
773 13808 : MEM_ADDR_SPACE (from)))
774 139185 : || REG_P (from)
775 : || GET_CODE (from) == SUBREG))
776 925 : from = force_reg (from_mode, from);
777 128301 : if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
778 152994 : && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
779 0 : from = copy_to_reg (from);
780 152993 : emit_move_insn (to, gen_lowpart (to_mode, from));
781 152993 : return;
782 : }
783 :
784 : /* Handle extension. */
785 0 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode))
786 : {
787 : /* Convert directly if that works. */
788 0 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
789 : != CODE_FOR_nothing)
790 : {
791 0 : emit_unop_insn (code, to, from, equiv_code);
792 0 : return;
793 : }
794 : else
795 : {
796 0 : rtx tmp;
797 0 : int shift_amount;
798 :
799 : /* Search for a mode to convert via. */
800 0 : opt_scalar_mode intermediate_iter;
801 0 : FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
802 : {
803 0 : scalar_mode intermediate = intermediate_iter.require ();
804 0 : if (((can_extend_p (to_mode, intermediate, unsignedp)
805 : != CODE_FOR_nothing)
806 0 : || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
807 0 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
808 : intermediate)))
809 0 : && (can_extend_p (intermediate, from_mode, unsignedp)
810 : != CODE_FOR_nothing))
811 : {
812 0 : convert_move (to, convert_to_mode (intermediate, from,
813 : unsignedp), unsignedp);
814 0 : return;
815 : }
816 : }
817 :
818 : /* No suitable intermediate mode.
819 : Generate what we need with shifts. */
820 0 : shift_amount = (GET_MODE_PRECISION (to_mode)
821 0 : - GET_MODE_PRECISION (from_mode));
822 0 : from = gen_lowpart (to_mode, force_reg (from_mode, from));
823 0 : tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
824 : to, unsignedp);
825 0 : tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
826 : to, unsignedp);
827 0 : if (tmp != to)
828 0 : emit_move_insn (to, tmp);
829 0 : return;
830 : }
831 : }
832 :
833 : /* Support special truncate insns for certain modes. */
834 0 : if (convert_optab_handler (trunc_optab, to_mode,
835 : from_mode) != CODE_FOR_nothing)
836 : {
837 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, from_mode),
838 : to, from, UNKNOWN);
839 0 : return;
840 : }
841 :
842 : /* Handle truncation of volatile memrefs, and so on;
843 : the things that couldn't be truncated directly,
844 : and for which there was no special instruction.
845 :
846 : ??? Code above formerly short-circuited this, for most integer
847 : mode pairs, with a force_reg in from_mode followed by a recursive
848 : call to this routine. Appears always to have been wrong. */
849 0 : if (GET_MODE_PRECISION (to_mode) < GET_MODE_PRECISION (from_mode))
850 : {
851 0 : rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
852 0 : emit_move_insn (to, temp);
853 0 : return;
854 : }
855 :
856 : /* Mode combination is not recognized. */
857 0 : gcc_unreachable ();
858 : }
859 :
860 : /* Return an rtx for a value that would result
861 : from converting X to mode MODE.
862 : Both X and MODE may be floating, or both integer.
863 : UNSIGNEDP is nonzero if X is an unsigned value.
864 : This can be done by referring to a part of X in place
865 : or by copying to a new temporary with conversion. */
866 :
867 : rtx
868 2011989 : convert_to_mode (machine_mode mode, rtx x, int unsignedp)
869 : {
870 2011989 : return convert_modes (mode, VOIDmode, x, unsignedp);
871 : }
872 :
873 : /* Return an rtx for a value that would result
874 : from converting X from mode OLDMODE to mode MODE.
875 : Both modes may be floating, or both integer.
876 : UNSIGNEDP is nonzero if X is an unsigned value.
877 :
878 : This can be done by referring to a part of X in place
879 : or by copying to a new temporary with conversion.
880 :
881 : You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode. */
882 :
883 : rtx
884 4835227 : convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
885 : {
886 4835227 : rtx temp;
887 4835227 : scalar_int_mode int_mode;
888 :
889 : /* If FROM is a SUBREG that indicates that we have already done at least
890 : the required extension, strip it. */
891 :
892 4835227 : if (GET_CODE (x) == SUBREG
893 140253 : && SUBREG_PROMOTED_VAR_P (x)
894 4835227 : && is_a <scalar_int_mode> (mode, &int_mode)
895 4835227 : && (GET_MODE_PRECISION (subreg_promoted_mode (x))
896 7 : >= GET_MODE_PRECISION (int_mode))
897 4835234 : && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
898 : {
899 7 : scalar_int_mode int_orig_mode;
900 7 : scalar_int_mode int_inner_mode;
901 7 : machine_mode orig_mode = GET_MODE (x);
902 7 : x = gen_lowpart (int_mode, SUBREG_REG (x));
903 :
904 : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
905 : the original mode, but narrower than the inner mode. */
906 7 : if (GET_CODE (x) == SUBREG
907 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
908 0 : && GET_MODE_PRECISION (int_mode)
909 0 : > GET_MODE_PRECISION (int_orig_mode)
910 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
911 : &int_inner_mode)
912 7 : && GET_MODE_PRECISION (int_inner_mode)
913 0 : > GET_MODE_PRECISION (int_mode))
914 : {
915 0 : SUBREG_PROMOTED_VAR_P (x) = 1;
916 0 : SUBREG_PROMOTED_SET (x, unsignedp);
917 : }
918 : }
919 :
920 4835227 : if (GET_MODE (x) != VOIDmode)
921 2498767 : oldmode = GET_MODE (x);
922 :
923 4835227 : if (mode == oldmode)
924 : return x;
925 :
926 3771640 : if (CONST_SCALAR_INT_P (x)
927 3771640 : && is_a <scalar_int_mode> (mode, &int_mode))
928 : {
929 : /* If the caller did not tell us the old mode, then there is not
930 : much to do with respect to canonicalization. We have to
931 : assume that all the bits are significant. */
932 2015919 : if (!is_a <scalar_int_mode> (oldmode))
933 1690117 : oldmode = MAX_MODE_INT;
934 2015919 : wide_int w = wide_int::from (rtx_mode_t (x, oldmode),
935 2015919 : GET_MODE_PRECISION (int_mode),
936 2662612 : unsignedp ? UNSIGNED : SIGNED);
937 2015919 : return immed_wide_int_const (w, int_mode);
938 2015919 : }
939 :
940 : /* We can do this with a gen_lowpart if both desired and current modes
941 : are integer, and this is either a constant integer, a register, or a
942 : non-volatile MEM. */
943 1755721 : scalar_int_mode int_oldmode;
944 1755721 : if (is_int_mode (mode, &int_mode)
945 1662635 : && is_int_mode (oldmode, &int_oldmode)
946 1662635 : && GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (int_oldmode)
947 460064 : && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
948 12210 : || CONST_POLY_INT_P (x)
949 447854 : || (REG_P (x)
950 412163 : && (!HARD_REGISTER_P (x)
951 1068 : || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
952 412163 : && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
953 424373 : return gen_lowpart (int_mode, x);
954 :
955 : /* Converting from integer constant into mode is always equivalent to an
956 : subreg operation. */
957 1331348 : if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
958 : {
959 0 : gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
960 : GET_MODE_BITSIZE (oldmode)));
961 0 : return force_subreg (mode, x, oldmode, 0);
962 : }
963 :
964 1331348 : temp = gen_reg_rtx (mode);
965 1331348 : convert_move (temp, x, unsignedp);
966 1331348 : return temp;
967 : }
968 :
969 : /* Variant of convert_modes for ABI parameter passing/return.
970 : Return an rtx for a value that would result from converting X from
971 : a floating point mode FMODE to wider integer mode MODE. */
972 :
973 : rtx
974 0 : convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
975 : {
976 0 : gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
977 0 : scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
978 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
979 0 : return convert_modes (mode, tmp_mode, tmp, 1);
980 : }
981 :
982 : /* Variant of convert_modes for ABI parameter passing/return.
983 : Return an rtx for a value that would result from converting X from
984 : an integer mode IMODE to a narrower floating point mode MODE. */
985 :
986 : rtx
987 0 : convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
988 : {
989 0 : gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
990 0 : scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
991 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
992 0 : return gen_lowpart_SUBREG (mode, tmp);
993 : }
994 :
995 : /* Return the largest alignment we can use for doing a move (or store)
996 : of MAX_PIECES. ALIGN is the largest alignment we could use. */
997 :
998 : static unsigned int
999 2769019 : alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
1000 : {
1001 2769019 : scalar_int_mode tmode
1002 2769019 : = int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
1003 :
1004 2769019 : if (align >= GET_MODE_ALIGNMENT (tmode))
1005 2186052 : align = GET_MODE_ALIGNMENT (tmode);
1006 : else
1007 : {
1008 582967 : scalar_int_mode xmode = NARROWEST_INT_MODE;
1009 582967 : opt_scalar_int_mode mode_iter;
1010 3513863 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
1011 : {
1012 3508203 : tmode = mode_iter.require ();
1013 3508203 : if (GET_MODE_SIZE (tmode) > max_pieces
1014 3508203 : || targetm.slow_unaligned_access (tmode, align))
1015 : break;
1016 2930896 : xmode = tmode;
1017 : }
1018 :
1019 582967 : align = MAX (align, GET_MODE_ALIGNMENT (xmode));
1020 : }
1021 :
1022 2769019 : return align;
1023 : }
1024 :
1025 : /* Return true if we know how to implement OP using vectors of bytes. */
1026 : static bool
1027 5855472 : can_use_qi_vectors (by_pieces_operation op)
1028 : {
1029 5855472 : return (op == COMPARE_BY_PIECES
1030 0 : || op == SET_BY_PIECES
1031 0 : || op == CLEAR_BY_PIECES);
1032 : }
1033 :
1034 : /* Return true if optabs exists for the mode and certain by pieces
1035 : operations. */
1036 : static bool
1037 25937857 : by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
1038 : {
1039 25937857 : if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
1040 : return false;
1041 :
1042 24579534 : if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
1043 688307 : && VECTOR_MODE_P (mode)
1044 25071823 : && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
1045 : return false;
1046 :
1047 24530926 : if (op == COMPARE_BY_PIECES
1048 24530926 : && !can_compare_p (EQ, mode, ccp_jump))
1049 : return false;
1050 :
1051 : return true;
1052 : }
1053 :
1054 : /* Return the widest mode that can be used to perform part of an
1055 : operation OP on SIZE bytes. Try to use QI vector modes where
1056 : possible. */
1057 : static fixed_size_mode
1058 5362533 : widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
1059 : {
1060 5362533 : fixed_size_mode result = NARROWEST_INT_MODE;
1061 :
1062 5362533 : gcc_checking_assert (size > 1);
1063 :
1064 : /* Use QI vector only if size is wider than a WORD. */
1065 5362533 : if (can_use_qi_vectors (op))
1066 : {
1067 728600 : machine_mode mode;
1068 728600 : fixed_size_mode candidate;
1069 12023471 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1070 12023471 : if (is_a<fixed_size_mode> (mode, &candidate)
1071 13129304 : && GET_MODE_SIZE (candidate) > UNITS_PER_WORD
1072 12938214 : && GET_MODE_INNER (candidate) == QImode)
1073 : {
1074 5661740 : if (GET_MODE_SIZE (candidate) >= size)
1075 : break;
1076 2102270 : if (by_pieces_mode_supported_p (candidate, op))
1077 11294871 : result = candidate;
1078 : }
1079 :
1080 728600 : if (result != NARROWEST_INT_MODE)
1081 471065 : return result;
1082 : }
1083 :
1084 4891468 : opt_scalar_int_mode tmode;
1085 4891468 : scalar_int_mode mode;
1086 39131744 : FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
1087 : {
1088 34240276 : mode = tmode.require ();
1089 34240276 : if (GET_MODE_SIZE (mode) < size
1090 34240276 : && by_pieces_mode_supported_p (mode, op))
1091 23794006 : result = mode;
1092 : }
1093 :
1094 4891468 : return result;
1095 : }
1096 :
1097 : /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
1098 : and should be performed piecewise. */
1099 :
1100 : static bool
1101 967087 : can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
1102 : enum by_pieces_operation op)
1103 : {
1104 967087 : return targetm.use_by_pieces_infrastructure_p (len, align, op,
1105 967087 : optimize_insn_for_speed_p ());
1106 : }
1107 :
1108 : /* Determine whether the LEN bytes can be moved by using several move
1109 : instructions. Return nonzero if a call to move_by_pieces should
1110 : succeed. */
1111 :
1112 : bool
1113 897616 : can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
1114 : {
1115 897616 : return can_do_by_pieces (len, align, MOVE_BY_PIECES);
1116 : }
1117 :
1118 : /* Return number of insns required to perform operation OP by pieces
1119 : for L bytes. ALIGN (in bits) is maximum alignment we can assume. */
1120 :
1121 : unsigned HOST_WIDE_INT
1122 1958051 : by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
1123 : unsigned int max_size, by_pieces_operation op)
1124 : {
1125 1958051 : unsigned HOST_WIDE_INT n_insns = 0;
1126 1958051 : fixed_size_mode mode;
1127 :
1128 1958051 : if (targetm.overlap_op_by_pieces_p ())
1129 : {
1130 : /* NB: Round up L and ALIGN to the widest integer mode for
1131 : MAX_SIZE. */
1132 1958051 : mode = widest_fixed_size_mode_for_size (max_size, op);
1133 1958051 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1134 3916102 : unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
1135 1958051 : if (up > l)
1136 : l = up;
1137 1958051 : align = GET_MODE_ALIGNMENT (mode);
1138 : }
1139 :
1140 1958051 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1141 :
1142 5882141 : while (max_size > 1 && l > 0)
1143 : {
1144 1966039 : mode = widest_fixed_size_mode_for_size (max_size, op);
1145 1966039 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1146 :
1147 1966039 : unsigned int modesize = GET_MODE_SIZE (mode);
1148 :
1149 1966039 : if (align >= GET_MODE_ALIGNMENT (mode))
1150 : {
1151 1966039 : unsigned HOST_WIDE_INT n_pieces = l / modesize;
1152 1966039 : l %= modesize;
1153 1966039 : switch (op)
1154 : {
1155 1896568 : default:
1156 1896568 : n_insns += n_pieces;
1157 1896568 : break;
1158 :
1159 69471 : case COMPARE_BY_PIECES:
1160 69471 : int batch = targetm.compare_by_pieces_branch_ratio (mode);
1161 69471 : int batch_ops = 4 * batch - 1;
1162 69471 : unsigned HOST_WIDE_INT full = n_pieces / batch;
1163 69471 : n_insns += full * batch_ops;
1164 69471 : if (n_pieces % batch != 0)
1165 0 : n_insns++;
1166 : break;
1167 :
1168 : }
1169 : }
1170 : max_size = modesize;
1171 : }
1172 :
1173 1958051 : gcc_assert (!l);
1174 1958051 : return n_insns;
1175 : }
1176 :
1177 : /* Used when performing piecewise block operations, holds information
1178 : about one of the memory objects involved. The member functions
1179 : can be used to generate code for loading from the object and
1180 : updating the address when iterating. */
1181 :
1182 : class pieces_addr
1183 : {
1184 : /* The object being referenced, a MEM. Can be NULL_RTX to indicate
1185 : stack pushes. */
1186 : rtx m_obj;
1187 : /* The address of the object. Can differ from that seen in the
1188 : MEM rtx if we copied the address to a register. */
1189 : rtx m_addr;
1190 : /* Nonzero if the address on the object has an autoincrement already,
1191 : signifies whether that was an increment or decrement. */
1192 : signed char m_addr_inc;
1193 : /* Nonzero if we intend to use autoinc without the address already
1194 : having autoinc form. We will insert add insns around each memory
1195 : reference, expecting later passes to form autoinc addressing modes.
1196 : The only supported options are predecrement and postincrement. */
1197 : signed char m_explicit_inc;
1198 : /* True if we have either of the two possible cases of using
1199 : autoincrement. */
1200 : bool m_auto;
1201 : /* True if this is an address to be used for load operations rather
1202 : than stores. */
1203 : bool m_is_load;
1204 :
1205 : /* Optionally, a function to obtain constants for any given offset into
1206 : the objects, and data associated with it. */
1207 : by_pieces_constfn m_constfn;
1208 : void *m_cfndata;
1209 : public:
1210 : pieces_addr (rtx, bool, by_pieces_constfn, void *);
1211 : rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
1212 : void increment_address (HOST_WIDE_INT);
1213 : void maybe_predec (HOST_WIDE_INT);
1214 : void maybe_postinc (HOST_WIDE_INT);
1215 : void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
1216 757492 : int get_addr_inc ()
1217 : {
1218 757492 : return m_addr_inc;
1219 : }
1220 : };
1221 :
1222 : /* Initialize a pieces_addr structure from an object OBJ. IS_LOAD is
1223 : true if the operation to be performed on this object is a load
1224 : rather than a store. For stores, OBJ can be NULL, in which case we
1225 : assume the operation is a stack push. For loads, the optional
1226 : CONSTFN and its associated CFNDATA can be used in place of the
1227 : memory load. */
1228 :
1229 1514984 : pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
1230 1514984 : void *cfndata)
1231 1514984 : : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
1232 : {
1233 1514984 : m_addr_inc = 0;
1234 1514984 : m_auto = false;
1235 1514984 : if (obj)
1236 : {
1237 1390470 : rtx addr = XEXP (obj, 0);
1238 1390470 : rtx_code code = GET_CODE (addr);
1239 1390470 : m_addr = addr;
1240 1390470 : bool dec = code == PRE_DEC || code == POST_DEC;
1241 1390470 : bool inc = code == PRE_INC || code == POST_INC;
1242 1390470 : m_auto = inc || dec;
1243 1390470 : if (m_auto)
1244 0 : m_addr_inc = dec ? -1 : 1;
1245 :
1246 : /* While we have always looked for these codes here, the code
1247 : implementing the memory operation has never handled them.
1248 : Support could be added later if necessary or beneficial. */
1249 1390470 : gcc_assert (code != PRE_INC && code != POST_DEC);
1250 : }
1251 : else
1252 : {
1253 124514 : m_addr = NULL_RTX;
1254 124514 : if (!is_load)
1255 : {
1256 45 : m_auto = true;
1257 45 : if (STACK_GROWS_DOWNWARD)
1258 45 : m_addr_inc = -1;
1259 : else
1260 : m_addr_inc = 1;
1261 : }
1262 : else
1263 124469 : gcc_assert (constfn != NULL);
1264 : }
1265 1514984 : m_explicit_inc = 0;
1266 1514984 : if (constfn)
1267 150568 : gcc_assert (is_load);
1268 1514984 : }
1269 :
1270 : /* Decide whether to use autoinc for an address involved in a memory op.
1271 : MODE is the mode of the accesses, REVERSE is true if we've decided to
1272 : perform the operation starting from the end, and LEN is the length of
1273 : the operation. Don't override an earlier decision to set m_auto. */
1274 :
1275 : void
1276 375228 : pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
1277 : HOST_WIDE_INT len)
1278 : {
1279 375228 : if (m_auto || m_obj == NULL_RTX)
1280 : return;
1281 :
1282 344303 : bool use_predec = (m_is_load
1283 : ? USE_LOAD_PRE_DECREMENT (mode)
1284 : : USE_STORE_PRE_DECREMENT (mode));
1285 344303 : bool use_postinc = (m_is_load
1286 : ? USE_LOAD_POST_INCREMENT (mode)
1287 : : USE_STORE_POST_INCREMENT (mode));
1288 344303 : machine_mode addr_mode = get_address_mode (m_obj);
1289 :
1290 344303 : if (use_predec && reverse)
1291 : {
1292 : m_addr = copy_to_mode_reg (addr_mode,
1293 : plus_constant (addr_mode,
1294 : m_addr, len));
1295 : m_auto = true;
1296 : m_explicit_inc = -1;
1297 : }
1298 344303 : else if (use_postinc && !reverse)
1299 : {
1300 : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1301 : m_auto = true;
1302 : m_explicit_inc = 1;
1303 : }
1304 344303 : else if (CONSTANT_P (m_addr))
1305 71838 : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1306 : }
1307 :
1308 : /* Adjust the address to refer to the data at OFFSET in MODE. If we
1309 : are using autoincrement for this address, we don't add the offset,
1310 : but we still modify the MEM's properties. */
1311 :
1312 : rtx
1313 4130343 : pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
1314 : by_pieces_prev *prev)
1315 : {
1316 4130343 : if (m_constfn)
1317 : /* Pass the previous data to m_constfn. */
1318 368078 : return m_constfn (m_cfndata, prev, offset, mode);
1319 3762265 : if (m_obj == NULL_RTX)
1320 : return NULL_RTX;
1321 3762218 : if (m_auto)
1322 0 : return adjust_automodify_address (m_obj, mode, m_addr, offset);
1323 : else
1324 3762218 : return adjust_address (m_obj, mode, offset);
1325 : }
1326 :
1327 : /* Emit an add instruction to increment the address by SIZE. */
1328 :
1329 : void
1330 0 : pieces_addr::increment_address (HOST_WIDE_INT size)
1331 : {
1332 0 : rtx amount = gen_int_mode (size, GET_MODE (m_addr));
1333 0 : emit_insn (gen_add2_insn (m_addr, amount));
1334 0 : }
1335 :
1336 : /* If we are supposed to decrement the address after each access, emit code
1337 : to do so now. Increment by SIZE (which has should have the correct sign
1338 : already). */
1339 :
1340 : void
1341 4129696 : pieces_addr::maybe_predec (HOST_WIDE_INT size)
1342 : {
1343 4129696 : if (m_explicit_inc >= 0)
1344 4129696 : return;
1345 0 : gcc_assert (HAVE_PRE_DECREMENT);
1346 : increment_address (size);
1347 : }
1348 :
1349 : /* If we are supposed to decrement the address after each access, emit code
1350 : to do so now. Increment by SIZE. */
1351 :
1352 : void
1353 4129719 : pieces_addr::maybe_postinc (HOST_WIDE_INT size)
1354 : {
1355 4129719 : if (m_explicit_inc <= 0)
1356 4129719 : return;
1357 0 : gcc_assert (HAVE_POST_INCREMENT);
1358 : increment_address (size);
1359 : }
1360 :
1361 : /* This structure is used by do_op_by_pieces to describe the operation
1362 : to be performed. */
1363 :
1364 : class op_by_pieces_d
1365 : {
1366 : private:
1367 : fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
1368 : fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
1369 :
1370 : protected:
1371 : pieces_addr m_to, m_from;
1372 : /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
1373 : use it to check the valid mode size. */
1374 : const unsigned HOST_WIDE_INT m_len;
1375 : HOST_WIDE_INT m_offset;
1376 : unsigned int m_align;
1377 : unsigned int m_max_size;
1378 : bool m_reverse;
1379 : /* True if this is a stack push. */
1380 : bool m_push;
1381 : /* True if targetm.overlap_op_by_pieces_p () returns true. */
1382 : bool m_overlap_op_by_pieces;
1383 : /* The type of operation that we're performing. */
1384 : by_pieces_operation m_op;
1385 :
1386 : /* Virtual functions, overridden by derived classes for the specific
1387 : operation. */
1388 : virtual void generate (rtx, rtx, machine_mode) = 0;
1389 : virtual bool prepare_mode (machine_mode, unsigned int) = 0;
1390 1149741 : virtual void finish_mode (machine_mode)
1391 : {
1392 1149741 : }
1393 :
1394 : public:
1395 : op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
1396 : void *, unsigned HOST_WIDE_INT, unsigned int, bool,
1397 : by_pieces_operation);
1398 : void run ();
1399 : };
1400 :
1401 : /* The constructor for an op_by_pieces_d structure. We require two
1402 : objects named TO and FROM, which are identified as loads or stores
1403 : by TO_LOAD and FROM_LOAD. If FROM is a load, the optional FROM_CFN
1404 : and its associated FROM_CFN_DATA can be used to replace loads with
1405 : constant values. MAX_PIECES describes the maximum number of bytes
1406 : at a time which can be moved efficiently. LEN describes the length
1407 : of the operation. */
1408 :
1409 757492 : op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
1410 : bool to_load, rtx from, bool from_load,
1411 : by_pieces_constfn from_cfn,
1412 : void *from_cfn_data,
1413 : unsigned HOST_WIDE_INT len,
1414 : unsigned int align, bool push,
1415 757492 : by_pieces_operation op)
1416 757492 : : m_to (to, to_load, NULL, NULL),
1417 757492 : m_from (from, from_load, from_cfn, from_cfn_data),
1418 757492 : m_len (len), m_max_size (max_pieces + 1),
1419 757492 : m_push (push), m_op (op)
1420 : {
1421 757492 : int toi = m_to.get_addr_inc ();
1422 757492 : int fromi = m_from.get_addr_inc ();
1423 757492 : if (toi >= 0 && fromi >= 0)
1424 757447 : m_reverse = false;
1425 45 : else if (toi <= 0 && fromi <= 0)
1426 45 : m_reverse = true;
1427 : else
1428 0 : gcc_unreachable ();
1429 :
1430 757492 : m_offset = m_reverse ? len : 0;
1431 2780995 : align = MIN (to ? MEM_ALIGN (to) : align,
1432 : from ? MEM_ALIGN (from) : align);
1433 :
1434 : /* If copying requires more than two move insns,
1435 : copy addresses to registers (to make displacements shorter)
1436 : and use post-increment if available. */
1437 757492 : if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
1438 : {
1439 : /* Find the mode of the largest comparison. */
1440 187614 : fixed_size_mode mode
1441 187614 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1442 :
1443 187614 : m_from.decide_autoinc (mode, m_reverse, len);
1444 187614 : m_to.decide_autoinc (mode, m_reverse, len);
1445 : }
1446 :
1447 757502 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1448 757492 : m_align = align;
1449 :
1450 757492 : m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
1451 757492 : }
1452 :
1453 : /* This function returns the largest usable integer mode for LEN bytes
1454 : whose size is no bigger than size of MODE. */
1455 :
1456 : fixed_size_mode
1457 1244242 : op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
1458 : {
1459 1543486 : unsigned int size;
1460 1842730 : do
1461 : {
1462 1543486 : size = GET_MODE_SIZE (mode);
1463 1543486 : if (len >= size && prepare_mode (mode, m_align))
1464 : break;
1465 : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1466 299244 : mode = widest_fixed_size_mode_for_size (size, m_op);
1467 : }
1468 : while (1);
1469 1244242 : return mode;
1470 : }
1471 :
1472 : /* Return the smallest integer or QI vector mode that is not narrower
1473 : than SIZE bytes. */
1474 :
1475 : fixed_size_mode
1476 492939 : op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
1477 : {
1478 : /* Use QI vector only for > size of WORD. */
1479 505166 : if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
1480 : {
1481 8177 : machine_mode mode;
1482 8177 : fixed_size_mode candidate;
1483 110621 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1484 110621 : if (is_a<fixed_size_mode> (mode, &candidate)
1485 221242 : && GET_MODE_INNER (candidate) == QImode)
1486 : {
1487 : /* Don't return a mode wider than M_LEN. */
1488 102870 : if (GET_MODE_SIZE (candidate) > m_len)
1489 : break;
1490 :
1491 49522 : if (GET_MODE_SIZE (candidate) >= size
1492 49522 : && by_pieces_mode_supported_p (candidate, m_op))
1493 6264 : return candidate;
1494 : }
1495 : }
1496 :
1497 486675 : return smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
1498 : }
1499 :
1500 : /* This function contains the main loop used for expanding a block
1501 : operation. First move what we can in the largest integer mode,
1502 : then go to successively smaller modes. For every access, call
1503 : GENFUN with the two operands and the EXTRA_DATA. */
1504 :
1505 : void
1506 757492 : op_by_pieces_d::run ()
1507 : {
1508 757492 : if (m_len == 0)
1509 : return;
1510 :
1511 751303 : unsigned HOST_WIDE_INT length = m_len;
1512 :
1513 : /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1. */
1514 751303 : fixed_size_mode mode
1515 751303 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1516 751303 : mode = get_usable_mode (mode, length);
1517 :
1518 751303 : by_pieces_prev to_prev = { nullptr, mode };
1519 751303 : by_pieces_prev from_prev = { nullptr, mode };
1520 :
1521 1244242 : do
1522 : {
1523 1244242 : unsigned int size = GET_MODE_SIZE (mode);
1524 1244242 : rtx to1 = NULL_RTX, from1;
1525 :
1526 3309090 : while (length >= size)
1527 : {
1528 2064848 : if (m_reverse)
1529 47 : m_offset -= size;
1530 :
1531 2064848 : to1 = m_to.adjust (mode, m_offset, &to_prev);
1532 2064848 : to_prev.data = to1;
1533 2064848 : to_prev.mode = mode;
1534 2064848 : from1 = m_from.adjust (mode, m_offset, &from_prev);
1535 2064848 : from_prev.data = from1;
1536 2064848 : from_prev.mode = mode;
1537 :
1538 2064848 : m_to.maybe_predec (-(HOST_WIDE_INT)size);
1539 2064848 : m_from.maybe_predec (-(HOST_WIDE_INT)size);
1540 :
1541 2064848 : generate (to1, from1, mode);
1542 :
1543 2064848 : m_to.maybe_postinc (size);
1544 2064848 : m_from.maybe_postinc (size);
1545 :
1546 2064848 : if (!m_reverse)
1547 2064801 : m_offset += size;
1548 :
1549 2064848 : length -= size;
1550 : }
1551 :
1552 1244242 : finish_mode (mode);
1553 :
1554 1244242 : if (length == 0)
1555 : return;
1556 :
1557 492939 : if (!m_push && m_overlap_op_by_pieces)
1558 : {
1559 : /* NB: Generate overlapping operations if it is not a stack
1560 : push since stack push must not overlap. Get the smallest
1561 : fixed size mode for M_LEN bytes. */
1562 492939 : mode = smallest_fixed_size_mode_for_size (length);
1563 985878 : mode = get_usable_mode (mode, GET_MODE_SIZE (mode));
1564 492939 : int gap = GET_MODE_SIZE (mode) - length;
1565 492939 : if (gap > 0)
1566 : {
1567 : /* If size of MODE > M_LEN, generate the last operation
1568 : in MODE for the remaining bytes with overlapping memory
1569 : from the previois operation. */
1570 48985 : if (m_reverse)
1571 0 : m_offset += gap;
1572 : else
1573 48985 : m_offset -= gap;
1574 48985 : length += gap;
1575 : }
1576 : }
1577 : else
1578 : {
1579 : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1580 0 : mode = widest_fixed_size_mode_for_size (size, m_op);
1581 0 : mode = get_usable_mode (mode, length);
1582 : }
1583 : }
1584 : while (1);
1585 : }
1586 :
1587 : /* Derived class from op_by_pieces_d, providing support for block move
1588 : operations. */
1589 :
1590 : #ifdef PUSH_ROUNDING
1591 : #define PUSHG_P(to) ((to) == nullptr)
1592 : #else
1593 : #define PUSHG_P(to) false
1594 : #endif
1595 :
1596 : class move_by_pieces_d : public op_by_pieces_d
1597 : {
1598 : insn_gen_fn m_gen_fun;
1599 : void generate (rtx, rtx, machine_mode) final override;
1600 : bool prepare_mode (machine_mode, unsigned int) final override;
1601 :
1602 : public:
1603 570323 : move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1604 : unsigned int align)
1605 570323 : : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
1606 1140646 : NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
1607 : {
1608 570323 : }
1609 : rtx finish_retmode (memop_ret);
1610 : };
1611 :
1612 : /* Return true if MODE can be used for a set of copies, given an
1613 : alignment ALIGN. Prepare whatever data is necessary for later
1614 : calls to generate. */
1615 :
1616 : bool
1617 951292 : move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1618 : {
1619 951292 : insn_code icode = optab_handler (mov_optab, mode);
1620 951292 : m_gen_fun = GEN_FCN (icode);
1621 951292 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1622 : }
1623 :
1624 : /* A callback used when iterating for a compare_by_pieces_operation.
1625 : OP0 and OP1 are the values that have been loaded and should be
1626 : compared in MODE. If OP0 is NULL, this means we should generate a
1627 : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1628 : gen function that should be used to generate the mode. */
1629 :
1630 : void
1631 1651255 : move_by_pieces_d::generate (rtx op0, rtx op1,
1632 : machine_mode mode ATTRIBUTE_UNUSED)
1633 : {
1634 : #ifdef PUSH_ROUNDING
1635 1651255 : if (op0 == NULL_RTX)
1636 : {
1637 47 : emit_single_push_insn (mode, op1, NULL);
1638 47 : return;
1639 : }
1640 : #endif
1641 1651208 : emit_insn (m_gen_fun (op0, op1));
1642 : }
1643 :
1644 : /* Perform the final adjustment at the end of a string to obtain the
1645 : correct return value for the block operation.
1646 : Return value is based on RETMODE argument. */
1647 :
1648 : rtx
1649 0 : move_by_pieces_d::finish_retmode (memop_ret retmode)
1650 : {
1651 0 : gcc_assert (!m_reverse);
1652 0 : if (retmode == RETURN_END_MINUS_ONE)
1653 : {
1654 0 : m_to.maybe_postinc (-1);
1655 0 : --m_offset;
1656 : }
1657 0 : return m_to.adjust (QImode, m_offset);
1658 : }
1659 :
1660 : /* Generate several move instructions to copy LEN bytes from block FROM to
1661 : block TO. (These are MEM rtx's with BLKmode).
1662 :
1663 : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1664 : used to push FROM to the stack.
1665 :
1666 : ALIGN is maximum stack alignment we can assume.
1667 :
1668 : Return value is based on RETMODE argument. */
1669 :
1670 : rtx
1671 570323 : move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1672 : unsigned int align, memop_ret retmode)
1673 : {
1674 : #ifndef PUSH_ROUNDING
1675 : if (to == NULL)
1676 : gcc_unreachable ();
1677 : #endif
1678 :
1679 570323 : move_by_pieces_d data (to, from, len, align);
1680 :
1681 570323 : data.run ();
1682 :
1683 570323 : if (retmode != RETURN_BEGIN)
1684 0 : return data.finish_retmode (retmode);
1685 : else
1686 : return to;
1687 : }
1688 :
1689 : /* Derived class from op_by_pieces_d, providing support for block move
1690 : operations. */
1691 :
1692 : class store_by_pieces_d : public op_by_pieces_d
1693 : {
1694 : insn_gen_fn m_gen_fun;
1695 :
1696 : void generate (rtx, rtx, machine_mode) final override;
1697 : bool prepare_mode (machine_mode, unsigned int) final override;
1698 :
1699 : public:
1700 124469 : store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
1701 : unsigned HOST_WIDE_INT len, unsigned int align,
1702 : by_pieces_operation op)
1703 124469 : : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
1704 248938 : cfn_data, len, align, false, op)
1705 : {
1706 124469 : }
1707 : rtx finish_retmode (memop_ret);
1708 : };
1709 :
1710 : /* Return true if MODE can be used for a set of stores, given an
1711 : alignment ALIGN. Prepare whatever data is necessary for later
1712 : calls to generate. */
1713 :
1714 : bool
1715 198449 : store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1716 : {
1717 198449 : insn_code icode = optab_handler (mov_optab, mode);
1718 198449 : m_gen_fun = GEN_FCN (icode);
1719 198449 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1720 : }
1721 :
1722 : /* A callback used when iterating for a store_by_pieces_operation.
1723 : OP0 and OP1 are the values that have been loaded and should be
1724 : compared in MODE. If OP0 is NULL, this means we should generate a
1725 : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1726 : gen function that should be used to generate the mode. */
1727 :
1728 : void
1729 315836 : store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
1730 : {
1731 315836 : emit_insn (m_gen_fun (op0, op1));
1732 315836 : }
1733 :
1734 : /* Perform the final adjustment at the end of a string to obtain the
1735 : correct return value for the block operation.
1736 : Return value is based on RETMODE argument. */
1737 :
1738 : rtx
1739 647 : store_by_pieces_d::finish_retmode (memop_ret retmode)
1740 : {
1741 647 : gcc_assert (!m_reverse);
1742 647 : if (retmode == RETURN_END_MINUS_ONE)
1743 : {
1744 23 : m_to.maybe_postinc (-1);
1745 23 : --m_offset;
1746 : }
1747 647 : return m_to.adjust (QImode, m_offset);
1748 : }
1749 :
1750 : /* Determine whether the LEN bytes generated by CONSTFUN can be
1751 : stored to memory using several move instructions. CONSTFUNDATA is
1752 : a pointer which will be passed as argument in every CONSTFUN call.
1753 : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1754 : a memset operation and false if it's a copy of a constant string.
1755 : Return true if a call to store_by_pieces should succeed. */
1756 :
1757 : bool
1758 90286 : can_store_by_pieces (unsigned HOST_WIDE_INT len,
1759 : by_pieces_constfn constfun,
1760 : void *constfundata, unsigned int align, bool memsetp)
1761 : {
1762 90286 : unsigned HOST_WIDE_INT l;
1763 90286 : unsigned int max_size;
1764 90286 : HOST_WIDE_INT offset = 0;
1765 90286 : enum insn_code icode;
1766 90286 : int reverse;
1767 : /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */
1768 90286 : rtx cst ATTRIBUTE_UNUSED;
1769 :
1770 90286 : if (len == 0)
1771 : return true;
1772 :
1773 136386 : if (!targetm.use_by_pieces_infrastructure_p (len, align,
1774 : memsetp
1775 : ? SET_BY_PIECES
1776 : : STORE_BY_PIECES,
1777 90232 : optimize_insn_for_speed_p ()))
1778 : return false;
1779 :
1780 53476 : align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
1781 :
1782 : /* We would first store what we can in the largest integer mode, then go to
1783 : successively smaller modes. */
1784 :
1785 53476 : for (reverse = 0;
1786 106952 : reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
1787 : reverse++)
1788 : {
1789 53476 : l = len;
1790 53476 : max_size = STORE_MAX_PIECES + 1;
1791 253758 : while (max_size > 1 && l > 0)
1792 : {
1793 200282 : auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
1794 200282 : auto mode = widest_fixed_size_mode_for_size (max_size, op);
1795 :
1796 200282 : icode = optab_handler (mov_optab, mode);
1797 200282 : if (icode != CODE_FOR_nothing
1798 200282 : && align >= GET_MODE_ALIGNMENT (mode))
1799 : {
1800 200282 : unsigned int size = GET_MODE_SIZE (mode);
1801 :
1802 346238 : while (l >= size)
1803 : {
1804 145956 : if (reverse)
1805 : offset -= size;
1806 :
1807 145956 : cst = (*constfun) (constfundata, nullptr, offset, mode);
1808 : /* All CONST_VECTORs can be loaded for memset since
1809 : vec_duplicate_optab is a precondition to pick a
1810 : vector mode for the memset expander. */
1811 271280 : if (!((memsetp && VECTOR_MODE_P (mode))
1812 125324 : || targetm.legitimate_constant_p (mode, cst)))
1813 36756 : return false;
1814 :
1815 145956 : if (!reverse)
1816 145956 : offset += size;
1817 :
1818 145956 : l -= size;
1819 : }
1820 : }
1821 :
1822 400564 : max_size = GET_MODE_SIZE (mode);
1823 : }
1824 :
1825 : /* The code above should have handled everything. */
1826 53476 : gcc_assert (!l);
1827 : }
1828 :
1829 : return true;
1830 : }
1831 :
1832 : /* Generate several move instructions to store LEN bytes generated by
1833 : CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
1834 : pointer which will be passed as argument in every CONSTFUN call.
1835 : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1836 : a memset operation and false if it's a copy of a constant string.
1837 : Return value is based on RETMODE argument. */
1838 :
1839 : rtx
1840 60772 : store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
1841 : by_pieces_constfn constfun,
1842 : void *constfundata, unsigned int align, bool memsetp,
1843 : memop_ret retmode)
1844 : {
1845 60772 : if (len == 0)
1846 : {
1847 7887 : gcc_assert (retmode != RETURN_END_MINUS_ONE);
1848 : return to;
1849 : }
1850 :
1851 94986 : gcc_assert (targetm.use_by_pieces_infrastructure_p
1852 : (len, align,
1853 : memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
1854 : optimize_insn_for_speed_p ()));
1855 :
1856 52885 : store_by_pieces_d data (to, constfun, constfundata, len, align,
1857 52885 : memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
1858 52885 : data.run ();
1859 :
1860 52885 : if (retmode != RETURN_BEGIN)
1861 647 : return data.finish_retmode (retmode);
1862 : else
1863 : return to;
1864 : }
1865 :
1866 : void
1867 71584 : clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
1868 : {
1869 71584 : if (len == 0)
1870 0 : return;
1871 :
1872 : /* Use builtin_memset_read_str to support vector mode broadcast. */
1873 71584 : char c = 0;
1874 71584 : store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
1875 71584 : CLEAR_BY_PIECES);
1876 71584 : data.run ();
1877 : }
1878 :
1879 : /* Context used by compare_by_pieces_genfn. It stores the fail label
1880 : to jump to in case of miscomparison, and for branch ratios greater than 1,
1881 : it stores an accumulator and the current and maximum counts before
1882 : emitting another branch. */
1883 :
1884 : class compare_by_pieces_d : public op_by_pieces_d
1885 : {
1886 : rtx_code_label *m_fail_label;
1887 : rtx m_accumulator;
1888 : int m_count, m_batch;
1889 :
1890 : void generate (rtx, rtx, machine_mode) final override;
1891 : bool prepare_mode (machine_mode, unsigned int) final override;
1892 : void finish_mode (machine_mode) final override;
1893 :
1894 : public:
1895 62700 : compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
1896 : void *op1_cfn_data, HOST_WIDE_INT len, int align,
1897 : rtx_code_label *fail_label)
1898 62700 : : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
1899 125400 : op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
1900 : {
1901 62700 : m_fail_label = fail_label;
1902 62700 : }
1903 : };
1904 :
1905 : /* A callback used when iterating for a compare_by_pieces_operation.
1906 : OP0 and OP1 are the values that have been loaded and should be
1907 : compared in MODE. DATA holds a pointer to the compare_by_pieces_data
1908 : context structure. */
1909 :
1910 : void
1911 97757 : compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
1912 : {
1913 97757 : if (m_batch > 1)
1914 : {
1915 0 : rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
1916 : true, OPTAB_LIB_WIDEN);
1917 0 : if (m_count != 0)
1918 0 : temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
1919 : true, OPTAB_LIB_WIDEN);
1920 0 : m_accumulator = temp;
1921 :
1922 0 : if (++m_count < m_batch)
1923 : return;
1924 :
1925 0 : m_count = 0;
1926 0 : op0 = m_accumulator;
1927 0 : op1 = const0_rtx;
1928 0 : m_accumulator = NULL_RTX;
1929 : }
1930 97757 : do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
1931 : m_fail_label, profile_probability::uninitialized ());
1932 : }
1933 :
1934 : /* Return true if MODE can be used for a set of moves and comparisons,
1935 : given an alignment ALIGN. Prepare whatever data is necessary for
1936 : later calls to generate. */
1937 :
1938 : bool
1939 94501 : compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1940 : {
1941 94501 : insn_code icode = optab_handler (mov_optab, mode);
1942 94501 : if (icode == CODE_FOR_nothing
1943 94501 : || align < GET_MODE_ALIGNMENT (mode)
1944 189002 : || !can_compare_p (EQ, mode, ccp_jump))
1945 0 : return false;
1946 94501 : m_batch = targetm.compare_by_pieces_branch_ratio (mode);
1947 94501 : if (m_batch < 0)
1948 : return false;
1949 94501 : m_accumulator = NULL_RTX;
1950 94501 : m_count = 0;
1951 94501 : return true;
1952 : }
1953 :
1954 : /* Called after expanding a series of comparisons in MODE. If we have
1955 : accumulated results for which we haven't emitted a branch yet, do
1956 : so now. */
1957 :
1958 : void
1959 94501 : compare_by_pieces_d::finish_mode (machine_mode mode)
1960 : {
1961 94501 : if (m_accumulator != NULL_RTX)
1962 0 : do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
1963 : NULL_RTX, NULL, m_fail_label,
1964 : profile_probability::uninitialized ());
1965 94501 : }
1966 :
1967 : /* Generate several move instructions to compare LEN bytes from blocks
1968 : ARG0 and ARG1. (These are MEM rtx's with BLKmode).
1969 :
1970 : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1971 : used to push FROM to the stack.
1972 :
1973 : ALIGN is maximum stack alignment we can assume.
1974 :
1975 : Optionally, the caller can pass a constfn and associated data in A1_CFN
1976 : and A1_CFN_DATA. describing that the second operand being compared is a
1977 : known constant and how to obtain its data. */
1978 :
1979 : static rtx
1980 62700 : compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
1981 : rtx target, unsigned int align,
1982 : by_pieces_constfn a1_cfn, void *a1_cfn_data)
1983 : {
1984 62700 : rtx_code_label *fail_label = gen_label_rtx ();
1985 62700 : rtx_code_label *end_label = gen_label_rtx ();
1986 :
1987 62700 : if (target == NULL_RTX
1988 62700 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
1989 2 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
1990 :
1991 62700 : compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
1992 62700 : fail_label);
1993 :
1994 62700 : data.run ();
1995 :
1996 62700 : emit_move_insn (target, const0_rtx);
1997 62700 : emit_jump (end_label);
1998 62700 : emit_barrier ();
1999 62700 : emit_label (fail_label);
2000 62700 : emit_move_insn (target, const1_rtx);
2001 62700 : emit_label (end_label);
2002 :
2003 62700 : return target;
2004 : }
2005 :
2006 : /* Emit code to move a block Y to a block X. This may be done with
2007 : string-move instructions, with multiple scalar move instructions,
2008 : or with a library call.
2009 :
2010 : Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
2011 : SIZE is an rtx that says how long they are.
2012 : ALIGN is the maximum alignment we can assume they have.
2013 : METHOD describes what kind of copy this is, and what mechanisms may be used.
2014 : MIN_SIZE is the minimal size of block to move
2015 : MAX_SIZE is the maximal size of block to move, if it cannot be represented
2016 : in unsigned HOST_WIDE_INT, than it is mask of all ones.
2017 : CTZ_SIZE is the trailing-zeros count of SIZE; even a nonconstant SIZE is
2018 : known to be a multiple of 1<<CTZ_SIZE.
2019 :
2020 : Return the address of the new block, if memcpy is called and returns it,
2021 : 0 otherwise. */
2022 :
2023 : rtx
2024 669378 : emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
2025 : unsigned int expected_align, HOST_WIDE_INT expected_size,
2026 : unsigned HOST_WIDE_INT min_size,
2027 : unsigned HOST_WIDE_INT max_size,
2028 : unsigned HOST_WIDE_INT probable_max_size,
2029 : bool bail_out_libcall, bool *is_move_done,
2030 : bool might_overlap, unsigned ctz_size)
2031 : {
2032 669378 : int may_use_call;
2033 669378 : rtx retval = 0;
2034 669378 : unsigned int align;
2035 :
2036 669378 : if (is_move_done)
2037 97879 : *is_move_done = true;
2038 :
2039 669378 : gcc_assert (size);
2040 669378 : if (CONST_INT_P (size) && INTVAL (size) == 0)
2041 : return 0;
2042 :
2043 669101 : switch (method)
2044 : {
2045 : case BLOCK_OP_NORMAL:
2046 : case BLOCK_OP_TAILCALL:
2047 : may_use_call = 1;
2048 : break;
2049 :
2050 269085 : case BLOCK_OP_CALL_PARM:
2051 269085 : may_use_call = block_move_libcall_safe_for_call_parm ();
2052 :
2053 : /* Make inhibit_defer_pop nonzero around the library call
2054 : to force it to pop the arguments right away. */
2055 269085 : NO_DEFER_POP;
2056 269085 : break;
2057 :
2058 354 : case BLOCK_OP_NO_LIBCALL:
2059 354 : may_use_call = 0;
2060 354 : break;
2061 :
2062 1074 : case BLOCK_OP_NO_LIBCALL_RET:
2063 1074 : may_use_call = -1;
2064 1074 : break;
2065 :
2066 0 : default:
2067 0 : gcc_unreachable ();
2068 : }
2069 :
2070 669101 : gcc_assert (MEM_P (x) && MEM_P (y));
2071 669186 : align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2072 669101 : gcc_assert (align >= BITS_PER_UNIT);
2073 :
2074 : /* Make sure we've got BLKmode addresses; store_one_arg can decide that
2075 : block copy is more efficient for other large modes, e.g. DCmode. */
2076 669101 : x = adjust_address (x, BLKmode, 0);
2077 669101 : y = adjust_address (y, BLKmode, 0);
2078 :
2079 : /* If source and destination are the same, no need to copy anything. */
2080 669101 : if (rtx_equal_p (x, y)
2081 13 : && !MEM_VOLATILE_P (x)
2082 669114 : && !MEM_VOLATILE_P (y))
2083 : return 0;
2084 :
2085 : /* Set MEM_SIZE as appropriate for this block copy. The main place this
2086 : can be incorrect is coming from __builtin_memcpy. */
2087 669088 : poly_int64 const_size;
2088 669088 : if (poly_int_rtx_p (size, &const_size))
2089 : {
2090 590295 : x = shallow_copy_rtx (x);
2091 590295 : y = shallow_copy_rtx (y);
2092 590295 : set_mem_size (x, const_size);
2093 590295 : set_mem_size (y, const_size);
2094 : }
2095 :
2096 669088 : bool pieces_ok = CONST_INT_P (size)
2097 669088 : && can_move_by_pieces (INTVAL (size), align);
2098 669088 : bool pattern_ok = false;
2099 :
2100 669088 : if (!pieces_ok || might_overlap)
2101 : {
2102 105584 : pattern_ok
2103 105584 : = emit_block_move_via_pattern (x, y, size, align,
2104 : expected_align, expected_size,
2105 : min_size, max_size, probable_max_size,
2106 : might_overlap);
2107 105584 : if (!pattern_ok && might_overlap)
2108 : {
2109 : /* Do not try any of the other methods below as they are not safe
2110 : for overlapping moves. */
2111 12467 : *is_move_done = false;
2112 12467 : return retval;
2113 : }
2114 : }
2115 :
2116 93117 : bool dynamic_direction = false;
2117 93117 : if (!pattern_ok && !pieces_ok && may_use_call
2118 135626 : && (flag_inline_stringops & (might_overlap ? ILSOP_MEMMOVE : ILSOP_MEMCPY)))
2119 : {
2120 656621 : may_use_call = 0;
2121 656621 : dynamic_direction = might_overlap;
2122 : }
2123 :
2124 656621 : if (pattern_ok)
2125 : ;
2126 631317 : else if (pieces_ok)
2127 563504 : move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
2128 67813 : else if (may_use_call && !might_overlap
2129 67765 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2130 135578 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
2131 : {
2132 67765 : if (bail_out_libcall)
2133 : {
2134 259 : if (is_move_done)
2135 259 : *is_move_done = false;
2136 259 : return retval;
2137 : }
2138 :
2139 67506 : if (may_use_call < 0)
2140 0 : return pc_rtx;
2141 :
2142 67506 : retval = emit_block_copy_via_libcall (x, y, size,
2143 : method == BLOCK_OP_TAILCALL);
2144 : }
2145 48 : else if (dynamic_direction)
2146 0 : emit_block_move_via_oriented_loop (x, y, size, align, ctz_size);
2147 48 : else if (might_overlap)
2148 0 : *is_move_done = false;
2149 : else
2150 48 : emit_block_move_via_sized_loop (x, y, size, align, ctz_size);
2151 :
2152 656362 : if (method == BLOCK_OP_CALL_PARM)
2153 269074 : OK_DEFER_POP;
2154 :
2155 : return retval;
2156 : }
2157 :
2158 : rtx
2159 571499 : emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method,
2160 : unsigned int ctz_size)
2161 : {
2162 571499 : unsigned HOST_WIDE_INT max, min = 0;
2163 571499 : if (GET_CODE (size) == CONST_INT)
2164 571279 : min = max = UINTVAL (size);
2165 : else
2166 220 : max = GET_MODE_MASK (GET_MODE (size));
2167 571499 : return emit_block_move_hints (x, y, size, method, 0, -1,
2168 : min, max, max,
2169 571499 : false, NULL, false, ctz_size);
2170 : }
2171 :
2172 : /* A subroutine of emit_block_move. Returns true if calling the
2173 : block move libcall will not clobber any parameters which may have
2174 : already been placed on the stack. */
2175 :
2176 : static bool
2177 269085 : block_move_libcall_safe_for_call_parm (void)
2178 : {
2179 269085 : tree fn;
2180 :
2181 : /* If arguments are pushed on the stack, then they're safe. */
2182 269085 : if (targetm.calls.push_argument (0))
2183 : return true;
2184 :
2185 : /* If registers go on the stack anyway, any argument is sure to clobber
2186 : an outgoing argument. */
2187 : #if defined (REG_PARM_STACK_SPACE)
2188 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2189 : /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
2190 : depend on its argument. */
2191 3 : (void) fn;
2192 3 : if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
2193 3 : && REG_PARM_STACK_SPACE (fn) != 0)
2194 : return false;
2195 : #endif
2196 :
2197 : /* If any argument goes in memory, then it might clobber an outgoing
2198 : argument. */
2199 3 : {
2200 3 : CUMULATIVE_ARGS args_so_far_v;
2201 3 : cumulative_args_t args_so_far;
2202 3 : tree arg;
2203 :
2204 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2205 3 : INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
2206 3 : args_so_far = pack_cumulative_args (&args_so_far_v);
2207 :
2208 3 : arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2209 12 : for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
2210 : {
2211 9 : machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
2212 9 : function_arg_info arg_info (mode, /*named=*/true);
2213 9 : rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
2214 9 : if (!tmp || !REG_P (tmp))
2215 0 : return false;
2216 9 : if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
2217 : return false;
2218 9 : targetm.calls.function_arg_advance (args_so_far, arg_info);
2219 : }
2220 : }
2221 3 : return true;
2222 : }
2223 :
2224 : /* A subroutine of emit_block_move. Expand a cpymem or movmem pattern;
2225 : return true if successful.
2226 :
2227 : X is the destination of the copy or move.
2228 : Y is the source of the copy or move.
2229 : SIZE is the size of the block to be moved.
2230 :
2231 : MIGHT_OVERLAP indicates this originated with expansion of a
2232 : builtin_memmove() and the source and destination blocks may
2233 : overlap.
2234 : */
2235 :
2236 : static bool
2237 105584 : emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
2238 : unsigned int expected_align,
2239 : HOST_WIDE_INT expected_size,
2240 : unsigned HOST_WIDE_INT min_size,
2241 : unsigned HOST_WIDE_INT max_size,
2242 : unsigned HOST_WIDE_INT probable_max_size,
2243 : bool might_overlap)
2244 : {
2245 105584 : if (expected_align < align)
2246 : expected_align = align;
2247 105584 : if (expected_size != -1)
2248 : {
2249 22 : if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
2250 0 : expected_size = probable_max_size;
2251 22 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
2252 0 : expected_size = min_size;
2253 : }
2254 :
2255 : /* Since this is a move insn, we don't care about volatility. */
2256 105584 : temporary_volatile_ok v (true);
2257 :
2258 : /* Try the most limited insn first, because there's no point
2259 : including more than one in the machine description unless
2260 : the more limited one has some advantage. */
2261 :
2262 105584 : opt_scalar_int_mode mode_iter;
2263 722115 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
2264 : {
2265 641835 : scalar_int_mode mode = mode_iter.require ();
2266 641835 : enum insn_code code;
2267 641835 : if (might_overlap)
2268 101463 : code = direct_optab_handler (movmem_optab, mode);
2269 : else
2270 540372 : code = direct_optab_handler (cpymem_optab, mode);
2271 :
2272 641835 : if (code != CODE_FOR_nothing
2273 : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
2274 : here because if SIZE is less than the mode mask, as it is
2275 : returned by the macro, it will definitely be less than the
2276 : actual mode mask. Since SIZE is within the Pmode address
2277 : space, we limit MODE to Pmode. */
2278 641835 : && ((CONST_INT_P (size)
2279 41613 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
2280 41613 : <= (GET_MODE_MASK (mode) >> 1)))
2281 143143 : || max_size <= (GET_MODE_MASK (mode) >> 1)
2282 178406 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
2283 : {
2284 122306 : class expand_operand ops[9];
2285 122306 : unsigned int nops;
2286 :
2287 : /* ??? When called via emit_block_move_for_call, it'd be
2288 : nice if there were some way to inform the backend, so
2289 : that it doesn't fail the expansion because it thinks
2290 : emitting the libcall would be more efficient. */
2291 122306 : nops = insn_data[(int) code].n_generator_args;
2292 122306 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
2293 :
2294 122306 : create_fixed_operand (&ops[0], x);
2295 122306 : create_fixed_operand (&ops[1], y);
2296 : /* The check above guarantees that this size conversion is valid. */
2297 122306 : create_convert_operand_to (&ops[2], size, mode, true);
2298 122306 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
2299 122306 : if (nops >= 6)
2300 : {
2301 122306 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
2302 122306 : create_integer_operand (&ops[5], expected_size);
2303 : }
2304 122306 : if (nops >= 8)
2305 : {
2306 122306 : create_integer_operand (&ops[6], min_size);
2307 : /* If we cannot represent the maximal size,
2308 : make parameter NULL. */
2309 122306 : if ((HOST_WIDE_INT) max_size != -1)
2310 105146 : create_integer_operand (&ops[7], max_size);
2311 : else
2312 17160 : create_fixed_operand (&ops[7], NULL);
2313 : }
2314 122306 : if (nops == 9)
2315 : {
2316 : /* If we cannot represent the maximal size,
2317 : make parameter NULL. */
2318 122306 : if ((HOST_WIDE_INT) probable_max_size != -1)
2319 107276 : create_integer_operand (&ops[8], probable_max_size);
2320 : else
2321 15030 : create_fixed_operand (&ops[8], NULL);
2322 : }
2323 122306 : gcc_assert (min_size != max_size
2324 : || rtx_equal_p (ops[2].value, GEN_INT (min_size)));
2325 122306 : if (maybe_expand_insn (code, nops, ops))
2326 25304 : return true;
2327 : }
2328 : }
2329 :
2330 : return false;
2331 105584 : }
2332 :
2333 : /* Like emit_block_move_via_loop, but choose a suitable INCR based on
2334 : ALIGN and CTZ_SIZE. */
2335 :
2336 : static void
2337 48 : emit_block_move_via_sized_loop (rtx x, rtx y, rtx size,
2338 : unsigned int align,
2339 : unsigned int ctz_size)
2340 : {
2341 48 : int incr = align / BITS_PER_UNIT;
2342 :
2343 48 : if (CONST_INT_P (size))
2344 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2345 :
2346 48 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2347 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2348 :
2349 48 : while (incr > 1 && !can_move_by_pieces (incr, align))
2350 0 : incr >>= 1;
2351 :
2352 48 : gcc_checking_assert (incr);
2353 :
2354 48 : return emit_block_move_via_loop (x, y, size, align, incr);
2355 : }
2356 :
2357 : /* Like emit_block_move_via_sized_loop, but besides choosing INCR so
2358 : as to ensure safe moves even in case of overlap, output dynamic
2359 : tests to choose between two loops, one moving downwards, another
2360 : moving upwards. */
2361 :
2362 : static void
2363 0 : emit_block_move_via_oriented_loop (rtx x, rtx y, rtx size,
2364 : unsigned int align,
2365 : unsigned int ctz_size)
2366 : {
2367 0 : int incr = align / BITS_PER_UNIT;
2368 :
2369 0 : if (CONST_INT_P (size))
2370 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2371 :
2372 0 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2373 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2374 :
2375 0 : while (incr > 1 && !int_mode_for_size (incr, 0).exists ())
2376 0 : incr >>= 1;
2377 :
2378 0 : gcc_checking_assert (incr);
2379 :
2380 0 : rtx_code_label *upw_label, *end_label;
2381 0 : upw_label = gen_label_rtx ();
2382 0 : end_label = gen_label_rtx ();
2383 :
2384 0 : rtx x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2385 0 : rtx y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2386 0 : do_pending_stack_adjust ();
2387 :
2388 0 : machine_mode mode = GET_MODE (x_addr);
2389 0 : if (mode != GET_MODE (y_addr))
2390 : {
2391 0 : scalar_int_mode xmode
2392 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (mode)).require ();
2393 0 : scalar_int_mode ymode
2394 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE
2395 0 : (GET_MODE (y_addr))).require ();
2396 0 : if (GET_MODE_BITSIZE (xmode) < GET_MODE_BITSIZE (ymode))
2397 : mode = ymode;
2398 : else
2399 0 : mode = xmode;
2400 :
2401 : #ifndef POINTERS_EXTEND_UNSIGNED
2402 : const int POINTERS_EXTEND_UNSIGNED = 1;
2403 : #endif
2404 0 : x_addr = convert_modes (mode, GET_MODE (x_addr), x_addr,
2405 : POINTERS_EXTEND_UNSIGNED);
2406 0 : y_addr = convert_modes (mode, GET_MODE (y_addr), y_addr,
2407 : POINTERS_EXTEND_UNSIGNED);
2408 : }
2409 :
2410 : /* Test for overlap: if (x >= y || x + size <= y) goto upw_label. */
2411 0 : emit_cmp_and_jump_insns (x_addr, y_addr, GEU, NULL_RTX, mode,
2412 : true, upw_label,
2413 0 : profile_probability::guessed_always ()
2414 : .apply_scale (5, 10));
2415 0 : rtx tmp = convert_modes (GET_MODE (x_addr), GET_MODE (size), size, true);
2416 0 : tmp = simplify_gen_binary (PLUS, GET_MODE (x_addr), x_addr, tmp);
2417 :
2418 0 : emit_cmp_and_jump_insns (tmp, y_addr, LEU, NULL_RTX, mode,
2419 : true, upw_label,
2420 0 : profile_probability::guessed_always ()
2421 : .apply_scale (8, 10));
2422 :
2423 0 : emit_block_move_via_loop (x, y, size, align, -incr);
2424 :
2425 0 : emit_jump (end_label);
2426 0 : emit_label (upw_label);
2427 :
2428 0 : emit_block_move_via_loop (x, y, size, align, incr);
2429 :
2430 0 : emit_label (end_label);
2431 0 : }
2432 :
2433 : /* A subroutine of emit_block_move. Copy the data via an explicit
2434 : loop. This is used only when libcalls are forbidden, or when
2435 : inlining is required. INCR is the block size to be copied in each
2436 : loop iteration. If it is negative, the absolute value is used, and
2437 : the block is copied backwards. INCR must be a power of two, an
2438 : exact divisor for SIZE and ALIGN, and imply a mode that can be
2439 : safely copied per iteration assuming no overlap. */
2440 :
2441 : static void
2442 48 : emit_block_move_via_loop (rtx x, rtx y, rtx size,
2443 : unsigned int align, int incr)
2444 : {
2445 48 : rtx_code_label *cmp_label, *top_label;
2446 48 : rtx iter, x_addr, y_addr, tmp;
2447 48 : machine_mode x_addr_mode = get_address_mode (x);
2448 48 : machine_mode y_addr_mode = get_address_mode (y);
2449 48 : machine_mode iter_mode;
2450 :
2451 48 : iter_mode = GET_MODE (size);
2452 48 : if (iter_mode == VOIDmode)
2453 0 : iter_mode = word_mode;
2454 :
2455 48 : top_label = gen_label_rtx ();
2456 48 : cmp_label = gen_label_rtx ();
2457 48 : iter = gen_reg_rtx (iter_mode);
2458 :
2459 48 : bool downwards = incr < 0;
2460 48 : rtx iter_init;
2461 48 : rtx_code iter_cond;
2462 48 : rtx iter_limit;
2463 48 : rtx iter_incr;
2464 48 : machine_mode move_mode;
2465 48 : if (downwards)
2466 : {
2467 0 : incr = -incr;
2468 0 : iter_init = size;
2469 0 : iter_cond = GEU;
2470 0 : iter_limit = const0_rtx;
2471 0 : iter_incr = GEN_INT (incr);
2472 : }
2473 : else
2474 : {
2475 48 : iter_init = const0_rtx;
2476 48 : iter_cond = LTU;
2477 48 : iter_limit = size;
2478 48 : iter_incr = GEN_INT (incr);
2479 : }
2480 48 : emit_move_insn (iter, iter_init);
2481 :
2482 48 : opt_scalar_int_mode int_move_mode
2483 48 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2484 48 : if (!int_move_mode.exists (&move_mode)
2485 96 : || GET_MODE_BITSIZE (int_move_mode.require ()) != incr * BITS_PER_UNIT)
2486 : {
2487 0 : move_mode = BLKmode;
2488 0 : gcc_checking_assert (can_move_by_pieces (incr, align));
2489 : }
2490 :
2491 48 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2492 48 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2493 48 : do_pending_stack_adjust ();
2494 :
2495 48 : emit_jump (cmp_label);
2496 48 : emit_label (top_label);
2497 :
2498 48 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2499 48 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2500 :
2501 48 : if (x_addr_mode != y_addr_mode)
2502 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2503 48 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2504 :
2505 48 : x = change_address (x, move_mode, x_addr);
2506 48 : y = change_address (y, move_mode, y_addr);
2507 :
2508 48 : if (move_mode == BLKmode)
2509 : {
2510 0 : bool done;
2511 0 : emit_block_move_hints (x, y, iter_incr, BLOCK_OP_NO_LIBCALL,
2512 : align, incr, incr, incr, incr,
2513 : false, &done, false);
2514 0 : gcc_checking_assert (done);
2515 : }
2516 : else
2517 48 : emit_move_insn (x, y);
2518 :
2519 48 : if (downwards)
2520 0 : emit_label (cmp_label);
2521 :
2522 48 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2523 : true, OPTAB_LIB_WIDEN);
2524 48 : if (tmp != iter)
2525 0 : emit_move_insn (iter, tmp);
2526 :
2527 48 : if (!downwards)
2528 48 : emit_label (cmp_label);
2529 :
2530 48 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2531 : true, top_label,
2532 48 : profile_probability::guessed_always ()
2533 : .apply_scale (9, 10));
2534 48 : }
2535 :
2536 : /* Expand a call to memcpy or memmove or memcmp, and return the result.
2537 : TAILCALL is true if this is a tail call. */
2538 :
2539 : rtx
2540 67507 : emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
2541 : rtx size, bool tailcall)
2542 : {
2543 67507 : rtx dst_addr, src_addr;
2544 67507 : tree call_expr, dst_tree, src_tree, size_tree;
2545 67507 : machine_mode size_mode;
2546 :
2547 : /* Since dst and src are passed to a libcall, mark the corresponding
2548 : tree EXPR as addressable. */
2549 67507 : tree dst_expr = MEM_EXPR (dst);
2550 67507 : tree src_expr = MEM_EXPR (src);
2551 67507 : if (dst_expr)
2552 60788 : mark_addressable (dst_expr);
2553 67507 : if (src_expr)
2554 66095 : mark_addressable (src_expr);
2555 :
2556 67507 : dst_addr = copy_addr_to_reg (XEXP (dst, 0));
2557 67507 : dst_addr = convert_memory_address (ptr_mode, dst_addr);
2558 67507 : dst_tree = make_tree (ptr_type_node, dst_addr);
2559 :
2560 67507 : src_addr = copy_addr_to_reg (XEXP (src, 0));
2561 67507 : src_addr = convert_memory_address (ptr_mode, src_addr);
2562 67507 : src_tree = make_tree (ptr_type_node, src_addr);
2563 :
2564 67507 : size_mode = TYPE_MODE (sizetype);
2565 67507 : size = convert_to_mode (size_mode, size, 1);
2566 67507 : size = copy_to_mode_reg (size_mode, size);
2567 67507 : size_tree = make_tree (sizetype, size);
2568 :
2569 : /* It is incorrect to use the libcall calling conventions for calls to
2570 : memcpy/memmove/memcmp because they can be provided by the user. */
2571 67507 : tree fn = builtin_decl_implicit (fncode);
2572 67507 : call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
2573 67507 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
2574 :
2575 67507 : return expand_call (call_expr, NULL_RTX, false);
2576 : }
2577 :
2578 : /* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
2579 : ARG3_TYPE is the type of ARG3_RTX. Return the result rtx on success,
2580 : otherwise return null. */
2581 :
2582 : rtx
2583 171425 : expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
2584 : rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
2585 : HOST_WIDE_INT align)
2586 : {
2587 171425 : machine_mode insn_mode = insn_data[icode].operand[0].mode;
2588 :
2589 171425 : if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
2590 : target = NULL_RTX;
2591 :
2592 171425 : class expand_operand ops[5];
2593 171425 : create_output_operand (&ops[0], target, insn_mode);
2594 171425 : create_fixed_operand (&ops[1], arg1_rtx);
2595 171425 : create_fixed_operand (&ops[2], arg2_rtx);
2596 171425 : create_convert_operand_from (&ops[3], arg3_rtx, TYPE_MODE (arg3_type),
2597 171425 : TYPE_UNSIGNED (arg3_type));
2598 171425 : create_integer_operand (&ops[4], align);
2599 171425 : if (maybe_expand_insn (icode, 5, ops))
2600 5796 : return ops[0].value;
2601 : return NULL_RTX;
2602 : }
2603 :
2604 : /* Expand a block compare between X and Y with length LEN using the
2605 : cmpmem optab, placing the result in TARGET. LEN_TYPE is the type
2606 : of the expression that was used to calculate the length. ALIGN
2607 : gives the known minimum common alignment. */
2608 :
2609 : static rtx
2610 43484 : emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
2611 : unsigned align)
2612 : {
2613 : /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
2614 : implementing memcmp because it will stop if it encounters two
2615 : zero bytes. */
2616 43484 : insn_code icode = direct_optab_handler (cmpmem_optab, SImode);
2617 :
2618 43484 : if (icode == CODE_FOR_nothing)
2619 : return NULL_RTX;
2620 :
2621 43484 : return expand_cmpstrn_or_cmpmem (icode, target, x, y, len_type, len, align);
2622 : }
2623 :
2624 : /* Emit code to compare a block Y to a block X. This may be done with
2625 : string-compare instructions, with multiple scalar instructions,
2626 : or with a library call.
2627 :
2628 : Both X and Y must be MEM rtx's. LEN is an rtx that says how long
2629 : they are. LEN_TYPE is the type of the expression that was used to
2630 : calculate it, and CTZ_LEN is the known trailing-zeros count of LEN,
2631 : so LEN must be a multiple of 1<<CTZ_LEN even if it's not constant.
2632 :
2633 : If EQUALITY_ONLY is true, it means we don't have to return the tri-state
2634 : value of a normal memcmp call, instead we can just compare for equality.
2635 : If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
2636 : returning NULL_RTX.
2637 :
2638 : Optionally, the caller can pass a constfn and associated data in Y_CFN
2639 : and Y_CFN_DATA. describing that the second operand being compared is a
2640 : known constant and how to obtain its data.
2641 : Return the result of the comparison, or NULL_RTX if we failed to
2642 : perform the operation. */
2643 :
2644 : rtx
2645 106183 : emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
2646 : bool equality_only, by_pieces_constfn y_cfn,
2647 : void *y_cfndata, unsigned ctz_len)
2648 : {
2649 106183 : rtx result = 0;
2650 :
2651 106183 : if (CONST_INT_P (len) && INTVAL (len) == 0)
2652 0 : return const0_rtx;
2653 :
2654 106183 : gcc_assert (MEM_P (x) && MEM_P (y));
2655 106183 : unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2656 106183 : gcc_assert (align >= BITS_PER_UNIT);
2657 :
2658 106183 : x = adjust_address (x, BLKmode, 0);
2659 106183 : y = adjust_address (y, BLKmode, 0);
2660 :
2661 106183 : if (equality_only
2662 91326 : && CONST_INT_P (len)
2663 175608 : && can_do_by_pieces (INTVAL (len), align, COMPARE_BY_PIECES))
2664 62699 : result = compare_by_pieces (x, y, INTVAL (len), target, align,
2665 : y_cfn, y_cfndata);
2666 : else
2667 43484 : result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
2668 :
2669 106183 : if (!result && (flag_inline_stringops & ILSOP_MEMCMP))
2670 361 : result = emit_block_cmp_via_loop (x, y, len, len_type,
2671 : target, equality_only,
2672 : align, ctz_len);
2673 :
2674 : return result;
2675 : }
2676 :
2677 : /* Like emit_block_cmp_hints, but with known alignment and no support
2678 : for constats. Always expand to a loop with iterations that compare
2679 : blocks of the largest compare-by-pieces size that divides both len
2680 : and align, and then, if !EQUALITY_ONLY, identify the word and then
2681 : the unit that first differs to return the result. */
2682 :
2683 : rtx
2684 403 : emit_block_cmp_via_loop (rtx x, rtx y, rtx len, tree len_type, rtx target,
2685 : bool equality_only, unsigned align, unsigned ctz_len)
2686 : {
2687 403 : unsigned incr = align / BITS_PER_UNIT;
2688 :
2689 403 : if (CONST_INT_P (len))
2690 319 : ctz_len = MAX (ctz_len, (unsigned) wi::ctz (UINTVAL (len)));
2691 :
2692 403 : if (HOST_WIDE_INT_1U << ctz_len < (unsigned HOST_WIDE_INT) incr)
2693 148 : incr = HOST_WIDE_INT_1U << ctz_len;
2694 :
2695 : while (incr > 1
2696 407 : && !can_do_by_pieces (incr, align, COMPARE_BY_PIECES))
2697 4 : incr >>= 1;
2698 :
2699 403 : rtx_code_label *cmp_label, *top_label, *ne_label, *res_label;
2700 403 : rtx iter, x_addr, y_addr, tmp;
2701 403 : machine_mode x_addr_mode = get_address_mode (x);
2702 403 : machine_mode y_addr_mode = get_address_mode (y);
2703 403 : machine_mode iter_mode;
2704 :
2705 403 : iter_mode = GET_MODE (len);
2706 403 : if (iter_mode == VOIDmode)
2707 319 : iter_mode = word_mode;
2708 :
2709 403 : rtx iter_init = const0_rtx;
2710 403 : rtx_code iter_cond = LTU;
2711 403 : rtx_code entry_cond = GEU;
2712 403 : rtx iter_limit = len;
2713 403 : rtx iter_incr = GEN_INT (incr);
2714 403 : machine_mode cmp_mode;
2715 :
2716 : /* We can drop the loop back edge if we know there's exactly one
2717 : iteration. */
2718 403 : top_label = (!rtx_equal_p (len, iter_incr)
2719 403 : ? gen_label_rtx ()
2720 : : NULL);
2721 : /* We need not test before entering the loop if len is known
2722 : nonzero. ??? This could be even stricter, testing whether a
2723 : nonconstant LEN could possibly be zero. */
2724 403 : cmp_label = (!CONSTANT_P (len) || rtx_equal_p (len, iter_init)
2725 403 : ? gen_label_rtx ()
2726 : : NULL);
2727 403 : ne_label = gen_label_rtx ();
2728 403 : res_label = gen_label_rtx ();
2729 :
2730 403 : iter = gen_reg_rtx (iter_mode);
2731 403 : emit_move_insn (iter, iter_init);
2732 :
2733 403 : opt_scalar_int_mode int_cmp_mode
2734 403 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2735 403 : if (!int_cmp_mode.exists (&cmp_mode)
2736 1206 : || GET_MODE_BITSIZE (int_cmp_mode.require ()) != incr * BITS_PER_UNIT
2737 402 : || !can_compare_p (NE, cmp_mode, ccp_jump))
2738 : {
2739 1 : cmp_mode = BLKmode;
2740 1 : gcc_checking_assert (incr != 1);
2741 : }
2742 :
2743 : /* Save the base addresses. */
2744 403 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2745 403 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2746 403 : do_pending_stack_adjust ();
2747 :
2748 403 : if (cmp_label)
2749 : {
2750 84 : if (top_label)
2751 84 : emit_jump (cmp_label);
2752 : else
2753 0 : emit_cmp_and_jump_insns (iter, iter_limit, entry_cond,
2754 : NULL_RTX, iter_mode,
2755 : true, cmp_label,
2756 0 : profile_probability::guessed_always ()
2757 : .apply_scale (1, 10));
2758 : }
2759 403 : if (top_label)
2760 386 : emit_label (top_label);
2761 :
2762 : /* Offset the base addresses by ITER. */
2763 403 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2764 403 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2765 :
2766 403 : if (x_addr_mode != y_addr_mode)
2767 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2768 403 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2769 :
2770 403 : x = change_address (x, cmp_mode, x_addr);
2771 403 : y = change_address (y, cmp_mode, y_addr);
2772 :
2773 : /* Compare one block. */
2774 403 : rtx part_res;
2775 403 : if (cmp_mode == BLKmode)
2776 1 : part_res = compare_by_pieces (x, y, incr, target, align, 0, 0);
2777 : else
2778 402 : part_res = expand_binop (cmp_mode, sub_optab, x, y, NULL_RTX,
2779 : true, OPTAB_LIB_WIDEN);
2780 :
2781 : /* Stop if we found a difference. */
2782 806 : emit_cmp_and_jump_insns (part_res, GEN_INT (0), NE, NULL_RTX,
2783 403 : GET_MODE (part_res), true, ne_label,
2784 403 : profile_probability::guessed_always ()
2785 : .apply_scale (1, 10));
2786 :
2787 : /* Increment ITER. */
2788 403 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2789 : true, OPTAB_LIB_WIDEN);
2790 403 : if (tmp != iter)
2791 0 : emit_move_insn (iter, tmp);
2792 :
2793 403 : if (cmp_label)
2794 84 : emit_label (cmp_label);
2795 : /* Loop until we reach the limit. */
2796 :
2797 403 : if (top_label)
2798 386 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2799 : true, top_label,
2800 772 : profile_probability::guessed_always ()
2801 : .apply_scale (9, 10));
2802 :
2803 : /* We got to the end without differences, so the result is zero. */
2804 403 : if (target == NULL_RTX
2805 403 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
2806 49 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
2807 :
2808 403 : emit_move_insn (target, const0_rtx);
2809 403 : emit_jump (res_label);
2810 :
2811 403 : emit_label (ne_label);
2812 :
2813 : /* Return nonzero, or pinpoint the difference to return the expected
2814 : result for non-equality tests. */
2815 403 : if (equality_only)
2816 0 : emit_move_insn (target, const1_rtx);
2817 : else
2818 : {
2819 403 : if (incr > UNITS_PER_WORD)
2820 : /* ??? Re-compare the block found to be different one word at a
2821 : time. */
2822 5 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2823 : target, equality_only,
2824 : BITS_PER_WORD, 0);
2825 398 : else if (incr > 1)
2826 : /* ??? Re-compare the block found to be different one byte at a
2827 : time. We could do better using part_res, and being careful
2828 : about endianness. */
2829 37 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2830 : target, equality_only,
2831 : BITS_PER_UNIT, 0);
2832 1083 : else if (known_gt (GET_MODE_BITSIZE (GET_MODE (target)),
2833 : GET_MODE_BITSIZE (cmp_mode)))
2834 361 : part_res = expand_binop (GET_MODE (target), sub_optab, x, y, target,
2835 : true, OPTAB_LIB_WIDEN);
2836 : else
2837 : {
2838 : /* In the odd chance target is QImode, we can't count on
2839 : widening subtract to capture the result of the unsigned
2840 : compares. */
2841 0 : rtx_code_label *ltu_label;
2842 0 : ltu_label = gen_label_rtx ();
2843 0 : emit_cmp_and_jump_insns (x, y, LTU, NULL_RTX,
2844 : cmp_mode, true, ltu_label,
2845 0 : profile_probability::guessed_always ()
2846 : .apply_scale (5, 10));
2847 :
2848 0 : emit_move_insn (target, const1_rtx);
2849 0 : emit_jump (res_label);
2850 :
2851 0 : emit_label (ltu_label);
2852 0 : emit_move_insn (target, constm1_rtx);
2853 0 : part_res = target;
2854 : }
2855 :
2856 403 : if (target != part_res)
2857 0 : convert_move (target, part_res, false);
2858 : }
2859 :
2860 403 : emit_label (res_label);
2861 :
2862 403 : return target;
2863 : }
2864 :
2865 :
2866 : /* Copy all or part of a value X into registers starting at REGNO.
2867 : The number of registers to be filled is NREGS. */
2868 :
2869 : void
2870 434 : move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
2871 : {
2872 434 : if (nregs == 0)
2873 : return;
2874 :
2875 420 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
2876 0 : x = validize_mem (force_const_mem (mode, x));
2877 :
2878 : /* See if the machine can do this with a load multiple insn. */
2879 420 : if (targetm.have_load_multiple ())
2880 : {
2881 0 : rtx_insn *last = get_last_insn ();
2882 0 : rtx first = gen_rtx_REG (word_mode, regno);
2883 0 : if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
2884 : GEN_INT (nregs)))
2885 : {
2886 0 : emit_insn (pat);
2887 0 : return;
2888 : }
2889 : else
2890 0 : delete_insns_since (last);
2891 : }
2892 :
2893 848 : for (int i = 0; i < nregs; i++)
2894 428 : emit_move_insn (gen_rtx_REG (word_mode, regno + i),
2895 428 : operand_subword_force (x, i, mode));
2896 : }
2897 :
2898 : /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
2899 : The number of registers to be filled is NREGS. */
2900 :
2901 : void
2902 1216 : move_block_from_reg (int regno, rtx x, int nregs)
2903 : {
2904 1216 : if (nregs == 0)
2905 : return;
2906 :
2907 : /* See if the machine can do this with a store multiple insn. */
2908 1216 : if (targetm.have_store_multiple ())
2909 : {
2910 0 : rtx_insn *last = get_last_insn ();
2911 0 : rtx first = gen_rtx_REG (word_mode, regno);
2912 0 : if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
2913 : GEN_INT (nregs)))
2914 : {
2915 0 : emit_insn (pat);
2916 0 : return;
2917 : }
2918 : else
2919 0 : delete_insns_since (last);
2920 : }
2921 :
2922 2436 : for (int i = 0; i < nregs; i++)
2923 : {
2924 1220 : rtx tem = operand_subword (x, i, 1, BLKmode);
2925 :
2926 1220 : gcc_assert (tem);
2927 :
2928 1220 : emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
2929 : }
2930 : }
2931 :
2932 : /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
2933 : ORIG, where ORIG is a non-consecutive group of registers represented by
2934 : a PARALLEL. The clone is identical to the original except in that the
2935 : original set of registers is replaced by a new set of pseudo registers.
2936 : The new set has the same modes as the original set. */
2937 :
2938 : rtx
2939 3063 : gen_group_rtx (rtx orig)
2940 : {
2941 3063 : int i, length;
2942 3063 : rtx *tmps;
2943 :
2944 3063 : gcc_assert (GET_CODE (orig) == PARALLEL);
2945 :
2946 3063 : length = XVECLEN (orig, 0);
2947 3063 : tmps = XALLOCAVEC (rtx, length);
2948 :
2949 : /* Skip a NULL entry in first slot. */
2950 3063 : i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
2951 :
2952 3063 : if (i)
2953 0 : tmps[0] = 0;
2954 :
2955 7456 : for (; i < length; i++)
2956 : {
2957 4393 : machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
2958 4393 : rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
2959 :
2960 4393 : tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
2961 : }
2962 :
2963 3063 : return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
2964 : }
2965 :
2966 : /* A subroutine of emit_group_load. Arguments as for emit_group_load,
2967 : except that values are placed in TMPS[i], and must later be moved
2968 : into corresponding XEXP (XVECEXP (DST, 0, i), 0) element. */
2969 :
2970 : static void
2971 298475 : emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
2972 : poly_int64 ssize)
2973 : {
2974 298478 : rtx src;
2975 298478 : int start, i;
2976 298478 : machine_mode m = GET_MODE (orig_src);
2977 :
2978 298478 : gcc_assert (GET_CODE (dst) == PARALLEL);
2979 :
2980 298478 : if (m != VOIDmode
2981 279613 : && !SCALAR_INT_MODE_P (m)
2982 19155 : && !MEM_P (orig_src)
2983 5725 : && GET_CODE (orig_src) != CONCAT)
2984 : {
2985 3 : scalar_int_mode imode;
2986 3 : if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode))
2987 : {
2988 3 : src = gen_reg_rtx (imode);
2989 3 : emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
2990 : }
2991 : else
2992 : {
2993 0 : src = assign_stack_temp (GET_MODE (orig_src), ssize);
2994 0 : emit_move_insn (src, orig_src);
2995 : }
2996 3 : emit_group_load_1 (tmps, dst, src, type, ssize);
2997 : return;
2998 : }
2999 :
3000 : /* Check for a NULL entry, used to indicate that the parameter goes
3001 : both on the stack and in registers. */
3002 298475 : if (XEXP (XVECEXP (dst, 0, 0), 0))
3003 : start = 0;
3004 : else
3005 0 : start = 1;
3006 :
3007 : /* Process the pieces. */
3008 883932 : for (i = start; i < XVECLEN (dst, 0); i++)
3009 : {
3010 585457 : machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
3011 585457 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
3012 1170914 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3013 585457 : poly_int64 shift = 0;
3014 :
3015 : /* Handle trailing fragments that run over the size of the struct.
3016 : It's the target's responsibility to make sure that the fragment
3017 : cannot be strictly smaller in some cases and strictly larger
3018 : in others. */
3019 585457 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3020 585457 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3021 : {
3022 : /* Arrange to shift the fragment to where it belongs.
3023 : extract_bit_field loads to the lsb of the reg. */
3024 : if (
3025 : #ifdef BLOCK_REG_PADDING
3026 : BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
3027 : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3028 : #else
3029 : BYTES_BIG_ENDIAN
3030 : #endif
3031 : )
3032 : shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3033 1836 : bytelen = ssize - bytepos;
3034 1836 : gcc_assert (maybe_gt (bytelen, 0));
3035 : }
3036 :
3037 : /* If we won't be loading directly from memory, protect the real source
3038 : from strange tricks we might play; but make sure that the source can
3039 : be loaded directly into the destination. */
3040 585457 : src = orig_src;
3041 585457 : if (!MEM_P (orig_src)
3042 484735 : && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
3043 46417 : && GET_CODE (orig_src) != CONCAT
3044 623187 : && !CONSTANT_P (orig_src))
3045 : {
3046 0 : gcc_assert (GET_MODE (orig_src) != VOIDmode);
3047 0 : src = force_reg (GET_MODE (orig_src), orig_src);
3048 : }
3049 :
3050 : /* Optimize the access just a bit. */
3051 585457 : if (MEM_P (src)
3052 100722 : && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
3053 0 : || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
3054 201444 : && multiple_p (bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
3055 686179 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3056 : {
3057 98905 : tmps[i] = gen_reg_rtx (mode);
3058 98905 : emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
3059 : }
3060 486552 : else if (COMPLEX_MODE_P (mode)
3061 0 : && GET_MODE (src) == mode
3062 486552 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3063 : /* Let emit_move_complex do the bulk of the work. */
3064 0 : tmps[i] = src;
3065 486552 : else if (SCALAR_INT_MODE_P (mode)
3066 479995 : && COMPLEX_MODE_P (GET_MODE (src))
3067 9372 : && known_eq (GET_MODE_SIZE (mode),
3068 : GET_MODE_SIZE (GET_MODE (src)))
3069 489290 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3070 : {
3071 : /* When passing a complex value in an integer mode of the same
3072 : size, explicitly construct (highpart<<isize)+lowpart to
3073 : avoid spilling to memory before reload. */
3074 2738 : rtx tmp = read_complex_part (src, !BYTES_BIG_ENDIAN);
3075 2738 : scalar_int_mode imode = int_mode_for_mode (GET_MODE (tmp)).require();
3076 2738 : tmp = gen_lowpart (imode, tmp);
3077 2738 : tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
3078 2738 : rtx result = force_reg (mode, tmp);
3079 5476 : result = expand_shift (LSHIFT_EXPR, mode, result,
3080 2738 : GET_MODE_BITSIZE (imode), NULL_RTX, 1);
3081 2738 : tmp = read_complex_part (src, BYTES_BIG_ENDIAN);
3082 2738 : tmp = gen_lowpart (imode, tmp);
3083 2738 : tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
3084 2738 : result = simplify_gen_binary (PLUS, mode, result, tmp);
3085 2738 : tmps[i] = force_reg (mode, result);
3086 : }
3087 483814 : else if (GET_CODE (src) == CONCAT)
3088 : {
3089 11898 : poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
3090 11898 : poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
3091 5949 : unsigned int elt;
3092 5949 : poly_int64 subpos;
3093 :
3094 5949 : if (can_div_trunc_p (bytepos, slen0, &elt, &subpos)
3095 5949 : && known_le (subpos + bytelen, slen0))
3096 : {
3097 : /* The following assumes that the concatenated objects all
3098 : have the same size. In this case, a simple calculation
3099 : can be used to determine the object and the bit field
3100 : to be extracted. */
3101 5930 : tmps[i] = XEXP (src, elt);
3102 5930 : if (maybe_ne (subpos, 0)
3103 5930 : || maybe_ne (subpos + bytelen, slen0)
3104 11860 : || (!CONSTANT_P (tmps[i])
3105 5930 : && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
3106 0 : tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
3107 0 : subpos * BITS_PER_UNIT,
3108 : 1, NULL_RTX, mode, mode, false,
3109 : NULL);
3110 : }
3111 : else
3112 : {
3113 19 : rtx mem;
3114 :
3115 19 : gcc_assert (known_eq (bytepos, 0));
3116 19 : mem = assign_stack_temp (GET_MODE (src), slen);
3117 19 : emit_move_insn (mem, src);
3118 19 : tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
3119 : 0, 1, NULL_RTX, mode, mode, false,
3120 : NULL);
3121 : }
3122 : }
3123 477865 : else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
3124 37730 : && XVECLEN (dst, 0) > 1)
3125 37730 : tmps[i] = force_subreg (mode, src, GET_MODE (dst), bytepos);
3126 440135 : else if (CONSTANT_P (src))
3127 : {
3128 0 : if (known_eq (bytelen, ssize))
3129 0 : tmps[i] = src;
3130 : else
3131 : {
3132 : rtx first, second;
3133 :
3134 : /* TODO: const_wide_int can have sizes other than this... */
3135 0 : gcc_assert (known_eq (2 * bytelen, ssize));
3136 0 : split_double (src, &first, &second);
3137 0 : if (i)
3138 0 : tmps[i] = second;
3139 : else
3140 0 : tmps[i] = first;
3141 : }
3142 : }
3143 440135 : else if (REG_P (src) && GET_MODE (src) == mode)
3144 0 : tmps[i] = src;
3145 : else
3146 440135 : tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
3147 880270 : bytepos * BITS_PER_UNIT, 1, NULL_RTX,
3148 : mode, mode, false, NULL);
3149 :
3150 585457 : if (maybe_ne (shift, 0))
3151 : tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
3152 : shift, tmps[i], 0);
3153 : }
3154 : }
3155 :
3156 : /* Emit code to move a block SRC of type TYPE to a block DST,
3157 : where DST is non-consecutive registers represented by a PARALLEL.
3158 : SSIZE represents the total size of block ORIG_SRC in bytes, or -1
3159 : if not known. */
3160 :
3161 : void
3162 10915 : emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
3163 : {
3164 10915 : rtx *tmps;
3165 10915 : int i;
3166 :
3167 10915 : tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
3168 10915 : emit_group_load_1 (tmps, dst, src, type, ssize);
3169 :
3170 : /* Copy the extracted pieces into the proper (probable) hard regs. */
3171 30473 : for (i = 0; i < XVECLEN (dst, 0); i++)
3172 : {
3173 19558 : rtx d = XEXP (XVECEXP (dst, 0, i), 0);
3174 19558 : if (d == NULL)
3175 0 : continue;
3176 19558 : emit_move_insn (d, tmps[i]);
3177 : }
3178 10915 : }
3179 :
3180 : /* Similar, but load SRC into new pseudos in a format that looks like
3181 : PARALLEL. This can later be fed to emit_group_move to get things
3182 : in the right place. */
3183 :
3184 : rtx
3185 287560 : emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
3186 : {
3187 287560 : rtvec vec;
3188 287560 : int i;
3189 :
3190 287560 : vec = rtvec_alloc (XVECLEN (parallel, 0));
3191 287560 : emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
3192 :
3193 : /* Convert the vector to look just like the original PARALLEL, except
3194 : with the computed values. */
3195 853459 : for (i = 0; i < XVECLEN (parallel, 0); i++)
3196 : {
3197 565899 : rtx e = XVECEXP (parallel, 0, i);
3198 565899 : rtx d = XEXP (e, 0);
3199 :
3200 565899 : if (d)
3201 : {
3202 565899 : d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
3203 565899 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
3204 : }
3205 565899 : RTVEC_ELT (vec, i) = e;
3206 : }
3207 :
3208 287560 : return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
3209 : }
3210 :
3211 : /* Emit code to move a block SRC to block DST, where SRC and DST are
3212 : non-consecutive groups of registers, each represented by a PARALLEL. */
3213 :
3214 : void
3215 290623 : emit_group_move (rtx dst, rtx src)
3216 : {
3217 290623 : int i;
3218 :
3219 290623 : gcc_assert (GET_CODE (src) == PARALLEL
3220 : && GET_CODE (dst) == PARALLEL
3221 : && XVECLEN (src, 0) == XVECLEN (dst, 0));
3222 :
3223 : /* Skip first entry if NULL. */
3224 860915 : for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
3225 570292 : emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
3226 570292 : XEXP (XVECEXP (src, 0, i), 0));
3227 290623 : }
3228 :
3229 : /* Move a group of registers represented by a PARALLEL into pseudos. */
3230 :
3231 : rtx
3232 5799 : emit_group_move_into_temps (rtx src)
3233 : {
3234 5799 : rtvec vec = rtvec_alloc (XVECLEN (src, 0));
3235 5799 : int i;
3236 :
3237 13629 : for (i = 0; i < XVECLEN (src, 0); i++)
3238 : {
3239 7830 : rtx e = XVECEXP (src, 0, i);
3240 7830 : rtx d = XEXP (e, 0);
3241 :
3242 7830 : if (d)
3243 7830 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
3244 7830 : RTVEC_ELT (vec, i) = e;
3245 : }
3246 :
3247 5799 : return gen_rtx_PARALLEL (GET_MODE (src), vec);
3248 : }
3249 :
3250 : /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
3251 : where SRC is non-consecutive registers represented by a PARALLEL.
3252 : SSIZE represents the total size of block ORIG_DST, or -1 if not
3253 : known. */
3254 :
3255 : void
3256 65505 : emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
3257 : poly_int64 ssize)
3258 : {
3259 65505 : rtx *tmps, dst;
3260 65505 : int start, finish, i;
3261 65505 : machine_mode m = GET_MODE (orig_dst);
3262 :
3263 65505 : gcc_assert (GET_CODE (src) == PARALLEL);
3264 :
3265 65505 : if (!SCALAR_INT_MODE_P (m)
3266 14311 : && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
3267 : {
3268 0 : scalar_int_mode imode;
3269 0 : if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode))
3270 : {
3271 0 : dst = gen_reg_rtx (imode);
3272 0 : emit_group_store (dst, src, type, ssize);
3273 0 : dst = gen_lowpart (GET_MODE (orig_dst), dst);
3274 : }
3275 : else
3276 : {
3277 0 : dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
3278 0 : emit_group_store (dst, src, type, ssize);
3279 : }
3280 0 : emit_move_insn (orig_dst, dst);
3281 0 : return;
3282 : }
3283 :
3284 : /* Check for a NULL entry, used to indicate that the parameter goes
3285 : both on the stack and in registers. */
3286 65505 : if (XEXP (XVECEXP (src, 0, 0), 0))
3287 : start = 0;
3288 : else
3289 0 : start = 1;
3290 65505 : finish = XVECLEN (src, 0);
3291 :
3292 65505 : tmps = XALLOCAVEC (rtx, finish);
3293 :
3294 : /* Copy the (probable) hard regs into pseudos. */
3295 188303 : for (i = start; i < finish; i++)
3296 : {
3297 122798 : rtx reg = XEXP (XVECEXP (src, 0, i), 0);
3298 122798 : if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
3299 : {
3300 114968 : tmps[i] = gen_reg_rtx (GET_MODE (reg));
3301 114968 : emit_move_insn (tmps[i], reg);
3302 : }
3303 : else
3304 7830 : tmps[i] = reg;
3305 : }
3306 :
3307 : /* If we won't be storing directly into memory, protect the real destination
3308 : from strange tricks we might play. */
3309 65505 : dst = orig_dst;
3310 65505 : if (GET_CODE (dst) == PARALLEL)
3311 : {
3312 0 : rtx temp;
3313 :
3314 : /* We can get a PARALLEL dst if there is a conditional expression in
3315 : a return statement. In that case, the dst and src are the same,
3316 : so no action is necessary. */
3317 0 : if (rtx_equal_p (dst, src))
3318 : return;
3319 :
3320 : /* It is unclear if we can ever reach here, but we may as well handle
3321 : it. Allocate a temporary, and split this into a store/load to/from
3322 : the temporary. */
3323 0 : temp = assign_stack_temp (GET_MODE (dst), ssize);
3324 0 : emit_group_store (temp, src, type, ssize);
3325 0 : emit_group_load (dst, temp, type, ssize);
3326 0 : return;
3327 : }
3328 65505 : else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
3329 : {
3330 50560 : machine_mode outer = GET_MODE (dst);
3331 50560 : machine_mode inner;
3332 50560 : poly_int64 bytepos;
3333 50560 : bool done = false;
3334 50560 : rtx temp;
3335 :
3336 50560 : if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
3337 0 : dst = gen_reg_rtx (outer);
3338 :
3339 : /* Make life a bit easier for combine: if the first element of the
3340 : vector is the low part of the destination mode, use a paradoxical
3341 : subreg to initialize the destination. */
3342 50560 : if (start < finish)
3343 : {
3344 50560 : inner = GET_MODE (tmps[start]);
3345 50560 : bytepos = subreg_lowpart_offset (inner, outer);
3346 50560 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
3347 : bytepos))
3348 : {
3349 50536 : temp = force_subreg (outer, tmps[start], inner, 0);
3350 50536 : if (temp)
3351 : {
3352 49864 : emit_move_insn (dst, temp);
3353 49864 : done = true;
3354 49864 : start++;
3355 : }
3356 : }
3357 : }
3358 :
3359 : /* If the first element wasn't the low part, try the last. */
3360 49864 : if (!done
3361 696 : && start < finish - 1)
3362 : {
3363 629 : inner = GET_MODE (tmps[finish - 1]);
3364 629 : bytepos = subreg_lowpart_offset (inner, outer);
3365 629 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
3366 : finish - 1), 1)),
3367 : bytepos))
3368 : {
3369 0 : temp = force_subreg (outer, tmps[finish - 1], inner, 0);
3370 0 : if (temp)
3371 : {
3372 0 : emit_move_insn (dst, temp);
3373 0 : done = true;
3374 0 : finish--;
3375 : }
3376 : }
3377 : }
3378 :
3379 : /* Otherwise, simply initialize the result to zero. */
3380 49864 : if (!done)
3381 696 : emit_move_insn (dst, CONST0_RTX (outer));
3382 : }
3383 :
3384 : /* Process the pieces. */
3385 135007 : for (i = start; i < finish; i++)
3386 : {
3387 72934 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
3388 72934 : machine_mode mode = GET_MODE (tmps[i]);
3389 145868 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3390 72934 : poly_uint64 adj_bytelen;
3391 72934 : rtx dest = dst;
3392 :
3393 : /* Handle trailing fragments that run over the size of the struct.
3394 : It's the target's responsibility to make sure that the fragment
3395 : cannot be strictly smaller in some cases and strictly larger
3396 : in others. */
3397 72934 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3398 144918 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3399 950 : adj_bytelen = ssize - bytepos;
3400 : else
3401 72934 : adj_bytelen = bytelen;
3402 :
3403 : /* Deal with destination CONCATs by either storing into one of the parts
3404 : or doing a copy after storing into a register or stack temporary. */
3405 72934 : if (GET_CODE (dst) == CONCAT)
3406 : {
3407 28280 : if (known_le (bytepos + adj_bytelen,
3408 : GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3409 : dest = XEXP (dst, 0);
3410 :
3411 17572 : else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3412 : {
3413 10708 : bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
3414 5354 : dest = XEXP (dst, 1);
3415 : }
3416 :
3417 : else
3418 : {
3419 3432 : machine_mode dest_mode = GET_MODE (dest);
3420 3432 : machine_mode tmp_mode = GET_MODE (tmps[i]);
3421 3432 : scalar_int_mode dest_imode;
3422 :
3423 3432 : gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
3424 :
3425 : /* If the source is a single scalar integer register, and the
3426 : destination has a complex mode for which a same-sized integer
3427 : mode exists, then we can take the left-justified part of the
3428 : source in the complex mode. */
3429 3432 : if (finish == start + 1
3430 3432 : && REG_P (tmps[i])
3431 3432 : && SCALAR_INT_MODE_P (tmp_mode)
3432 3432 : && COMPLEX_MODE_P (dest_mode)
3433 6864 : && int_mode_for_mode (dest_mode).exists (&dest_imode))
3434 : {
3435 3432 : const scalar_int_mode tmp_imode
3436 3432 : = as_a <scalar_int_mode> (tmp_mode);
3437 :
3438 6864 : if (GET_MODE_BITSIZE (dest_imode)
3439 3432 : < GET_MODE_BITSIZE (tmp_imode))
3440 : {
3441 59 : dest = gen_reg_rtx (dest_imode);
3442 59 : if (BYTES_BIG_ENDIAN)
3443 : tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
3444 : GET_MODE_BITSIZE (tmp_imode)
3445 : - GET_MODE_BITSIZE (dest_imode),
3446 : NULL_RTX, 1);
3447 59 : emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
3448 59 : dst = gen_lowpart (dest_mode, dest);
3449 : }
3450 : else
3451 3373 : dst = gen_lowpart (dest_mode, tmps[i]);
3452 : }
3453 :
3454 : /* Otherwise spill the source onto the stack using the more
3455 : aligned of the two modes. */
3456 0 : else if (GET_MODE_ALIGNMENT (dest_mode)
3457 0 : >= GET_MODE_ALIGNMENT (tmp_mode))
3458 : {
3459 0 : dest = assign_stack_temp (dest_mode,
3460 0 : GET_MODE_SIZE (dest_mode));
3461 0 : emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
3462 : tmps[i]);
3463 0 : dst = dest;
3464 : }
3465 :
3466 : else
3467 : {
3468 0 : dest = assign_stack_temp (tmp_mode,
3469 0 : GET_MODE_SIZE (tmp_mode));
3470 0 : emit_move_insn (dest, tmps[i]);
3471 0 : dst = adjust_address (dest, dest_mode, bytepos);
3472 : }
3473 :
3474 : break;
3475 : }
3476 : }
3477 :
3478 : /* Handle trailing fragments that run over the size of the struct. */
3479 69502 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3480 : {
3481 : /* store_bit_field always takes its value from the lsb.
3482 : Move the fragment to the lsb if it's not already there. */
3483 891 : if (
3484 : #ifdef BLOCK_REG_PADDING
3485 : BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
3486 : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3487 : #else
3488 : BYTES_BIG_ENDIAN
3489 : #endif
3490 : )
3491 : {
3492 : poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3493 : tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
3494 : shift, tmps[i], 0);
3495 : }
3496 :
3497 : /* Make sure not to write past the end of the struct. */
3498 891 : store_bit_field (dest,
3499 891 : adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3500 2673 : bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
3501 : VOIDmode, tmps[i], false, false);
3502 : }
3503 :
3504 : /* Optimize the access just a bit. */
3505 68611 : else if (MEM_P (dest)
3506 7547 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
3507 0 : || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
3508 15094 : && multiple_p (bytepos * BITS_PER_UNIT,
3509 : GET_MODE_ALIGNMENT (mode))
3510 76158 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3511 7547 : emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
3512 :
3513 : else
3514 122128 : store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3515 : 0, 0, mode, tmps[i], false, false);
3516 : }
3517 :
3518 : /* Copy from the pseudo into the (probable) hard reg. */
3519 65505 : if (orig_dst != dst)
3520 3432 : emit_move_insn (orig_dst, dst);
3521 : }
3522 :
3523 : /* Return a form of X that does not use a PARALLEL. TYPE is the type
3524 : of the value stored in X. */
3525 :
3526 : rtx
3527 335317 : maybe_emit_group_store (rtx x, tree type)
3528 : {
3529 335317 : machine_mode mode = TYPE_MODE (type);
3530 335317 : gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
3531 335317 : if (GET_CODE (x) == PARALLEL)
3532 : {
3533 0 : rtx result = gen_reg_rtx (mode);
3534 0 : emit_group_store (result, x, type, int_size_in_bytes (type));
3535 0 : return result;
3536 : }
3537 : return x;
3538 : }
3539 :
3540 : /* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
3541 :
3542 : This is used on targets that return BLKmode values in registers. */
3543 :
3544 : static void
3545 256 : copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
3546 : {
3547 256 : unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
3548 256 : rtx src = NULL, dst = NULL;
3549 256 : unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
3550 256 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
3551 : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3552 256 : fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
3553 256 : fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
3554 256 : fixed_size_mode copy_mode;
3555 :
3556 : /* BLKmode registers created in the back-end shouldn't have survived. */
3557 256 : gcc_assert (mode != BLKmode);
3558 :
3559 : /* If the structure doesn't take up a whole number of words, see whether
3560 : SRCREG is padded on the left or on the right. If it's on the left,
3561 : set PADDING_CORRECTION to the number of bits to skip.
3562 :
3563 : In most ABIs, the structure will be returned at the least end of
3564 : the register, which translates to right padding on little-endian
3565 : targets and left padding on big-endian targets. The opposite
3566 : holds if the structure is returned at the most significant
3567 : end of the register. */
3568 256 : if (bytes % UNITS_PER_WORD != 0
3569 256 : && (targetm.calls.return_in_msb (type)
3570 225 : ? !BYTES_BIG_ENDIAN
3571 : : BYTES_BIG_ENDIAN))
3572 0 : padding_correction
3573 0 : = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
3574 :
3575 : /* We can use a single move if we have an exact mode for the size. */
3576 256 : else if (MEM_P (target)
3577 256 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
3578 0 : || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
3579 512 : && bytes == GET_MODE_SIZE (mode))
3580 : {
3581 38 : emit_move_insn (adjust_address (target, mode, 0), srcreg);
3582 38 : return;
3583 : }
3584 :
3585 : /* And if we additionally have the same mode for a register. */
3586 218 : else if (REG_P (target)
3587 0 : && GET_MODE (target) == mode
3588 218 : && bytes == GET_MODE_SIZE (mode))
3589 : {
3590 0 : emit_move_insn (target, srcreg);
3591 0 : return;
3592 : }
3593 :
3594 : /* This code assumes srcreg is at least a full word. If it isn't, copy it
3595 : into a new pseudo which is a full word. */
3596 436 : if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3597 : {
3598 77 : srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
3599 77 : mode = word_mode;
3600 : }
3601 :
3602 : /* Copy the structure BITSIZE bits at a time. If the target lives in
3603 : memory, take care of not reading/writing past its end by selecting
3604 : a copy mode suited to BITSIZE. This should always be possible given
3605 : how it is computed.
3606 :
3607 : If the target lives in register, make sure not to select a copy mode
3608 : larger than the mode of the register.
3609 :
3610 : We could probably emit more efficient code for machines which do not use
3611 : strict alignment, but it doesn't seem worth the effort at the current
3612 : time. */
3613 :
3614 218 : copy_mode = word_mode;
3615 218 : if (MEM_P (target))
3616 : {
3617 218 : opt_scalar_int_mode mem_mode = int_mode_for_size (bitsize, 1);
3618 218 : if (mem_mode.exists ())
3619 218 : copy_mode = mem_mode.require ();
3620 : }
3621 0 : else if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3622 : copy_mode = tmode;
3623 :
3624 218 : for (bitpos = 0, xbitpos = padding_correction;
3625 1068 : bitpos < bytes * BITS_PER_UNIT;
3626 850 : bitpos += bitsize, xbitpos += bitsize)
3627 : {
3628 : /* We need a new source operand each time xbitpos is on a
3629 : word boundary and when xbitpos == padding_correction
3630 : (the first time through). */
3631 850 : if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
3632 218 : src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
3633 :
3634 : /* We need a new destination operand each time bitpos is on
3635 : a word boundary. */
3636 850 : if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3637 : dst = target;
3638 850 : else if (bitpos % BITS_PER_WORD == 0)
3639 218 : dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
3640 :
3641 : /* Use xbitpos for the source extraction (right justified) and
3642 : bitpos for the destination store (left justified). */
3643 850 : store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
3644 850 : extract_bit_field (src, bitsize,
3645 850 : xbitpos % BITS_PER_WORD, 1,
3646 : NULL_RTX, copy_mode, copy_mode,
3647 : false, NULL),
3648 : false, false);
3649 : }
3650 : }
3651 :
3652 : /* Copy BLKmode value SRC into a register of mode MODE_IN. Return the
3653 : register if it contains any data, otherwise return null.
3654 :
3655 : This is used on targets that return BLKmode values in registers. */
3656 :
3657 : rtx
3658 3511 : copy_blkmode_to_reg (machine_mode mode_in, tree src)
3659 : {
3660 3511 : int i, n_regs;
3661 3511 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
3662 3511 : unsigned int bitsize;
3663 3511 : rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
3664 : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3665 3511 : fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
3666 3511 : fixed_size_mode dst_mode;
3667 3511 : scalar_int_mode min_mode;
3668 :
3669 3511 : gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
3670 :
3671 3511 : x = expand_normal (src);
3672 :
3673 3511 : bytes = arg_int_size_in_bytes (TREE_TYPE (src));
3674 3511 : if (bytes == 0)
3675 : return NULL_RTX;
3676 :
3677 : /* If the structure doesn't take up a whole number of words, see
3678 : whether the register value should be padded on the left or on
3679 : the right. Set PADDING_CORRECTION to the number of padding
3680 : bits needed on the left side.
3681 :
3682 : In most ABIs, the structure will be returned at the least end of
3683 : the register, which translates to right padding on little-endian
3684 : targets and left padding on big-endian targets. The opposite
3685 : holds if the structure is returned at the most significant
3686 : end of the register. */
3687 1224 : if (bytes % UNITS_PER_WORD != 0
3688 1224 : && (targetm.calls.return_in_msb (TREE_TYPE (src))
3689 1188 : ? !BYTES_BIG_ENDIAN
3690 : : BYTES_BIG_ENDIAN))
3691 0 : padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
3692 0 : * BITS_PER_UNIT));
3693 :
3694 1224 : n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3695 1224 : dst_words = XALLOCAVEC (rtx, n_regs);
3696 1224 : bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
3697 1224 : min_mode = smallest_int_mode_for_size (bitsize).require ();
3698 :
3699 : /* Copy the structure BITSIZE bits at a time. */
3700 1224 : for (bitpos = 0, xbitpos = padding_correction;
3701 3974 : bitpos < bytes * BITS_PER_UNIT;
3702 2750 : bitpos += bitsize, xbitpos += bitsize)
3703 : {
3704 : /* We need a new destination pseudo each time xbitpos is
3705 : on a word boundary and when xbitpos == padding_correction
3706 : (the first time through). */
3707 2750 : if (xbitpos % BITS_PER_WORD == 0
3708 1523 : || xbitpos == padding_correction)
3709 : {
3710 : /* Generate an appropriate register. */
3711 1227 : dst_word = gen_reg_rtx (word_mode);
3712 1227 : dst_words[xbitpos / BITS_PER_WORD] = dst_word;
3713 :
3714 : /* Clear the destination before we move anything into it. */
3715 1227 : emit_move_insn (dst_word, CONST0_RTX (word_mode));
3716 : }
3717 :
3718 : /* Find the largest integer mode that can be used to copy all or as
3719 : many bits as possible of the structure if the target supports larger
3720 : copies. There are too many corner cases here w.r.t to alignments on
3721 : the read/writes. So if there is any padding just use single byte
3722 : operations. */
3723 2750 : opt_scalar_int_mode mode_iter;
3724 2750 : if (padding_correction == 0 && !STRICT_ALIGNMENT)
3725 : {
3726 7488 : FOR_EACH_MODE_FROM (mode_iter, min_mode)
3727 : {
3728 7488 : unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
3729 7488 : if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
3730 4741 : && msize <= BITS_PER_WORD)
3731 4738 : bitsize = msize;
3732 : else
3733 : break;
3734 : }
3735 : }
3736 :
3737 : /* We need a new source operand each time bitpos is on a word
3738 : boundary. */
3739 2750 : if (bitpos % BITS_PER_WORD == 0)
3740 1227 : src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
3741 :
3742 : /* Use bitpos for the source extraction (left justified) and
3743 : xbitpos for the destination store (right justified). */
3744 5500 : store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
3745 : 0, 0, word_mode,
3746 2750 : extract_bit_field (src_word, bitsize,
3747 2750 : bitpos % BITS_PER_WORD, 1,
3748 : NULL_RTX, word_mode, word_mode,
3749 : false, NULL),
3750 : false, false);
3751 : }
3752 :
3753 1224 : if (mode == BLKmode)
3754 : {
3755 : /* Find the smallest integer mode large enough to hold the
3756 : entire structure. */
3757 0 : opt_scalar_int_mode mode_iter;
3758 0 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3759 0 : if (GET_MODE_SIZE (mode_iter.require ()) >= bytes)
3760 : break;
3761 :
3762 : /* A suitable mode should have been found. */
3763 0 : mode = mode_iter.require ();
3764 : }
3765 :
3766 3672 : if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
3767 : dst_mode = word_mode;
3768 : else
3769 498 : dst_mode = mode;
3770 1224 : dst = gen_reg_rtx (dst_mode);
3771 :
3772 3675 : for (i = 0; i < n_regs; i++)
3773 1227 : emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
3774 :
3775 1224 : if (mode != dst_mode)
3776 726 : dst = gen_lowpart (mode, dst);
3777 :
3778 : return dst;
3779 : }
3780 :
3781 : /* Add a USE expression for REG to the (possibly empty) list pointed
3782 : to by CALL_FUSAGE. REG must denote a hard register. */
3783 :
3784 : void
3785 11593819 : use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3786 : {
3787 11593819 : gcc_assert (REG_P (reg));
3788 :
3789 11593819 : if (!HARD_REGISTER_P (reg))
3790 : return;
3791 :
3792 11593819 : *call_fusage
3793 11593819 : = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
3794 : }
3795 :
3796 : /* Add a CLOBBER expression for REG to the (possibly empty) list pointed
3797 : to by CALL_FUSAGE. REG must denote a hard register. */
3798 :
3799 : void
3800 0 : clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3801 : {
3802 0 : gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
3803 :
3804 0 : *call_fusage
3805 0 : = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
3806 0 : }
3807 :
3808 : /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
3809 : starting at REGNO. All of these registers must be hard registers. */
3810 :
3811 : void
3812 1608 : use_regs (rtx *call_fusage, int regno, int nregs)
3813 : {
3814 1608 : int i;
3815 :
3816 1608 : gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
3817 :
3818 3224 : for (i = 0; i < nregs; i++)
3819 1616 : use_reg (call_fusage, regno_reg_rtx[regno + i]);
3820 1608 : }
3821 :
3822 : /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
3823 : PARALLEL REGS. This is for calls that pass values in multiple
3824 : non-contiguous locations. The Irix 6 ABI has examples of this. */
3825 :
3826 : void
3827 294333 : use_group_regs (rtx *call_fusage, rtx regs)
3828 : {
3829 294333 : int i;
3830 :
3831 873778 : for (i = 0; i < XVECLEN (regs, 0); i++)
3832 : {
3833 579445 : rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
3834 :
3835 : /* A NULL entry means the parameter goes both on the stack and in
3836 : registers. This can also be a MEM for targets that pass values
3837 : partially on the stack and partially in registers. */
3838 579445 : if (reg != 0 && REG_P (reg))
3839 579445 : use_reg (call_fusage, reg);
3840 : }
3841 294333 : }
3842 :
3843 : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3844 : assignment and the code of the expression on the RHS is CODE. Return
3845 : NULL otherwise. */
3846 :
3847 : static gimple *
3848 12022972 : get_def_for_expr (tree name, enum tree_code code)
3849 : {
3850 12022972 : gimple *def_stmt;
3851 :
3852 12022972 : if (TREE_CODE (name) != SSA_NAME)
3853 : return NULL;
3854 :
3855 9356964 : def_stmt = get_gimple_for_ssa_name (name);
3856 9356964 : if (!def_stmt
3857 2007370 : || !is_gimple_assign (def_stmt)
3858 11362875 : || gimple_assign_rhs_code (def_stmt) != code)
3859 : return NULL;
3860 :
3861 : return def_stmt;
3862 : }
3863 :
3864 : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3865 : assignment and the class of the expression on the RHS is CLASS. Return
3866 : NULL otherwise. */
3867 :
3868 : static gimple *
3869 16656 : get_def_for_expr_class (tree name, enum tree_code_class tclass)
3870 : {
3871 16656 : gimple *def_stmt;
3872 :
3873 16656 : if (TREE_CODE (name) != SSA_NAME)
3874 : return NULL;
3875 :
3876 16656 : def_stmt = get_gimple_for_ssa_name (name);
3877 16656 : if (!def_stmt
3878 14563 : || !is_gimple_assign (def_stmt)
3879 31219 : || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
3880 : return NULL;
3881 :
3882 : return def_stmt;
3883 : }
3884 :
3885 : /* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is
3886 : its length in bytes. */
3887 :
3888 : rtx
3889 157149 : clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
3890 : unsigned int expected_align, HOST_WIDE_INT expected_size,
3891 : unsigned HOST_WIDE_INT min_size,
3892 : unsigned HOST_WIDE_INT max_size,
3893 : unsigned HOST_WIDE_INT probable_max_size,
3894 : unsigned ctz_size)
3895 : {
3896 157149 : machine_mode mode = GET_MODE (object);
3897 157149 : unsigned int align;
3898 :
3899 157149 : gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
3900 :
3901 : /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
3902 : just move a zero. Otherwise, do this a piece at a time. */
3903 157149 : poly_int64 size_val;
3904 157149 : if (mode != BLKmode
3905 57337 : && poly_int_rtx_p (size, &size_val)
3906 214486 : && known_eq (size_val, GET_MODE_SIZE (mode)))
3907 : {
3908 57337 : rtx zero = CONST0_RTX (mode);
3909 57337 : if (zero != NULL)
3910 : {
3911 57337 : emit_move_insn (object, zero);
3912 57337 : return NULL;
3913 : }
3914 :
3915 0 : if (COMPLEX_MODE_P (mode))
3916 : {
3917 0 : zero = CONST0_RTX (GET_MODE_INNER (mode));
3918 0 : if (zero != NULL)
3919 : {
3920 0 : write_complex_part (object, zero, 0, true);
3921 0 : write_complex_part (object, zero, 1, false);
3922 0 : return NULL;
3923 : }
3924 : }
3925 : }
3926 :
3927 99812 : if (size == const0_rtx)
3928 : return NULL;
3929 :
3930 99811 : align = MEM_ALIGN (object);
3931 :
3932 99811 : if (CONST_INT_P (size)
3933 192290 : && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
3934 : CLEAR_BY_PIECES,
3935 92479 : optimize_insn_for_speed_p ()))
3936 71584 : clear_by_pieces (object, INTVAL (size), align);
3937 28227 : else if (set_storage_via_setmem (object, size, const0_rtx, align,
3938 : expected_align, expected_size,
3939 : min_size, max_size, probable_max_size))
3940 : ;
3941 16069 : else if (try_store_by_multiple_pieces (object, size, ctz_size,
3942 : min_size, max_size,
3943 : NULL_RTX, 0, align))
3944 : ;
3945 15805 : else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
3946 15805 : return set_storage_via_libcall (object, size, const0_rtx,
3947 15805 : method == BLOCK_OP_TAILCALL);
3948 : else
3949 0 : gcc_unreachable ();
3950 :
3951 : return NULL;
3952 : }
3953 :
3954 : rtx
3955 110308 : clear_storage (rtx object, rtx size, enum block_op_methods method)
3956 : {
3957 110308 : unsigned HOST_WIDE_INT max, min = 0;
3958 110308 : if (GET_CODE (size) == CONST_INT)
3959 110308 : min = max = UINTVAL (size);
3960 : else
3961 0 : max = GET_MODE_MASK (GET_MODE (size));
3962 110308 : return clear_storage_hints (object, size, method, 0, -1, min, max, max, 0);
3963 : }
3964 :
3965 :
3966 : /* A subroutine of clear_storage. Expand a call to memset.
3967 : Return the return value of memset, 0 otherwise. */
3968 :
3969 : rtx
3970 15806 : set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
3971 : {
3972 15806 : tree call_expr, fn, object_tree, size_tree, val_tree;
3973 15806 : machine_mode size_mode;
3974 :
3975 15806 : object = copy_addr_to_reg (XEXP (object, 0));
3976 15806 : object_tree = make_tree (ptr_type_node, object);
3977 :
3978 15806 : if (!CONST_INT_P (val))
3979 0 : val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
3980 15806 : val_tree = make_tree (integer_type_node, val);
3981 :
3982 15806 : size_mode = TYPE_MODE (sizetype);
3983 15806 : size = convert_to_mode (size_mode, size, 1);
3984 15806 : size = copy_to_mode_reg (size_mode, size);
3985 15806 : size_tree = make_tree (sizetype, size);
3986 :
3987 : /* It is incorrect to use the libcall calling conventions for calls to
3988 : memset because it can be provided by the user. */
3989 15806 : fn = builtin_decl_implicit (BUILT_IN_MEMSET);
3990 15806 : call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
3991 15806 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
3992 :
3993 15806 : return expand_call (call_expr, NULL_RTX, false);
3994 : }
3995 :
3996 : /* Expand a setmem pattern; return true if successful. */
3997 :
3998 : bool
3999 36670 : set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
4000 : unsigned int expected_align, HOST_WIDE_INT expected_size,
4001 : unsigned HOST_WIDE_INT min_size,
4002 : unsigned HOST_WIDE_INT max_size,
4003 : unsigned HOST_WIDE_INT probable_max_size)
4004 : {
4005 : /* Try the most limited insn first, because there's no point
4006 : including more than one in the machine description unless
4007 : the more limited one has some advantage. */
4008 :
4009 36670 : if (expected_align < align)
4010 : expected_align = align;
4011 36670 : if (expected_size != -1)
4012 : {
4013 8 : if ((unsigned HOST_WIDE_INT)expected_size > max_size)
4014 0 : expected_size = max_size;
4015 8 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
4016 0 : expected_size = min_size;
4017 : }
4018 :
4019 36670 : opt_scalar_int_mode mode_iter;
4020 222095 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
4021 : {
4022 199827 : scalar_int_mode mode = mode_iter.require ();
4023 199827 : enum insn_code code = direct_optab_handler (setmem_optab, mode);
4024 :
4025 199827 : if (code != CODE_FOR_nothing
4026 : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
4027 : here because if SIZE is less than the mode mask, as it is
4028 : returned by the macro, it will definitely be less than the
4029 : actual mode mask. Since SIZE is within the Pmode address
4030 : space, we limit MODE to Pmode. */
4031 199827 : && ((CONST_INT_P (size)
4032 31697 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
4033 31697 : <= (GET_MODE_MASK (mode) >> 1)))
4034 26364 : || max_size <= (GET_MODE_MASK (mode) >> 1)
4035 31368 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
4036 : {
4037 47555 : class expand_operand ops[9];
4038 47555 : unsigned int nops;
4039 :
4040 47555 : nops = insn_data[(int) code].n_generator_args;
4041 47555 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
4042 :
4043 47555 : create_fixed_operand (&ops[0], object);
4044 : /* The check above guarantees that this size conversion is valid. */
4045 47555 : create_convert_operand_to (&ops[1], size, mode, true);
4046 47555 : create_convert_operand_from (&ops[2], val, byte_mode, true);
4047 47555 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
4048 47555 : if (nops >= 6)
4049 : {
4050 47555 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
4051 47555 : create_integer_operand (&ops[5], expected_size);
4052 : }
4053 47555 : if (nops >= 8)
4054 : {
4055 47555 : create_integer_operand (&ops[6], min_size);
4056 : /* If we cannot represent the maximal size,
4057 : make parameter NULL. */
4058 47555 : if ((HOST_WIDE_INT) max_size != -1)
4059 44420 : create_integer_operand (&ops[7], max_size);
4060 : else
4061 3135 : create_fixed_operand (&ops[7], NULL);
4062 : }
4063 47555 : if (nops == 9)
4064 : {
4065 : /* If we cannot represent the maximal size,
4066 : make parameter NULL. */
4067 47555 : if ((HOST_WIDE_INT) probable_max_size != -1)
4068 44580 : create_integer_operand (&ops[8], probable_max_size);
4069 : else
4070 2975 : create_fixed_operand (&ops[8], NULL);
4071 : }
4072 47555 : gcc_assert (min_size != max_size
4073 : || rtx_equal_p (ops[1].value, GEN_INT (min_size)));
4074 47555 : if (maybe_expand_insn (code, nops, ops))
4075 14402 : return true;
4076 : }
4077 : }
4078 :
4079 : return false;
4080 : }
4081 :
4082 :
4083 : /* Write to one of the components of the complex value CPLX. Write VAL to
4084 : the real part if IMAG_P is false, and the imaginary part if its true.
4085 : If UNDEFINED_P then the value in CPLX is currently undefined. */
4086 :
4087 : void
4088 571756 : write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
4089 : {
4090 571756 : machine_mode cmode;
4091 571756 : scalar_mode imode;
4092 571756 : unsigned ibitsize;
4093 :
4094 571756 : if (GET_CODE (cplx) == CONCAT)
4095 : {
4096 513910 : emit_move_insn (XEXP (cplx, imag_p), val);
4097 513910 : return;
4098 : }
4099 :
4100 57846 : cmode = GET_MODE (cplx);
4101 57846 : imode = GET_MODE_INNER (cmode);
4102 57846 : ibitsize = GET_MODE_BITSIZE (imode);
4103 :
4104 : /* For MEMs simplify_gen_subreg may generate an invalid new address
4105 : because, e.g., the original address is considered mode-dependent
4106 : by the target, which restricts simplify_subreg from invoking
4107 : adjust_address_nv. Instead of preparing fallback support for an
4108 : invalid address, we call adjust_address_nv directly. */
4109 57846 : if (MEM_P (cplx))
4110 : {
4111 68340 : emit_move_insn (adjust_address_nv (cplx, imode,
4112 : imag_p ? GET_MODE_SIZE (imode) : 0),
4113 : val);
4114 45560 : return;
4115 : }
4116 :
4117 : /* If the sub-object is at least word sized, then we know that subregging
4118 : will work. This special case is important, since store_bit_field
4119 : wants to operate on integer modes, and there's rarely an OImode to
4120 : correspond to TCmode. */
4121 12286 : if (ibitsize >= BITS_PER_WORD
4122 : /* For hard regs we have exact predicates. Assume we can split
4123 : the original object if it spans an even number of hard regs.
4124 : This special case is important for SCmode on 64-bit platforms
4125 : where the natural size of floating-point regs is 32-bit. */
4126 12286 : || (REG_P (cplx)
4127 7324 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4128 7122 : && REG_NREGS (cplx) % 2 == 0))
4129 : {
4130 4978 : rtx part = simplify_gen_subreg (imode, cplx, cmode,
4131 7467 : imag_p ? GET_MODE_SIZE (imode) : 0);
4132 4978 : if (part)
4133 : {
4134 4978 : emit_move_insn (part, val);
4135 4978 : return;
4136 : }
4137 : else
4138 : /* simplify_gen_subreg may fail for sub-word MEMs. */
4139 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4140 : }
4141 :
4142 10962 : store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
4143 : false, undefined_p);
4144 : }
4145 :
4146 : /* Extract one of the components of the complex value CPLX. Extract the
4147 : real part if IMAG_P is false, and the imaginary part if it's true. */
4148 :
4149 : rtx
4150 559215 : read_complex_part (rtx cplx, bool imag_p)
4151 : {
4152 559215 : machine_mode cmode;
4153 559215 : scalar_mode imode;
4154 559215 : unsigned ibitsize;
4155 :
4156 559215 : if (GET_CODE (cplx) == CONCAT)
4157 345638 : return XEXP (cplx, imag_p);
4158 :
4159 213577 : cmode = GET_MODE (cplx);
4160 213577 : imode = GET_MODE_INNER (cmode);
4161 213577 : ibitsize = GET_MODE_BITSIZE (imode);
4162 :
4163 : /* Special case reads from complex constants that got spilled to memory. */
4164 213577 : if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
4165 : {
4166 37949 : tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
4167 37949 : if (decl && TREE_CODE (decl) == COMPLEX_CST)
4168 : {
4169 0 : tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
4170 0 : if (CONSTANT_CLASS_P (part))
4171 0 : return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
4172 : }
4173 : }
4174 :
4175 : /* For MEMs simplify_gen_subreg may generate an invalid new address
4176 : because, e.g., the original address is considered mode-dependent
4177 : by the target, which restricts simplify_subreg from invoking
4178 : adjust_address_nv. Instead of preparing fallback support for an
4179 : invalid address, we call adjust_address_nv directly. */
4180 213577 : if (MEM_P (cplx))
4181 236989 : return adjust_address_nv (cplx, imode,
4182 : imag_p ? GET_MODE_SIZE (imode) : 0);
4183 :
4184 : /* If the sub-object is at least word sized, then we know that subregging
4185 : will work. This special case is important, since extract_bit_field
4186 : wants to operate on integer modes, and there's rarely an OImode to
4187 : correspond to TCmode. */
4188 55418 : if (ibitsize >= BITS_PER_WORD
4189 : /* For hard regs we have exact predicates. Assume we can split
4190 : the original object if it spans an even number of hard regs.
4191 : This special case is important for SCmode on 64-bit platforms
4192 : where the natural size of floating-point regs is 32-bit. */
4193 55418 : || (REG_P (cplx)
4194 34804 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4195 292 : && REG_NREGS (cplx) % 2 == 0))
4196 : {
4197 10229 : rtx ret = simplify_gen_subreg (imode, cplx, cmode,
4198 15343 : imag_p ? GET_MODE_SIZE (imode) : 0);
4199 10229 : if (ret)
4200 : return ret;
4201 : else
4202 : /* simplify_gen_subreg may fail for sub-word MEMs. */
4203 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4204 : }
4205 :
4206 67781 : return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
4207 : true, NULL_RTX, imode, imode, false, NULL);
4208 : }
4209 :
4210 : /* A subroutine of emit_move_insn_1. Yet another lowpart generator.
4211 : NEW_MODE and OLD_MODE are the same size. Return NULL if X cannot be
4212 : represented in NEW_MODE. If FORCE is true, this will never happen, as
4213 : we'll force-create a SUBREG if needed. */
4214 :
4215 : static rtx
4216 277662 : emit_move_change_mode (machine_mode new_mode,
4217 : machine_mode old_mode, rtx x, bool force)
4218 : {
4219 277662 : rtx ret;
4220 :
4221 277662 : if (push_operand (x, GET_MODE (x)))
4222 : {
4223 1318 : ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
4224 1318 : MEM_COPY_ATTRIBUTES (ret, x);
4225 : }
4226 276344 : else if (MEM_P (x))
4227 : {
4228 : /* We don't have to worry about changing the address since the
4229 : size in bytes is supposed to be the same. */
4230 52783 : if (reload_in_progress)
4231 : {
4232 : /* Copy the MEM to change the mode and move any
4233 : substitutions from the old MEM to the new one. */
4234 0 : ret = adjust_address_nv (x, new_mode, 0);
4235 0 : copy_replacements (x, ret);
4236 : }
4237 : else
4238 52783 : ret = adjust_address (x, new_mode, 0);
4239 : }
4240 : else
4241 : {
4242 : /* Note that we do want simplify_subreg's behavior of validating
4243 : that the new mode is ok for a hard register. If we were to use
4244 : simplify_gen_subreg, we would create the subreg, but would
4245 : probably run into the target not being able to implement it. */
4246 : /* Except, of course, when FORCE is true, when this is exactly what
4247 : we want. Which is needed for CCmodes on some targets. */
4248 223561 : if (force)
4249 223561 : ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
4250 : else
4251 0 : ret = simplify_subreg (new_mode, x, old_mode, 0);
4252 : }
4253 :
4254 277662 : return ret;
4255 : }
4256 :
4257 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X using
4258 : an integer mode of the same size as MODE. Returns the instruction
4259 : emitted, or NULL if such a move could not be generated. */
4260 :
4261 : static rtx_insn *
4262 138831 : emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
4263 : {
4264 138831 : scalar_int_mode imode;
4265 138831 : enum insn_code code;
4266 :
4267 : /* There must exist a mode of the exact size we require. */
4268 138831 : if (!int_mode_for_mode (mode).exists (&imode))
4269 0 : return NULL;
4270 :
4271 : /* The target must support moves in this mode. */
4272 138831 : code = optab_handler (mov_optab, imode);
4273 138831 : if (code == CODE_FOR_nothing)
4274 : return NULL;
4275 :
4276 138831 : x = emit_move_change_mode (imode, mode, x, force);
4277 138831 : if (x == NULL_RTX)
4278 : return NULL;
4279 138831 : y = emit_move_change_mode (imode, mode, y, force);
4280 138831 : if (y == NULL_RTX)
4281 : return NULL;
4282 138831 : return emit_insn (GEN_FCN (code) (x, y));
4283 : }
4284 :
4285 : /* A subroutine of emit_move_insn_1. X is a push_operand in MODE.
4286 : Return an equivalent MEM that does not use an auto-increment. */
4287 :
4288 : rtx
4289 3636 : emit_move_resolve_push (machine_mode mode, rtx x)
4290 : {
4291 3636 : enum rtx_code code = GET_CODE (XEXP (x, 0));
4292 3636 : rtx temp;
4293 :
4294 7272 : poly_int64 adjust = GET_MODE_SIZE (mode);
4295 : #ifdef PUSH_ROUNDING
4296 3636 : adjust = PUSH_ROUNDING (adjust);
4297 : #endif
4298 3636 : if (code == PRE_DEC || code == POST_DEC)
4299 3240 : adjust = -adjust;
4300 396 : else if (code == PRE_MODIFY || code == POST_MODIFY)
4301 : {
4302 396 : rtx expr = XEXP (XEXP (x, 0), 1);
4303 :
4304 396 : gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
4305 396 : poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
4306 396 : if (GET_CODE (expr) == MINUS)
4307 0 : val = -val;
4308 396 : gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
4309 : adjust = val;
4310 : }
4311 :
4312 : /* Do not use anti_adjust_stack, since we don't want to update
4313 : stack_pointer_delta. */
4314 3640 : temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
4315 3636 : gen_int_mode (adjust, Pmode), stack_pointer_rtx,
4316 : 0, OPTAB_LIB_WIDEN);
4317 3636 : if (temp != stack_pointer_rtx)
4318 0 : emit_move_insn (stack_pointer_rtx, temp);
4319 :
4320 3636 : switch (code)
4321 : {
4322 3636 : case PRE_INC:
4323 3636 : case PRE_DEC:
4324 3636 : case PRE_MODIFY:
4325 3636 : temp = stack_pointer_rtx;
4326 3636 : break;
4327 : case POST_INC:
4328 : case POST_DEC:
4329 : case POST_MODIFY:
4330 0 : temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
4331 0 : break;
4332 0 : default:
4333 0 : gcc_unreachable ();
4334 : }
4335 :
4336 3636 : return replace_equiv_address (x, temp);
4337 : }
4338 :
4339 : /* A subroutine of emit_move_complex. Generate a move from Y into X.
4340 : X is known to satisfy push_operand, and MODE is known to be complex.
4341 : Returns the last instruction emitted. */
4342 :
4343 : rtx_insn *
4344 5560 : emit_move_complex_push (machine_mode mode, rtx x, rtx y)
4345 : {
4346 5560 : scalar_mode submode = GET_MODE_INNER (mode);
4347 5560 : bool imag_first;
4348 :
4349 : #ifdef PUSH_ROUNDING
4350 11120 : poly_int64 submodesize = GET_MODE_SIZE (submode);
4351 :
4352 : /* In case we output to the stack, but the size is smaller than the
4353 : machine can push exactly, we need to use move instructions. */
4354 5560 : if (maybe_ne (PUSH_ROUNDING (submodesize), submodesize))
4355 : {
4356 718 : x = emit_move_resolve_push (mode, x);
4357 718 : return emit_move_insn (x, y);
4358 : }
4359 : #endif
4360 :
4361 : /* Note that the real part always precedes the imag part in memory
4362 : regardless of machine's endianness. */
4363 4842 : switch (GET_CODE (XEXP (x, 0)))
4364 : {
4365 : case PRE_DEC:
4366 : case POST_DEC:
4367 : imag_first = true;
4368 : break;
4369 0 : case PRE_INC:
4370 0 : case POST_INC:
4371 0 : imag_first = false;
4372 0 : break;
4373 0 : default:
4374 0 : gcc_unreachable ();
4375 : }
4376 :
4377 4842 : emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4378 : read_complex_part (y, imag_first));
4379 4842 : return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4380 9684 : read_complex_part (y, !imag_first));
4381 : }
4382 :
4383 : /* A subroutine of emit_move_complex. Perform the move from Y to X
4384 : via two moves of the parts. Returns the last instruction emitted. */
4385 :
4386 : rtx_insn *
4387 87915 : emit_move_complex_parts (rtx x, rtx y)
4388 : {
4389 : /* Show the output dies here. This is necessary for SUBREGs
4390 : of pseudos since we cannot track their lifetimes correctly;
4391 : hard regs shouldn't appear here except as return values. */
4392 87915 : if (!reload_completed && !reload_in_progress
4393 175830 : && REG_P (x) && !reg_overlap_mentioned_p (x, y))
4394 6136 : emit_clobber (x);
4395 :
4396 87915 : write_complex_part (x, read_complex_part (y, false), false, true);
4397 87915 : write_complex_part (x, read_complex_part (y, true), true, false);
4398 :
4399 87915 : return get_last_insn ();
4400 : }
4401 :
4402 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4403 : MODE is known to be complex. Returns the last instruction emitted. */
4404 :
4405 : static rtx_insn *
4406 110088 : emit_move_complex (machine_mode mode, rtx x, rtx y)
4407 : {
4408 110088 : bool try_int;
4409 :
4410 : /* Need to take special care for pushes, to maintain proper ordering
4411 : of the data, and possibly extra padding. */
4412 110088 : if (push_operand (x, mode))
4413 4952 : return emit_move_complex_push (mode, x, y);
4414 :
4415 : /* See if we can coerce the target into moving both values at once, except
4416 : for floating point where we favor moving as parts if this is easy. */
4417 105136 : if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
4418 62431 : && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
4419 62431 : && !(REG_P (x)
4420 2213 : && HARD_REGISTER_P (x)
4421 564 : && REG_NREGS (x) == 1)
4422 167567 : && !(REG_P (y)
4423 3302 : && HARD_REGISTER_P (y)
4424 1651 : && REG_NREGS (y) == 1))
4425 : try_int = false;
4426 : /* Not possible if the values are inherently not adjacent. */
4427 42705 : else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
4428 : try_int = false;
4429 : /* Is possible if both are registers (or subregs of registers). */
4430 17998 : else if (register_operand (x, mode) && register_operand (y, mode))
4431 : try_int = true;
4432 : /* If one of the operands is a memory, and alignment constraints
4433 : are friendly enough, we may be able to do combined memory operations.
4434 : We do not attempt this if Y is a constant because that combination is
4435 : usually better with the by-parts thing below. */
4436 635 : else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
4437 : && (!STRICT_ALIGNMENT
4438 : || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
4439 : try_int = true;
4440 : else
4441 : try_int = false;
4442 :
4443 : if (try_int)
4444 : {
4445 17998 : rtx_insn *ret;
4446 :
4447 : /* For memory to memory moves, optimal behavior can be had with the
4448 : existing block move logic. But use normal expansion if optimizing
4449 : for size. */
4450 17998 : if (MEM_P (x) && MEM_P (y))
4451 : {
4452 726 : emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
4453 360 : (optimize_insn_for_speed_p()
4454 : ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
4455 360 : return get_last_insn ();
4456 : }
4457 :
4458 17638 : ret = emit_move_via_integer (mode, x, y, true);
4459 17638 : if (ret)
4460 : return ret;
4461 : }
4462 :
4463 87138 : return emit_move_complex_parts (x, y);
4464 : }
4465 :
4466 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4467 : MODE is known to be MODE_CC. Returns the last instruction emitted. */
4468 :
4469 : static rtx_insn *
4470 0 : emit_move_ccmode (machine_mode mode, rtx x, rtx y)
4471 : {
4472 0 : rtx_insn *ret;
4473 :
4474 : /* Assume all MODE_CC modes are equivalent; if we have movcc, use it. */
4475 0 : if (mode != CCmode)
4476 : {
4477 0 : enum insn_code code = optab_handler (mov_optab, CCmode);
4478 0 : if (code != CODE_FOR_nothing)
4479 : {
4480 0 : x = emit_move_change_mode (CCmode, mode, x, true);
4481 0 : y = emit_move_change_mode (CCmode, mode, y, true);
4482 0 : return emit_insn (GEN_FCN (code) (x, y));
4483 : }
4484 : }
4485 :
4486 : /* Otherwise, find the MODE_INT mode of the same width. */
4487 0 : ret = emit_move_via_integer (mode, x, y, false);
4488 0 : gcc_assert (ret != NULL);
4489 : return ret;
4490 : }
4491 :
4492 : /* Return true if word I of OP lies entirely in the
4493 : undefined bits of a paradoxical subreg. */
4494 :
4495 : static bool
4496 0 : undefined_operand_subword_p (const_rtx op, int i)
4497 : {
4498 0 : if (GET_CODE (op) != SUBREG)
4499 : return false;
4500 0 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
4501 0 : poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
4502 0 : return (known_ge (offset, GET_MODE_SIZE (innermostmode))
4503 0 : || known_le (offset, -UNITS_PER_WORD));
4504 : }
4505 :
4506 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4507 : MODE is any multi-word or full-word mode that lacks a move_insn
4508 : pattern. Note that you will get better code if you define such
4509 : patterns, even if they must turn into multiple assembler instructions. */
4510 :
4511 : static rtx_insn *
4512 0 : emit_move_multi_word (machine_mode mode, rtx x, rtx y)
4513 : {
4514 0 : rtx_insn *last_insn = 0;
4515 0 : rtx_insn *seq;
4516 0 : rtx inner;
4517 0 : bool need_clobber;
4518 0 : int i, mode_size;
4519 :
4520 : /* This function can only handle cases where the number of words is
4521 : known at compile time. */
4522 0 : mode_size = GET_MODE_SIZE (mode).to_constant ();
4523 0 : gcc_assert (mode_size >= UNITS_PER_WORD);
4524 :
4525 : /* If X is a push on the stack, do the push now and replace
4526 : X with a reference to the stack pointer. */
4527 0 : if (push_operand (x, mode))
4528 0 : x = emit_move_resolve_push (mode, x);
4529 :
4530 : /* If we are in reload, see if either operand is a MEM whose address
4531 : is scheduled for replacement. */
4532 0 : if (reload_in_progress && MEM_P (x)
4533 0 : && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
4534 0 : x = replace_equiv_address_nv (x, inner);
4535 0 : if (reload_in_progress && MEM_P (y)
4536 0 : && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
4537 0 : y = replace_equiv_address_nv (y, inner);
4538 :
4539 0 : start_sequence ();
4540 :
4541 0 : need_clobber = false;
4542 0 : for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
4543 : {
4544 : /* Do not generate code for a move if it would go entirely
4545 : to the non-existing bits of a paradoxical subreg. */
4546 0 : if (undefined_operand_subword_p (x, i))
4547 0 : continue;
4548 :
4549 0 : rtx xpart = operand_subword (x, i, 1, mode);
4550 0 : rtx ypart;
4551 :
4552 : /* Do not generate code for a move if it would come entirely
4553 : from the undefined bits of a paradoxical subreg. */
4554 0 : if (undefined_operand_subword_p (y, i))
4555 0 : continue;
4556 :
4557 0 : ypart = operand_subword (y, i, 1, mode);
4558 :
4559 : /* If we can't get a part of Y, put Y into memory if it is a
4560 : constant. Otherwise, force it into a register. Then we must
4561 : be able to get a part of Y. */
4562 0 : if (ypart == 0 && CONSTANT_P (y))
4563 : {
4564 0 : y = use_anchored_address (force_const_mem (mode, y));
4565 0 : ypart = operand_subword (y, i, 1, mode);
4566 : }
4567 0 : else if (ypart == 0)
4568 0 : ypart = operand_subword_force (y, i, mode);
4569 :
4570 0 : gcc_assert (xpart && ypart);
4571 :
4572 0 : need_clobber |= (GET_CODE (xpart) == SUBREG);
4573 :
4574 0 : last_insn = emit_move_insn (xpart, ypart);
4575 : }
4576 :
4577 0 : seq = end_sequence ();
4578 :
4579 : /* Show the output dies here. This is necessary for SUBREGs
4580 : of pseudos since we cannot track their lifetimes correctly;
4581 : hard regs shouldn't appear here except as return values.
4582 : We never want to emit such a clobber after reload. */
4583 0 : if (x != y
4584 0 : && ! (reload_in_progress || reload_completed)
4585 0 : && need_clobber != 0)
4586 0 : emit_clobber (x);
4587 :
4588 0 : emit_insn (seq);
4589 :
4590 0 : return last_insn;
4591 : }
4592 :
4593 : /* Low level part of emit_move_insn.
4594 : Called just like emit_move_insn, but assumes X and Y
4595 : are basically valid. */
4596 :
4597 : rtx_insn *
4598 76944496 : emit_move_insn_1 (rtx x, rtx y)
4599 : {
4600 76944496 : machine_mode mode = GET_MODE (x);
4601 76944496 : enum insn_code code;
4602 :
4603 76944496 : gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
4604 :
4605 76944496 : code = optab_handler (mov_optab, mode);
4606 76944496 : if (code != CODE_FOR_nothing)
4607 76713215 : return emit_insn (GEN_FCN (code) (x, y));
4608 :
4609 : /* Expand complex moves by moving real part and imag part. */
4610 231281 : if (COMPLEX_MODE_P (mode))
4611 110088 : return emit_move_complex (mode, x, y);
4612 :
4613 : if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
4614 : || ALL_FIXED_POINT_MODE_P (mode))
4615 : {
4616 121193 : rtx_insn *result = emit_move_via_integer (mode, x, y, true);
4617 :
4618 : /* If we can't find an integer mode, use multi words. */
4619 121193 : if (result)
4620 : return result;
4621 : else
4622 0 : return emit_move_multi_word (mode, x, y);
4623 : }
4624 :
4625 : if (GET_MODE_CLASS (mode) == MODE_CC)
4626 0 : return emit_move_ccmode (mode, x, y);
4627 :
4628 : /* Try using a move pattern for the corresponding integer mode. This is
4629 : only safe when simplify_subreg can convert MODE constants into integer
4630 : constants. At present, it can only do this reliably if the value
4631 : fits within a HOST_WIDE_INT. */
4632 0 : if (!CONSTANT_P (y)
4633 0 : || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
4634 : {
4635 0 : rtx_insn *ret = emit_move_via_integer (mode, x, y, lra_in_progress);
4636 :
4637 0 : if (ret)
4638 : {
4639 0 : if (! lra_in_progress || recog (PATTERN (ret), ret, 0) >= 0)
4640 0 : return ret;
4641 : }
4642 : }
4643 :
4644 0 : return emit_move_multi_word (mode, x, y);
4645 : }
4646 :
4647 : /* Generate code to copy Y into X.
4648 : Both Y and X must have the same mode, except that
4649 : Y can be a constant with VOIDmode.
4650 : This mode cannot be BLKmode; use emit_block_move for that.
4651 :
4652 : Return the last instruction emitted. */
4653 :
4654 : rtx_insn *
4655 71031787 : emit_move_insn (rtx x, rtx y)
4656 : {
4657 71031787 : machine_mode mode = GET_MODE (x);
4658 71031787 : rtx y_cst = NULL_RTX;
4659 71031787 : rtx_insn *last_insn;
4660 71031787 : rtx set;
4661 :
4662 71031787 : gcc_assert (mode != BLKmode
4663 : && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
4664 :
4665 : /* If we have a copy that looks like one of the following patterns:
4666 : (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
4667 : (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
4668 : (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
4669 : (set (subreg:M1 (reg:M2 ...)) (constant C))
4670 : where mode M1 is equal in size to M2, try to detect whether the
4671 : mode change involves an implicit round trip through memory.
4672 : If so, see if we can avoid that by removing the subregs and
4673 : doing the move in mode M2 instead. */
4674 :
4675 71031787 : rtx x_inner = NULL_RTX;
4676 71031787 : rtx y_inner = NULL_RTX;
4677 :
4678 73801015 : auto candidate_subreg_p = [&](rtx subreg) {
4679 2769228 : return (REG_P (SUBREG_REG (subreg))
4680 8305923 : && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
4681 : GET_MODE_SIZE (GET_MODE (subreg)))
4682 3138737 : && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg)))
4683 2769228 : != CODE_FOR_nothing);
4684 : };
4685 :
4686 71038016 : auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
4687 6229 : return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
4688 6229 : && !push_operand (mem, GET_MODE (mem))
4689 : /* Not a candidate if innermode requires too much alignment. */
4690 12398 : && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
4691 232 : || targetm.slow_unaligned_access (GET_MODE (mem),
4692 116 : MEM_ALIGN (mem))
4693 232 : || !targetm.slow_unaligned_access (innermode,
4694 116 : MEM_ALIGN (mem))));
4695 : };
4696 :
4697 71031787 : if (SUBREG_P (x) && candidate_subreg_p (x))
4698 13185 : x_inner = SUBREG_REG (x);
4699 :
4700 71031787 : if (SUBREG_P (y) && candidate_subreg_p (y))
4701 320468 : y_inner = SUBREG_REG (y);
4702 :
4703 71031787 : if (x_inner != NULL_RTX
4704 71031787 : && y_inner != NULL_RTX
4705 1160 : && GET_MODE (x_inner) == GET_MODE (y_inner)
4706 71032524 : && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
4707 : {
4708 737 : x = x_inner;
4709 737 : y = y_inner;
4710 737 : mode = GET_MODE (x_inner);
4711 : }
4712 71031050 : else if (x_inner != NULL_RTX
4713 12448 : && MEM_P (y)
4714 71031374 : && candidate_mem_p (GET_MODE (x_inner), y))
4715 : {
4716 324 : x = x_inner;
4717 324 : y = adjust_address (y, GET_MODE (x_inner), 0);
4718 324 : mode = GET_MODE (x_inner);
4719 : }
4720 71030726 : else if (y_inner != NULL_RTX
4721 319731 : && MEM_P (x)
4722 71036631 : && candidate_mem_p (GET_MODE (y_inner), x))
4723 : {
4724 5845 : x = adjust_address (x, GET_MODE (y_inner), 0);
4725 5845 : y = y_inner;
4726 5845 : mode = GET_MODE (y_inner);
4727 : }
4728 71024881 : else if (x_inner != NULL_RTX
4729 12124 : && CONSTANT_P (y)
4730 475 : && !targetm.can_change_mode_class (GET_MODE (x_inner),
4731 : mode, ALL_REGS)
4732 71025356 : && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
4733 : {
4734 475 : x = x_inner;
4735 475 : y = y_inner;
4736 475 : mode = GET_MODE (x_inner);
4737 : }
4738 :
4739 71031787 : if (CONSTANT_P (y))
4740 : {
4741 16604823 : if (optimize
4742 12924945 : && SCALAR_FLOAT_MODE_P (GET_MODE (x))
4743 17378311 : && (last_insn = compress_float_constant (x, y)))
4744 : return last_insn;
4745 :
4746 16535701 : y_cst = y;
4747 :
4748 16535701 : if (!targetm.legitimate_constant_p (mode, y))
4749 : {
4750 510769 : y = force_const_mem (mode, y);
4751 :
4752 : /* If the target's cannot_force_const_mem prevented the spill,
4753 : assume that the target's move expanders will also take care
4754 : of the non-legitimate constant. */
4755 510769 : if (!y)
4756 : y = y_cst;
4757 : else
4758 490650 : y = use_anchored_address (y);
4759 : }
4760 : }
4761 :
4762 : /* If X or Y are memory references, verify that their addresses are valid
4763 : for the machine. */
4764 70962665 : if (MEM_P (x)
4765 87164579 : && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
4766 13941219 : MEM_ADDR_SPACE (x))
4767 2260869 : && ! push_operand (x, GET_MODE (x))))
4768 174 : x = validize_mem (x);
4769 :
4770 70962665 : if (MEM_P (y)
4771 88695556 : && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
4772 17732891 : MEM_ADDR_SPACE (y)))
4773 8702 : y = validize_mem (y);
4774 :
4775 70962665 : gcc_assert (mode != BLKmode);
4776 :
4777 70962665 : last_insn = emit_move_insn_1 (x, y);
4778 :
4779 16535701 : if (y_cst && REG_P (x)
4780 12116379 : && (set = single_set (last_insn)) != NULL_RTX
4781 12116379 : && SET_DEST (set) == x
4782 83064529 : && ! rtx_equal_p (y_cst, SET_SRC (set)))
4783 1243388 : set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
4784 :
4785 : return last_insn;
4786 : }
4787 :
4788 : /* Generate the body of an instruction to copy Y into X.
4789 : It may be a list of insns, if one insn isn't enough. */
4790 :
4791 : rtx_insn *
4792 5981751 : gen_move_insn (rtx x, rtx y)
4793 : {
4794 5981751 : start_sequence ();
4795 5981751 : emit_move_insn_1 (x, y);
4796 5981751 : return end_sequence ();
4797 : }
4798 :
4799 : /* If Y is representable exactly in a narrower mode, and the target can
4800 : perform the extension directly from constant or memory, then emit the
4801 : move as an extension. */
4802 :
4803 : static rtx_insn *
4804 773488 : compress_float_constant (rtx x, rtx y)
4805 : {
4806 773488 : machine_mode dstmode = GET_MODE (x);
4807 773488 : machine_mode orig_srcmode = GET_MODE (y);
4808 773488 : machine_mode srcmode;
4809 773488 : const REAL_VALUE_TYPE *r;
4810 773488 : int oldcost, newcost;
4811 773488 : bool speed = optimize_insn_for_speed_p ();
4812 :
4813 773488 : r = CONST_DOUBLE_REAL_VALUE (y);
4814 :
4815 773488 : if (targetm.legitimate_constant_p (dstmode, y))
4816 771870 : oldcost = set_src_cost (y, orig_srcmode, speed);
4817 : else
4818 1618 : oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
4819 :
4820 2740896 : FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
4821 : {
4822 2036530 : enum insn_code ic;
4823 2036530 : rtx trunc_y;
4824 2036530 : rtx_insn *last_insn;
4825 :
4826 : /* Skip if the target can't extend this way. */
4827 2036530 : ic = can_extend_p (dstmode, srcmode, 0);
4828 2036530 : if (ic == CODE_FOR_nothing)
4829 1612731 : continue;
4830 :
4831 : /* Skip if the narrowed value isn't exact. */
4832 423799 : if (! exact_real_truncate (srcmode, r))
4833 52349 : continue;
4834 :
4835 371450 : trunc_y = const_double_from_real_value (*r, srcmode);
4836 :
4837 371450 : if (targetm.legitimate_constant_p (srcmode, trunc_y))
4838 : {
4839 : /* Skip if the target needs extra instructions to perform
4840 : the extension. */
4841 367806 : if (!insn_operand_matches (ic, 1, trunc_y))
4842 4080 : continue;
4843 : /* This is valid, but may not be cheaper than the original. */
4844 363726 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4845 : dstmode, speed);
4846 363726 : if (oldcost < newcost)
4847 294604 : continue;
4848 : }
4849 3644 : else if (float_extend_from_mem[dstmode][srcmode])
4850 : {
4851 0 : trunc_y = force_const_mem (srcmode, trunc_y);
4852 : /* This is valid, but may not be cheaper than the original. */
4853 0 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4854 : dstmode, speed);
4855 0 : if (oldcost < newcost)
4856 0 : continue;
4857 0 : trunc_y = validize_mem (trunc_y);
4858 : }
4859 : else
4860 3644 : continue;
4861 :
4862 : /* For CSE's benefit, force the compressed constant pool entry
4863 : into a new pseudo. This constant may be used in different modes,
4864 : and if not, combine will put things back together for us. */
4865 69122 : trunc_y = force_reg (srcmode, trunc_y);
4866 :
4867 : /* If x is a hard register, perform the extension into a pseudo,
4868 : so that e.g. stack realignment code is aware of it. */
4869 69122 : rtx target = x;
4870 69122 : if (REG_P (x) && HARD_REGISTER_P (x))
4871 1 : target = gen_reg_rtx (dstmode);
4872 :
4873 69122 : emit_unop_insn (ic, target, trunc_y, UNKNOWN);
4874 69122 : last_insn = get_last_insn ();
4875 :
4876 69122 : if (REG_P (target))
4877 58426 : set_unique_reg_note (last_insn, REG_EQUAL, y);
4878 :
4879 69122 : if (target != x)
4880 1 : return emit_move_insn (x, target);
4881 : return last_insn;
4882 : }
4883 :
4884 : return NULL;
4885 : }
4886 :
4887 : /* Pushing data onto the stack. */
4888 :
4889 : /* Push a block of length SIZE (perhaps variable)
4890 : and return an rtx to address the beginning of the block.
4891 : The value may be virtual_outgoing_args_rtx.
4892 :
4893 : EXTRA is the number of bytes of padding to push in addition to SIZE.
4894 : BELOW nonzero means this padding comes at low addresses;
4895 : otherwise, the padding comes at high addresses. */
4896 :
4897 : rtx
4898 269040 : push_block (rtx size, poly_int64 extra, int below)
4899 : {
4900 269040 : rtx temp;
4901 :
4902 334153 : size = convert_modes (Pmode, ptr_mode, size, 1);
4903 269040 : if (CONSTANT_P (size))
4904 334153 : anti_adjust_stack (plus_constant (Pmode, size, extra));
4905 0 : else if (REG_P (size) && known_eq (extra, 0))
4906 0 : anti_adjust_stack (size);
4907 : else
4908 : {
4909 0 : temp = copy_to_mode_reg (Pmode, size);
4910 0 : if (maybe_ne (extra, 0))
4911 0 : temp = expand_binop (Pmode, add_optab, temp,
4912 0 : gen_int_mode (extra, Pmode),
4913 : temp, 0, OPTAB_LIB_WIDEN);
4914 0 : anti_adjust_stack (temp);
4915 : }
4916 :
4917 269040 : if (STACK_GROWS_DOWNWARD)
4918 : {
4919 269040 : temp = virtual_outgoing_args_rtx;
4920 269040 : if (maybe_ne (extra, 0) && below)
4921 0 : temp = plus_constant (Pmode, temp, extra);
4922 : }
4923 : else
4924 : {
4925 : poly_int64 csize;
4926 : if (poly_int_rtx_p (size, &csize))
4927 : temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
4928 : -csize - (below ? 0 : extra));
4929 : else if (maybe_ne (extra, 0) && !below)
4930 : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4931 : negate_rtx (Pmode, plus_constant (Pmode, size,
4932 : extra)));
4933 : else
4934 : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4935 : negate_rtx (Pmode, size));
4936 : }
4937 :
4938 269040 : return memory_address (NARROWEST_INT_MODE, temp);
4939 : }
4940 :
4941 : /* A utility routine that returns the base of an auto-inc memory, or NULL. */
4942 :
4943 : static rtx
4944 2585528 : mem_autoinc_base (rtx mem)
4945 : {
4946 0 : if (MEM_P (mem))
4947 : {
4948 1582528 : rtx addr = XEXP (mem, 0);
4949 1582528 : if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
4950 1034033 : return XEXP (addr, 0);
4951 : }
4952 : return NULL;
4953 : }
4954 :
4955 : /* A utility routine used here, in reload, and in try_split. The insns
4956 : after PREV up to and including LAST are known to adjust the stack,
4957 : with a final value of END_ARGS_SIZE. Iterate backward from LAST
4958 : placing notes as appropriate. PREV may be NULL, indicating the
4959 : entire insn sequence prior to LAST should be scanned.
4960 :
4961 : The set of allowed stack pointer modifications is small:
4962 : (1) One or more auto-inc style memory references (aka pushes),
4963 : (2) One or more addition/subtraction with the SP as destination,
4964 : (3) A single move insn with the SP as destination,
4965 : (4) A call_pop insn,
4966 : (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
4967 :
4968 : Insns in the sequence that do not modify the SP are ignored,
4969 : except for noreturn calls.
4970 :
4971 : The return value is the amount of adjustment that can be trivially
4972 : verified, via immediate operand or auto-inc. If the adjustment
4973 : cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN. */
4974 :
4975 : poly_int64
4976 4604184 : find_args_size_adjust (rtx_insn *insn)
4977 : {
4978 4604184 : rtx dest, set, pat;
4979 4604184 : int i;
4980 :
4981 4604184 : pat = PATTERN (insn);
4982 4604184 : set = NULL;
4983 :
4984 : /* Look for a call_pop pattern. */
4985 4604184 : if (CALL_P (insn))
4986 : {
4987 : /* We have to allow non-call_pop patterns for the case
4988 : of emit_single_push_insn of a TLS address. */
4989 2951212 : if (GET_CODE (pat) != PARALLEL)
4990 2936355 : return 0;
4991 :
4992 : /* All call_pop have a stack pointer adjust in the parallel.
4993 : The call itself is always first, and the stack adjust is
4994 : usually last, so search from the end. */
4995 14857 : for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
4996 : {
4997 14857 : set = XVECEXP (pat, 0, i);
4998 14857 : if (GET_CODE (set) != SET)
4999 0 : continue;
5000 14857 : dest = SET_DEST (set);
5001 14857 : if (dest == stack_pointer_rtx)
5002 : break;
5003 : }
5004 : /* We'd better have found the stack pointer adjust. */
5005 14857 : if (i == 0)
5006 0 : return 0;
5007 : /* Fall through to process the extracted SET and DEST
5008 : as if it was a standalone insn. */
5009 : }
5010 1652972 : else if (GET_CODE (pat) == SET)
5011 : set = pat;
5012 257717 : else if ((set = single_set (insn)) != NULL)
5013 : ;
5014 46805 : else if (GET_CODE (pat) == PARALLEL)
5015 : {
5016 : /* ??? Some older ports use a parallel with a stack adjust
5017 : and a store for a PUSH_ROUNDING pattern, rather than a
5018 : PRE/POST_MODIFY rtx. Don't force them to update yet... */
5019 : /* ??? See h8300 and m68k, pushqi1. */
5020 0 : for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
5021 : {
5022 0 : set = XVECEXP (pat, 0, i);
5023 0 : if (GET_CODE (set) != SET)
5024 0 : continue;
5025 0 : dest = SET_DEST (set);
5026 0 : if (dest == stack_pointer_rtx)
5027 : break;
5028 :
5029 : /* We do not expect an auto-inc of the sp in the parallel. */
5030 0 : gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
5031 0 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5032 : != stack_pointer_rtx);
5033 : }
5034 0 : if (i < 0)
5035 0 : return 0;
5036 : }
5037 : else
5038 46805 : return 0;
5039 :
5040 1621024 : dest = SET_DEST (set);
5041 :
5042 : /* Look for direct modifications of the stack pointer. */
5043 1621024 : if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
5044 : {
5045 : /* Look for a trivial adjustment, otherwise assume nothing. */
5046 : /* Note that the SPU restore_stack_block pattern refers to
5047 : the stack pointer in V4SImode. Consider that non-trivial. */
5048 328260 : poly_int64 offset;
5049 328260 : if (SCALAR_INT_MODE_P (GET_MODE (dest))
5050 328260 : && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
5051 325827 : return offset;
5052 : /* ??? Reload can generate no-op moves, which will be cleaned
5053 : up later. Recognize it and continue searching. */
5054 2433 : else if (rtx_equal_p (dest, SET_SRC (set)))
5055 0 : return 0;
5056 : else
5057 2433 : return HOST_WIDE_INT_MIN;
5058 : }
5059 : else
5060 : {
5061 1292764 : rtx mem, addr;
5062 :
5063 : /* Otherwise only think about autoinc patterns. */
5064 2339351 : if (mem_autoinc_base (dest) == stack_pointer_rtx)
5065 : {
5066 925248 : mem = dest;
5067 1283792 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5068 : != stack_pointer_rtx);
5069 : }
5070 544913 : else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
5071 : mem = SET_SRC (set);
5072 : else
5073 258731 : return 0;
5074 :
5075 1034033 : addr = XEXP (mem, 0);
5076 1034033 : switch (GET_CODE (addr))
5077 : {
5078 108785 : case PRE_INC:
5079 108785 : case POST_INC:
5080 217570 : return GET_MODE_SIZE (GET_MODE (mem));
5081 907185 : case PRE_DEC:
5082 907185 : case POST_DEC:
5083 1814370 : return -GET_MODE_SIZE (GET_MODE (mem));
5084 18063 : case PRE_MODIFY:
5085 18063 : case POST_MODIFY:
5086 18063 : addr = XEXP (addr, 1);
5087 18063 : gcc_assert (GET_CODE (addr) == PLUS);
5088 18063 : gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
5089 18063 : return rtx_to_poly_int64 (XEXP (addr, 1));
5090 0 : default:
5091 0 : gcc_unreachable ();
5092 : }
5093 : }
5094 : }
5095 :
5096 : poly_int64
5097 666620 : fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
5098 : poly_int64 end_args_size)
5099 : {
5100 666620 : poly_int64 args_size = end_args_size;
5101 666620 : bool saw_unknown = false;
5102 666620 : rtx_insn *insn;
5103 :
5104 1901568 : for (insn = last; insn != prev; insn = PREV_INSN (insn))
5105 : {
5106 1234948 : if (!NONDEBUG_INSN_P (insn))
5107 0 : continue;
5108 :
5109 : /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
5110 : a call argument containing a TLS address that itself requires
5111 : a call to __tls_get_addr. The handling of stack_pointer_delta
5112 : in emit_single_push_insn is supposed to ensure that any such
5113 : notes are already correct. */
5114 1234948 : rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
5115 1234948 : gcc_assert (!note || known_eq (args_size, get_args_size (note)));
5116 :
5117 1234948 : poly_int64 this_delta = find_args_size_adjust (insn);
5118 1234948 : if (known_eq (this_delta, 0))
5119 : {
5120 607183 : if (!CALL_P (insn)
5121 9 : || ACCUMULATE_OUTGOING_ARGS
5122 303605 : || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
5123 303587 : continue;
5124 : }
5125 :
5126 931361 : gcc_assert (!saw_unknown);
5127 931361 : if (known_eq (this_delta, HOST_WIDE_INT_MIN))
5128 2411 : saw_unknown = true;
5129 :
5130 931361 : if (!note)
5131 931361 : add_args_size_note (insn, args_size);
5132 : if (STACK_GROWS_DOWNWARD)
5133 931361 : this_delta = -poly_uint64 (this_delta);
5134 :
5135 931361 : if (saw_unknown)
5136 : args_size = HOST_WIDE_INT_MIN;
5137 : else
5138 1234948 : args_size -= this_delta;
5139 : }
5140 :
5141 666620 : return args_size;
5142 : }
5143 :
5144 : #ifdef PUSH_ROUNDING
5145 : /* Emit single push insn. */
5146 :
5147 : static void
5148 1846418 : emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
5149 : {
5150 1846418 : rtx dest_addr;
5151 3692836 : poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
5152 1846418 : rtx dest;
5153 1846418 : enum insn_code icode;
5154 :
5155 : /* If there is push pattern, use it. Otherwise try old way of throwing
5156 : MEM representing push operation to move expander. */
5157 1846418 : icode = optab_handler (push_optab, mode);
5158 1846418 : if (icode != CODE_FOR_nothing)
5159 : {
5160 0 : class expand_operand ops[1];
5161 :
5162 0 : create_input_operand (&ops[0], x, mode);
5163 0 : if (maybe_expand_insn (icode, 1, ops))
5164 0 : return;
5165 : }
5166 3692836 : if (known_eq (GET_MODE_SIZE (mode), rounded_size))
5167 3188815 : dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
5168 : /* If we are to pad downward, adjust the stack pointer first and
5169 : then store X into the stack location using an offset. This is
5170 : because emit_move_insn does not know how to pad; it does not have
5171 : access to type. */
5172 104591 : else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
5173 : {
5174 0 : emit_move_insn (stack_pointer_rtx,
5175 0 : expand_binop (Pmode,
5176 : STACK_GROWS_DOWNWARD ? sub_optab
5177 : : add_optab,
5178 : stack_pointer_rtx,
5179 0 : gen_int_mode (rounded_size, Pmode),
5180 : NULL_RTX, 0, OPTAB_LIB_WIDEN));
5181 :
5182 0 : poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
5183 0 : if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
5184 : /* We have already decremented the stack pointer, so get the
5185 : previous value. */
5186 : offset += rounded_size;
5187 :
5188 0 : if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
5189 : /* We have already incremented the stack pointer, so get the
5190 : previous value. */
5191 : offset -= rounded_size;
5192 :
5193 0 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
5194 : }
5195 : else
5196 : {
5197 : if (STACK_GROWS_DOWNWARD)
5198 : /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
5199 105139 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
5200 : else
5201 : /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
5202 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
5203 :
5204 105139 : dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
5205 : }
5206 :
5207 1846418 : dest = gen_rtx_MEM (mode, dest_addr);
5208 :
5209 1846418 : if (type != 0)
5210 : {
5211 1846371 : set_mem_attributes (dest, type, 1);
5212 :
5213 1846371 : if (cfun->tail_call_marked)
5214 : /* Function incoming arguments may overlap with sibling call
5215 : outgoing arguments and we cannot allow reordering of reads
5216 : from function arguments with stores to outgoing arguments
5217 : of sibling calls. */
5218 142564 : set_mem_alias_set (dest, 0);
5219 : }
5220 1846418 : emit_move_insn (dest, x);
5221 : }
5222 :
5223 : /* Emit and annotate a single push insn. */
5224 :
5225 : static void
5226 1846418 : emit_single_push_insn (machine_mode mode, rtx x, tree type)
5227 : {
5228 1846418 : poly_int64 delta, old_delta = stack_pointer_delta;
5229 1846418 : rtx_insn *prev = get_last_insn ();
5230 1846418 : rtx_insn *last;
5231 :
5232 1846418 : emit_single_push_insn_1 (mode, x, type);
5233 :
5234 : /* Adjust stack_pointer_delta to describe the situation after the push
5235 : we just performed. Note that we must do this after the push rather
5236 : than before the push in case calculating X needs pushes and pops of
5237 : its own (e.g. if calling __tls_get_addr). The REG_ARGS_SIZE notes
5238 : for such pushes and pops must not include the effect of the future
5239 : push of X. */
5240 3692836 : stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
5241 :
5242 1846418 : last = get_last_insn ();
5243 :
5244 : /* Notice the common case where we emitted exactly one insn. */
5245 1846418 : if (PREV_INSN (last) == prev)
5246 : {
5247 1735770 : add_args_size_note (last, stack_pointer_delta);
5248 1735770 : return;
5249 : }
5250 :
5251 110648 : delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
5252 110648 : gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
5253 : || known_eq (delta, old_delta));
5254 : }
5255 : #endif
5256 :
5257 : /* If reading SIZE bytes from X will end up reading from
5258 : Y return the number of bytes that overlap. Return -1
5259 : if there is no overlap or -2 if we can't determine
5260 : (for example when X and Y have different base registers). */
5261 :
5262 : static int
5263 0 : memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
5264 : {
5265 0 : rtx tmp = plus_constant (Pmode, x, size);
5266 0 : rtx sub = simplify_gen_binary (MINUS, Pmode, tmp, y);
5267 :
5268 0 : if (!CONST_INT_P (sub))
5269 : return -2;
5270 :
5271 0 : HOST_WIDE_INT val = INTVAL (sub);
5272 :
5273 0 : return IN_RANGE (val, 1, size) ? val : -1;
5274 : }
5275 :
5276 : /* Generate code to push X onto the stack, assuming it has mode MODE and
5277 : type TYPE.
5278 : MODE is redundant except when X is a CONST_INT (since they don't
5279 : carry mode info).
5280 : SIZE is an rtx for the size of data to be copied (in bytes),
5281 : needed only if X is BLKmode.
5282 : Return true if successful. May return false if asked to push a
5283 : partial argument during a sibcall optimization (as specified by
5284 : SIBCALL_P) and the incoming and outgoing pointers cannot be shown
5285 : to not overlap.
5286 :
5287 : ALIGN (in bits) is maximum alignment we can assume.
5288 :
5289 : If PARTIAL and REG are both nonzero, then copy that many of the first
5290 : bytes of X into registers starting with REG, and push the rest of X.
5291 : The amount of space pushed is decreased by PARTIAL bytes.
5292 : REG must be a hard register in this case.
5293 : If REG is zero but PARTIAL is not, take any all others actions for an
5294 : argument partially in registers, but do not actually load any
5295 : registers.
5296 :
5297 : EXTRA is the amount in bytes of extra space to leave next to this arg.
5298 : This is ignored if an argument block has already been allocated.
5299 :
5300 : On a machine that lacks real push insns, ARGS_ADDR is the address of
5301 : the bottom of the argument block for this call. We use indexing off there
5302 : to store the arg. On machines with push insns, ARGS_ADDR is 0 when a
5303 : argument block has not been preallocated.
5304 :
5305 : ARGS_SO_FAR is the size of args previously pushed for this call.
5306 :
5307 : REG_PARM_STACK_SPACE is nonzero if functions require stack space
5308 : for arguments passed in registers. If nonzero, it will be the number
5309 : of bytes required. */
5310 :
5311 : bool
5312 2170848 : emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
5313 : unsigned int align, int partial, rtx reg, poly_int64 extra,
5314 : rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
5315 : rtx alignment_pad, bool sibcall_p)
5316 : {
5317 2170848 : rtx xinner;
5318 2170848 : pad_direction stack_direction
5319 : = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
5320 :
5321 : /* Decide where to pad the argument: PAD_DOWNWARD for below,
5322 : PAD_UPWARD for above, or PAD_NONE for don't pad it.
5323 : Default is below for small data on big-endian machines; else above. */
5324 2170848 : pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
5325 :
5326 : /* Invert direction if stack is post-decrement.
5327 : FIXME: why? */
5328 2170848 : if (STACK_PUSH_CODE == POST_DEC)
5329 : if (where_pad != PAD_NONE)
5330 : where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
5331 :
5332 2170848 : xinner = x;
5333 :
5334 2170848 : int nregs = partial / UNITS_PER_WORD;
5335 2170848 : rtx *tmp_regs = NULL;
5336 2170848 : int overlapping = 0;
5337 :
5338 2170848 : if (mode == BLKmode
5339 : || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
5340 : {
5341 : /* Copy a block into the stack, entirely or partially. */
5342 :
5343 269133 : rtx temp;
5344 269133 : int used;
5345 269133 : int offset;
5346 269133 : int skip;
5347 :
5348 269133 : offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5349 269133 : used = partial - offset;
5350 :
5351 269133 : if (mode != BLKmode)
5352 : {
5353 : /* A value is to be stored in an insufficiently aligned
5354 : stack slot; copy via a suitably aligned slot if
5355 : necessary. */
5356 : size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
5357 : if (!MEM_P (xinner))
5358 : {
5359 : temp = assign_temp (type, 1, 1);
5360 : emit_move_insn (temp, xinner);
5361 : xinner = temp;
5362 : }
5363 : }
5364 :
5365 269133 : gcc_assert (size);
5366 :
5367 : /* USED is now the # of bytes we need not copy to the stack
5368 : because registers will take care of them. */
5369 :
5370 269133 : if (partial != 0)
5371 0 : xinner = adjust_address (xinner, BLKmode, used);
5372 :
5373 : /* If the partial register-part of the arg counts in its stack size,
5374 : skip the part of stack space corresponding to the registers.
5375 : Otherwise, start copying to the beginning of the stack space,
5376 : by setting SKIP to 0. */
5377 269133 : skip = (reg_parm_stack_space == 0) ? 0 : used;
5378 :
5379 : #ifdef PUSH_ROUNDING
5380 : /* NB: Let the backend known the number of bytes to push and
5381 : decide if push insns should be generated. */
5382 269133 : unsigned int push_size;
5383 269133 : if (CONST_INT_P (size))
5384 269133 : push_size = INTVAL (size);
5385 : else
5386 : push_size = 0;
5387 :
5388 : /* Do it with several push insns if that doesn't take lots of insns
5389 : and if there is no difficulty with push insns that skip bytes
5390 : on the stack for alignment purposes. */
5391 269133 : if (args_addr == 0
5392 269079 : && targetm.calls.push_argument (push_size)
5393 3783 : && CONST_INT_P (size)
5394 3783 : && skip == 0
5395 3783 : && MEM_ALIGN (xinner) >= align
5396 2941 : && can_move_by_pieces ((unsigned) INTVAL (size) - used, align)
5397 : /* Here we avoid the case of a structure whose weak alignment
5398 : forces many pushes of a small amount of data,
5399 : and such small pushes do rounding that causes trouble. */
5400 2941 : && ((!targetm.slow_unaligned_access (word_mode, align))
5401 0 : || align >= BIGGEST_ALIGNMENT
5402 0 : || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
5403 : align / BITS_PER_UNIT))
5404 272074 : && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
5405 : {
5406 : /* Push padding now if padding above and stack grows down,
5407 : or if padding below and stack grows up.
5408 : But if space already allocated, this has already been done. */
5409 45 : if (maybe_ne (extra, 0)
5410 : && args_addr == 0
5411 0 : && where_pad != PAD_NONE
5412 45 : && where_pad != stack_direction)
5413 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5414 :
5415 45 : move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
5416 : RETURN_BEGIN);
5417 : }
5418 : else
5419 : #endif /* PUSH_ROUNDING */
5420 : {
5421 269088 : rtx target;
5422 :
5423 : /* Otherwise make space on the stack and copy the data
5424 : to the address of that space. */
5425 :
5426 : /* Deduct words put into registers from the size we must copy. */
5427 269088 : if (partial != 0)
5428 : {
5429 0 : if (CONST_INT_P (size))
5430 0 : size = GEN_INT (INTVAL (size) - used);
5431 : else
5432 0 : size = expand_binop (GET_MODE (size), sub_optab, size,
5433 0 : gen_int_mode (used, GET_MODE (size)),
5434 : NULL_RTX, 0, OPTAB_LIB_WIDEN);
5435 : }
5436 :
5437 : /* Get the address of the stack space.
5438 : In this case, we do not deal with EXTRA separately.
5439 : A single stack adjust will do. */
5440 269088 : poly_int64 const_args_so_far;
5441 269088 : if (! args_addr)
5442 : {
5443 269034 : temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
5444 269034 : extra = 0;
5445 : }
5446 54 : else if (poly_int_rtx_p (args_so_far, &const_args_so_far))
5447 72 : temp = memory_address (BLKmode,
5448 : plus_constant (Pmode, args_addr,
5449 : skip + const_args_so_far));
5450 : else
5451 0 : temp = memory_address (BLKmode,
5452 : plus_constant (Pmode,
5453 : gen_rtx_PLUS (Pmode,
5454 : args_addr,
5455 : args_so_far),
5456 : skip));
5457 :
5458 269088 : if (!ACCUMULATE_OUTGOING_ARGS)
5459 : {
5460 : /* If the source is referenced relative to the stack pointer,
5461 : copy it to another register to stabilize it. We do not need
5462 : to do this if we know that we won't be changing sp. */
5463 :
5464 269088 : if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
5465 269088 : || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
5466 269034 : temp = copy_to_reg (temp);
5467 : }
5468 :
5469 269088 : target = gen_rtx_MEM (BLKmode, temp);
5470 :
5471 : /* We do *not* set_mem_attributes here, because incoming arguments
5472 : may overlap with sibling call outgoing arguments and we cannot
5473 : allow reordering of reads from function arguments with stores
5474 : to outgoing arguments of sibling calls. We do, however, want
5475 : to record the alignment of the stack slot. */
5476 : /* ALIGN may well be better aligned than TYPE, e.g. due to
5477 : PARM_BOUNDARY. Assume the caller isn't lying. */
5478 269088 : set_mem_align (target, align);
5479 :
5480 : /* If part should go in registers and pushing to that part would
5481 : overwrite some of the values that need to go into regs, load the
5482 : overlapping values into temporary pseudos to be moved into the hard
5483 : regs at the end after the stack pushing has completed.
5484 : We cannot load them directly into the hard regs here because
5485 : they can be clobbered by the block move expansions.
5486 : See PR 65358. */
5487 :
5488 269088 : if (partial > 0 && reg != 0 && mode == BLKmode
5489 0 : && GET_CODE (reg) != PARALLEL)
5490 : {
5491 0 : overlapping = memory_load_overlap (XEXP (x, 0), temp, partial);
5492 0 : if (overlapping > 0)
5493 : {
5494 0 : gcc_assert (overlapping % UNITS_PER_WORD == 0);
5495 0 : overlapping /= UNITS_PER_WORD;
5496 :
5497 0 : tmp_regs = XALLOCAVEC (rtx, overlapping);
5498 :
5499 0 : for (int i = 0; i < overlapping; i++)
5500 0 : tmp_regs[i] = gen_reg_rtx (word_mode);
5501 :
5502 0 : for (int i = 0; i < overlapping; i++)
5503 0 : emit_move_insn (tmp_regs[i],
5504 0 : operand_subword_force (target, i, mode));
5505 : }
5506 0 : else if (overlapping == -1)
5507 : overlapping = 0;
5508 : /* Could not determine whether there is overlap.
5509 : Fail the sibcall. */
5510 : else
5511 : {
5512 0 : overlapping = 0;
5513 0 : if (sibcall_p)
5514 0 : return false;
5515 : }
5516 : }
5517 :
5518 : /* If source is a constant VAR_DECL with a simple constructor,
5519 : store the constructor to the stack instead of moving it. */
5520 269088 : const_tree decl;
5521 269088 : HOST_WIDE_INT sz;
5522 269088 : if (partial == 0
5523 269088 : && MEM_P (xinner)
5524 269088 : && SYMBOL_REF_P (XEXP (xinner, 0))
5525 82554 : && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
5526 82554 : && VAR_P (decl)
5527 82554 : && TREE_READONLY (decl)
5528 5183 : && !TREE_SIDE_EFFECTS (decl)
5529 5183 : && immediate_const_ctor_p (DECL_INITIAL (decl), 2)
5530 9 : && (sz = int_expr_size (DECL_INITIAL (decl))) > 0
5531 9 : && CONST_INT_P (size)
5532 269097 : && INTVAL (size) == sz)
5533 3 : store_constructor (DECL_INITIAL (decl), target, 0, sz, false);
5534 : else
5535 269085 : emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
5536 : }
5537 : }
5538 1901715 : else if (partial > 0)
5539 : {
5540 : /* Scalar partly in registers. This case is only supported
5541 : for fixed-wdth modes. */
5542 0 : int num_words = GET_MODE_SIZE (mode).to_constant ();
5543 0 : num_words /= UNITS_PER_WORD;
5544 0 : int i;
5545 0 : int not_stack;
5546 : /* # bytes of start of argument
5547 : that we must make space for but need not store. */
5548 0 : int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5549 0 : int args_offset = INTVAL (args_so_far);
5550 0 : int skip;
5551 :
5552 : /* Push padding now if padding above and stack grows down,
5553 : or if padding below and stack grows up.
5554 : But if space already allocated, this has already been done. */
5555 0 : if (maybe_ne (extra, 0)
5556 0 : && args_addr == 0
5557 0 : && where_pad != PAD_NONE
5558 0 : && where_pad != stack_direction)
5559 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5560 :
5561 : /* If we make space by pushing it, we might as well push
5562 : the real data. Otherwise, we can leave OFFSET nonzero
5563 : and leave the space uninitialized. */
5564 0 : if (args_addr == 0)
5565 0 : offset = 0;
5566 :
5567 : /* Now NOT_STACK gets the number of words that we don't need to
5568 : allocate on the stack. Convert OFFSET to words too. */
5569 0 : not_stack = (partial - offset) / UNITS_PER_WORD;
5570 0 : offset /= UNITS_PER_WORD;
5571 :
5572 : /* If the partial register-part of the arg counts in its stack size,
5573 : skip the part of stack space corresponding to the registers.
5574 : Otherwise, start copying to the beginning of the stack space,
5575 : by setting SKIP to 0. */
5576 0 : skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
5577 :
5578 0 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
5579 0 : x = validize_mem (force_const_mem (mode, x));
5580 :
5581 : /* If X is a hard register in a non-integer mode, copy it into a pseudo;
5582 : SUBREGs of such registers are not allowed. */
5583 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
5584 0 : && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
5585 0 : x = copy_to_reg (x);
5586 :
5587 : /* Loop over all the words allocated on the stack for this arg. */
5588 : /* We can do it by words, because any scalar bigger than a word
5589 : has a size a multiple of a word. */
5590 0 : tree word_mode_type = lang_hooks.types.type_for_mode (word_mode, 1);
5591 0 : for (i = num_words - 1; i >= not_stack; i--)
5592 0 : if (i >= not_stack + offset)
5593 0 : if (!emit_push_insn (operand_subword_force (x, i, mode),
5594 : word_mode, word_mode_type, NULL_RTX, align, 0,
5595 : NULL_RTX, 0, args_addr,
5596 0 : GEN_INT (args_offset + ((i - not_stack + skip)
5597 : * UNITS_PER_WORD)),
5598 : reg_parm_stack_space, alignment_pad, sibcall_p))
5599 0 : return false;
5600 : }
5601 : else
5602 : {
5603 1901715 : rtx addr;
5604 1901715 : rtx dest;
5605 :
5606 : /* Push padding now if padding above and stack grows down,
5607 : or if padding below and stack grows up.
5608 : But if space already allocated, this has already been done. */
5609 1901715 : if (maybe_ne (extra, 0)
5610 0 : && args_addr == 0
5611 0 : && where_pad != PAD_NONE
5612 1901715 : && where_pad != stack_direction)
5613 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5614 :
5615 : #ifdef PUSH_ROUNDING
5616 1901715 : if (args_addr == 0 && targetm.calls.push_argument (0))
5617 1846371 : emit_single_push_insn (mode, x, type);
5618 : else
5619 : #endif
5620 : {
5621 63583 : addr = simplify_gen_binary (PLUS, Pmode, args_addr, args_so_far);
5622 55344 : dest = gen_rtx_MEM (mode, memory_address (mode, addr));
5623 :
5624 : /* We do *not* set_mem_attributes here, because incoming arguments
5625 : may overlap with sibling call outgoing arguments and we cannot
5626 : allow reordering of reads from function arguments with stores
5627 : to outgoing arguments of sibling calls. We do, however, want
5628 : to record the alignment of the stack slot. */
5629 : /* ALIGN may well be better aligned than TYPE, e.g. due to
5630 : PARM_BOUNDARY. Assume the caller isn't lying. */
5631 55344 : set_mem_align (dest, align);
5632 :
5633 55344 : emit_move_insn (dest, x);
5634 : }
5635 : }
5636 :
5637 : /* Move the partial arguments into the registers and any overlapping
5638 : values that we moved into the pseudos in tmp_regs. */
5639 2170848 : if (partial > 0 && reg != 0)
5640 : {
5641 : /* Handle calls that pass values in multiple non-contiguous locations.
5642 : The Irix 6 ABI has examples of this. */
5643 0 : if (GET_CODE (reg) == PARALLEL)
5644 0 : emit_group_load (reg, x, type, -1);
5645 : else
5646 : {
5647 0 : gcc_assert (partial % UNITS_PER_WORD == 0);
5648 0 : move_block_to_reg (REGNO (reg), x, nregs - overlapping, mode);
5649 :
5650 0 : for (int i = 0; i < overlapping; i++)
5651 0 : emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg)
5652 0 : + nregs - overlapping + i),
5653 0 : tmp_regs[i]);
5654 :
5655 : }
5656 : }
5657 :
5658 2170848 : if (maybe_ne (extra, 0) && args_addr == 0 && where_pad == stack_direction)
5659 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5660 :
5661 2170848 : if (alignment_pad && args_addr == 0)
5662 2115450 : anti_adjust_stack (alignment_pad);
5663 :
5664 : return true;
5665 : }
5666 :
5667 : /* Return X if X can be used as a subtarget in a sequence of arithmetic
5668 : operations. */
5669 :
5670 : static rtx
5671 203732050 : get_subtarget (rtx x)
5672 : {
5673 203732050 : return (optimize
5674 52897503 : || x == 0
5675 : /* Only registers can be subtargets. */
5676 17709164 : || !REG_P (x)
5677 : /* Don't use hard regs to avoid extending their life. */
5678 12042394 : || REGNO (x) < FIRST_PSEUDO_REGISTER
5679 203732050 : ? 0 : x);
5680 : }
5681 :
5682 : /* A subroutine of expand_assignment. Optimize FIELD op= VAL, where
5683 : FIELD is a bitfield. Returns true if the optimization was successful,
5684 : and there's nothing else to do. */
5685 :
5686 : static bool
5687 4774649 : optimize_bitfield_assignment_op (poly_uint64 pbitsize,
5688 : poly_uint64 pbitpos,
5689 : poly_uint64 pbitregion_start,
5690 : poly_uint64 pbitregion_end,
5691 : machine_mode mode1, rtx str_rtx,
5692 : tree to, tree src, bool reverse)
5693 : {
5694 : /* str_mode is not guaranteed to be a scalar type. */
5695 4774649 : machine_mode str_mode = GET_MODE (str_rtx);
5696 4774649 : unsigned int str_bitsize;
5697 4774649 : tree op0, op1;
5698 4774649 : rtx value, result;
5699 4774649 : optab binop;
5700 4774649 : gimple *srcstmt;
5701 4774649 : enum tree_code code;
5702 :
5703 4774649 : unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
5704 4774649 : if (mode1 != VOIDmode
5705 67161 : || !pbitsize.is_constant (&bitsize)
5706 67161 : || !pbitpos.is_constant (&bitpos)
5707 67161 : || !pbitregion_start.is_constant (&bitregion_start)
5708 67161 : || !pbitregion_end.is_constant (&bitregion_end)
5709 67796 : || bitsize >= BITS_PER_WORD
5710 66890 : || !GET_MODE_BITSIZE (str_mode).is_constant (&str_bitsize)
5711 67525 : || str_bitsize > BITS_PER_WORD
5712 61480 : || TREE_SIDE_EFFECTS (to)
5713 4836000 : || TREE_THIS_VOLATILE (to))
5714 : return false;
5715 :
5716 61351 : STRIP_NOPS (src);
5717 61351 : if (TREE_CODE (src) != SSA_NAME)
5718 : return false;
5719 20194 : if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
5720 : return false;
5721 :
5722 18598 : srcstmt = get_gimple_for_ssa_name (src);
5723 18598 : if (!srcstmt
5724 4961 : || !is_gimple_assign (srcstmt)
5725 23559 : || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
5726 : return false;
5727 :
5728 851 : code = gimple_assign_rhs_code (srcstmt);
5729 :
5730 851 : op0 = gimple_assign_rhs1 (srcstmt);
5731 :
5732 : /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
5733 : to find its initialization. Hopefully the initialization will
5734 : be from a bitfield load. */
5735 851 : if (TREE_CODE (op0) == SSA_NAME)
5736 : {
5737 851 : gimple *op0stmt = get_gimple_for_ssa_name (op0);
5738 :
5739 : /* We want to eventually have OP0 be the same as TO, which
5740 : should be a bitfield. */
5741 851 : if (!op0stmt
5742 785 : || !is_gimple_assign (op0stmt)
5743 1636 : || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
5744 : return false;
5745 548 : op0 = gimple_assign_rhs1 (op0stmt);
5746 : }
5747 :
5748 548 : op1 = gimple_assign_rhs2 (srcstmt);
5749 :
5750 548 : if (!operand_equal_p (to, op0, 0))
5751 : return false;
5752 :
5753 463 : if (MEM_P (str_rtx))
5754 : {
5755 422 : unsigned HOST_WIDE_INT offset1;
5756 :
5757 422 : if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
5758 82 : str_bitsize = BITS_PER_WORD;
5759 :
5760 422 : scalar_int_mode best_mode;
5761 422 : if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
5762 422 : MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
5763 0 : return false;
5764 422 : str_mode = best_mode;
5765 422 : str_bitsize = GET_MODE_BITSIZE (best_mode);
5766 :
5767 422 : offset1 = bitpos;
5768 422 : bitpos %= str_bitsize;
5769 422 : offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
5770 422 : str_rtx = adjust_address (str_rtx, str_mode, offset1);
5771 : }
5772 41 : else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
5773 : return false;
5774 :
5775 : /* If the bit field covers the whole REG/MEM, store_field
5776 : will likely generate better code. */
5777 463 : if (bitsize >= str_bitsize)
5778 : return false;
5779 :
5780 : /* We can't handle fields split across multiple entities. */
5781 463 : if (bitpos + bitsize > str_bitsize)
5782 : return false;
5783 :
5784 463 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
5785 0 : bitpos = str_bitsize - bitpos - bitsize;
5786 :
5787 463 : switch (code)
5788 : {
5789 140 : case PLUS_EXPR:
5790 140 : case MINUS_EXPR:
5791 : /* For now, just optimize the case of the topmost bitfield
5792 : where we don't need to do any masking and also
5793 : 1 bit bitfields where xor can be used.
5794 : We might win by one instruction for the other bitfields
5795 : too if insv/extv instructions aren't used, so that
5796 : can be added later. */
5797 140 : if ((reverse || bitpos + bitsize != str_bitsize)
5798 96 : && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
5799 : break;
5800 :
5801 69 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5802 69 : value = convert_modes (str_mode,
5803 69 : TYPE_MODE (TREE_TYPE (op1)), value,
5804 69 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5805 :
5806 : /* We may be accessing data outside the field, which means
5807 : we can alias adjacent data. */
5808 69 : if (MEM_P (str_rtx))
5809 : {
5810 69 : str_rtx = shallow_copy_rtx (str_rtx);
5811 69 : set_mem_alias_set (str_rtx, 0);
5812 69 : set_mem_expr (str_rtx, 0);
5813 : }
5814 :
5815 69 : if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
5816 : {
5817 25 : value = expand_and (str_mode, value, const1_rtx, NULL);
5818 25 : binop = xor_optab;
5819 : }
5820 : else
5821 44 : binop = code == PLUS_EXPR ? add_optab : sub_optab;
5822 :
5823 69 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5824 69 : if (reverse)
5825 0 : value = flip_storage_order (str_mode, value);
5826 69 : result = expand_binop (str_mode, binop, str_rtx,
5827 : value, str_rtx, 1, OPTAB_WIDEN);
5828 69 : if (result != str_rtx)
5829 0 : emit_move_insn (str_rtx, result);
5830 : return true;
5831 :
5832 255 : case BIT_IOR_EXPR:
5833 255 : case BIT_XOR_EXPR:
5834 255 : if (TREE_CODE (op1) != INTEGER_CST)
5835 : break;
5836 97 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5837 97 : value = convert_modes (str_mode,
5838 97 : TYPE_MODE (TREE_TYPE (op1)), value,
5839 97 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5840 :
5841 : /* We may be accessing data outside the field, which means
5842 : we can alias adjacent data. */
5843 97 : if (MEM_P (str_rtx))
5844 : {
5845 61 : str_rtx = shallow_copy_rtx (str_rtx);
5846 61 : set_mem_alias_set (str_rtx, 0);
5847 61 : set_mem_expr (str_rtx, 0);
5848 : }
5849 :
5850 97 : binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
5851 97 : if (bitpos + bitsize != str_bitsize)
5852 : {
5853 55 : rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
5854 : str_mode);
5855 55 : value = expand_and (str_mode, value, mask, NULL_RTX);
5856 : }
5857 97 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5858 97 : if (reverse)
5859 0 : value = flip_storage_order (str_mode, value);
5860 97 : result = expand_binop (str_mode, binop, str_rtx,
5861 : value, str_rtx, 1, OPTAB_WIDEN);
5862 97 : if (result != str_rtx)
5863 0 : emit_move_insn (str_rtx, result);
5864 : return true;
5865 :
5866 : default:
5867 : break;
5868 : }
5869 :
5870 : return false;
5871 : }
5872 :
5873 : /* In the C++ memory model, consecutive bit fields in a structure are
5874 : considered one memory location.
5875 :
5876 : Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
5877 : returns the bit range of consecutive bits in which this COMPONENT_REF
5878 : belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
5879 : and *OFFSET may be adjusted in the process.
5880 :
5881 : If the access does not need to be restricted, 0 is returned in both
5882 : *BITSTART and *BITEND. */
5883 :
5884 : void
5885 885565 : get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
5886 : poly_int64 *bitpos, tree *offset)
5887 : {
5888 885565 : poly_int64 bitoffset;
5889 885565 : tree field, repr;
5890 :
5891 885565 : gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
5892 :
5893 885565 : field = TREE_OPERAND (exp, 1);
5894 885565 : repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
5895 : /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
5896 : need to limit the range we can access. */
5897 885565 : if (!repr)
5898 : {
5899 65 : *bitstart = *bitend = 0;
5900 65 : return;
5901 : }
5902 :
5903 : /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
5904 : part of a larger bit field, then the representative does not serve any
5905 : useful purpose. This can occur in Ada. */
5906 885500 : if (handled_component_p (TREE_OPERAND (exp, 0)))
5907 : {
5908 458567 : machine_mode rmode;
5909 458567 : poly_int64 rbitsize, rbitpos;
5910 458567 : tree roffset;
5911 458567 : int unsignedp, reversep, volatilep = 0;
5912 458567 : get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
5913 : &roffset, &rmode, &unsignedp, &reversep,
5914 : &volatilep);
5915 917134 : if (!multiple_p (rbitpos, BITS_PER_UNIT))
5916 : {
5917 0 : *bitstart = *bitend = 0;
5918 0 : return;
5919 : }
5920 : }
5921 :
5922 : /* Compute the adjustment to bitpos from the offset of the field
5923 : relative to the representative. DECL_FIELD_OFFSET of field and
5924 : repr are the same by construction if they are not constants,
5925 : see finish_bitfield_layout. */
5926 885500 : poly_uint64 field_offset, repr_offset;
5927 885500 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
5928 1770995 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
5929 885495 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
5930 : else
5931 : bitoffset = 0;
5932 885500 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
5933 885500 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
5934 :
5935 : /* If the adjustment is larger than bitpos, we would have a negative bit
5936 : position for the lower bound and this may wreak havoc later. Adjust
5937 : offset and bitpos to make the lower bound non-negative in that case. */
5938 885500 : if (maybe_gt (bitoffset, *bitpos))
5939 : {
5940 9 : poly_int64 adjust_bits = upper_bound (bitoffset, *bitpos) - *bitpos;
5941 9 : poly_int64 adjust_bytes = exact_div (adjust_bits, BITS_PER_UNIT);
5942 :
5943 9 : *bitpos += adjust_bits;
5944 9 : if (*offset == NULL_TREE)
5945 5 : *offset = size_int (-adjust_bytes);
5946 : else
5947 4 : *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
5948 9 : *bitstart = 0;
5949 : }
5950 : else
5951 885491 : *bitstart = *bitpos - bitoffset;
5952 :
5953 885500 : *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
5954 : }
5955 :
5956 : /* Returns true if BASE is a DECL that does not reside in memory and
5957 : has non-BLKmode. DECL_RTL must not be a MEM; if
5958 : DECL_RTL was not set yet, return false. */
5959 :
5960 : bool
5961 5507086 : non_mem_decl_p (tree base)
5962 : {
5963 5507086 : if (!DECL_P (base)
5964 5506695 : || TREE_ADDRESSABLE (base)
5965 7958647 : || DECL_MODE (base) == BLKmode)
5966 : return false;
5967 :
5968 1589896 : if (!DECL_RTL_SET_P (base))
5969 : return false;
5970 :
5971 1471285 : return (!MEM_P (DECL_RTL (base)));
5972 : }
5973 :
5974 : /* Returns true if REF refers to an object that does not
5975 : reside in memory and has non-BLKmode. */
5976 :
5977 : bool
5978 12024528 : mem_ref_refers_to_non_mem_p (tree ref)
5979 : {
5980 12024528 : tree base;
5981 :
5982 12024528 : if (TREE_CODE (ref) == MEM_REF
5983 12024528 : || TREE_CODE (ref) == TARGET_MEM_REF)
5984 : {
5985 10497093 : tree addr = TREE_OPERAND (ref, 0);
5986 :
5987 10497093 : if (TREE_CODE (addr) != ADDR_EXPR)
5988 : return false;
5989 :
5990 3954455 : base = TREE_OPERAND (addr, 0);
5991 : }
5992 : else
5993 : base = ref;
5994 :
5995 5481890 : return non_mem_decl_p (base);
5996 : }
5997 :
5998 : /* Helper function of expand_assignment. Check if storing field of
5999 : size BITSIZE at position BITPOS overlaps with the most significant
6000 : bit of TO_RTX, known to be SUBREG_PROMOTED_VAR_P.
6001 : Updating this field requires an explicit extension. */
6002 : static bool
6003 0 : store_field_updates_msb_p (poly_int64 bitpos, poly_int64 bitsize, rtx to_rtx)
6004 : {
6005 0 : return (BYTES_BIG_ENDIAN
6006 : ? maybe_le (bitpos, 0)
6007 0 : : maybe_ge (bitpos + bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))));
6008 : }
6009 :
6010 : /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL
6011 : is true, try generating a nontemporal store. */
6012 :
6013 : void
6014 18619784 : expand_assignment (tree to, tree from, bool nontemporal)
6015 : {
6016 18619784 : rtx to_rtx = 0;
6017 18619784 : rtx result;
6018 18619784 : machine_mode mode;
6019 18619784 : unsigned int align;
6020 18619784 : enum insn_code icode;
6021 :
6022 : /* Don't crash if the lhs of the assignment was erroneous. */
6023 18619784 : if (TREE_CODE (to) == ERROR_MARK)
6024 : {
6025 0 : expand_normal (from);
6026 0 : return;
6027 : }
6028 :
6029 : /* Optimize away no-op moves without side-effects. */
6030 18619784 : if (operand_equal_p (to, from, 0))
6031 : return;
6032 :
6033 : /* Handle misaligned stores. */
6034 18619629 : mode = TYPE_MODE (TREE_TYPE (to));
6035 18619629 : if ((TREE_CODE (to) == MEM_REF
6036 18619629 : || TREE_CODE (to) == TARGET_MEM_REF
6037 16407989 : || DECL_P (to))
6038 4068640 : && mode != BLKmode
6039 3602295 : && !mem_ref_refers_to_non_mem_p (to)
6040 6458246 : && ((align = get_object_alignment (to))
6041 3229123 : < GET_MODE_ALIGNMENT (mode))
6042 19051319 : && (((icode = optab_handler (movmisalign_optab, mode))
6043 : != CODE_FOR_nothing)
6044 96787 : || targetm.slow_unaligned_access (mode, align)))
6045 : {
6046 334903 : rtx reg, mem;
6047 :
6048 334903 : reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6049 : /* Handle PARALLEL. */
6050 334903 : reg = maybe_emit_group_store (reg, TREE_TYPE (from));
6051 334903 : reg = force_not_mem (reg);
6052 334903 : mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6053 334903 : if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
6054 0 : reg = flip_storage_order (mode, reg);
6055 :
6056 334903 : if (icode != CODE_FOR_nothing)
6057 : {
6058 334903 : class expand_operand ops[2];
6059 :
6060 334903 : create_fixed_operand (&ops[0], mem);
6061 334903 : create_input_operand (&ops[1], reg, mode);
6062 : /* The movmisalign<mode> pattern cannot fail, else the assignment
6063 : would silently be omitted. */
6064 334903 : expand_insn (icode, 2, ops);
6065 : }
6066 : else
6067 0 : store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
6068 : false, false);
6069 334903 : return;
6070 : }
6071 :
6072 : /* Assignment of a structure component needs special treatment
6073 : if the structure component's rtx is not simply a MEM.
6074 : Assignment of an array element at a constant index, and assignment of
6075 : an array element in an unaligned packed structure field, has the same
6076 : problem. Same for (partially) storing into a non-memory object. */
6077 18284726 : if (handled_component_p (to)
6078 13740592 : || (TREE_CODE (to) == MEM_REF
6079 1641196 : && (REF_REVERSE_STORAGE_ORDER (to)
6080 1641116 : || mem_ref_refers_to_non_mem_p (to)))
6081 13631059 : || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
6082 : {
6083 4774780 : machine_mode mode1;
6084 4774780 : poly_int64 bitsize, bitpos;
6085 4774780 : poly_uint64 bitregion_start = 0;
6086 4774780 : poly_uint64 bitregion_end = 0;
6087 4774780 : tree offset;
6088 4774780 : int unsignedp, reversep, volatilep = 0;
6089 4774780 : tree tem;
6090 :
6091 4774780 : push_temp_slots ();
6092 4774780 : tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
6093 : &unsignedp, &reversep, &volatilep);
6094 :
6095 : /* Make sure bitpos is not negative, it can wreak havoc later. */
6096 4774780 : if (maybe_lt (bitpos, 0))
6097 : {
6098 199 : gcc_assert (offset == NULL_TREE);
6099 199 : offset = size_int (bits_to_bytes_round_down (bitpos));
6100 199 : bitpos = num_trailing_bits (bitpos);
6101 : }
6102 :
6103 4774780 : if (TREE_CODE (to) == COMPONENT_REF
6104 4774780 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
6105 85340 : get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
6106 : /* The C++ memory model naturally applies to byte-aligned fields.
6107 : However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
6108 : BITSIZE are not byte-aligned, there is no need to limit the range
6109 : we can access. This can occur with packed structures in Ada. */
6110 4689440 : else if (maybe_gt (bitsize, 0)
6111 4689425 : && multiple_p (bitsize, BITS_PER_UNIT)
6112 9378598 : && multiple_p (bitpos, BITS_PER_UNIT))
6113 : {
6114 4689158 : bitregion_start = bitpos;
6115 4689158 : bitregion_end = bitpos + bitsize - 1;
6116 : }
6117 :
6118 4774780 : to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
6119 :
6120 : /* If the field has a mode, we want to access it in the
6121 : field's mode, not the computed mode.
6122 : If a MEM has VOIDmode (external with incomplete type),
6123 : use BLKmode for it instead. */
6124 4774780 : if (MEM_P (to_rtx))
6125 : {
6126 4082868 : if (mode1 != VOIDmode)
6127 4016444 : to_rtx = adjust_address (to_rtx, mode1, 0);
6128 66424 : else if (GET_MODE (to_rtx) == VOIDmode)
6129 0 : to_rtx = adjust_address (to_rtx, BLKmode, 0);
6130 : }
6131 :
6132 4774780 : rtx stemp = NULL_RTX, old_to_rtx = NULL_RTX;
6133 4774780 : if (offset != 0)
6134 : {
6135 179004 : machine_mode address_mode;
6136 179004 : rtx offset_rtx;
6137 :
6138 179004 : if (!MEM_P (to_rtx))
6139 : {
6140 : /* We can get constant negative offsets into arrays with broken
6141 : user code. Translate this to a trap instead of ICEing. */
6142 4 : if (TREE_CODE (offset) == INTEGER_CST)
6143 : {
6144 1 : expand_builtin_trap ();
6145 1 : to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
6146 : }
6147 : /* Else spill for variable offset to the destination. We expect
6148 : to run into this only for hard registers. */
6149 : else
6150 : {
6151 3 : gcc_assert (VAR_P (tem) && DECL_HARD_REGISTER (tem));
6152 3 : stemp = assign_stack_temp (GET_MODE (to_rtx),
6153 6 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6154 3 : emit_move_insn (stemp, to_rtx);
6155 3 : old_to_rtx = to_rtx;
6156 3 : to_rtx = stemp;
6157 : }
6158 : }
6159 :
6160 179004 : offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
6161 179004 : address_mode = get_address_mode (to_rtx);
6162 179004 : if (GET_MODE (offset_rtx) != address_mode)
6163 : {
6164 : /* We cannot be sure that the RTL in offset_rtx is valid outside
6165 : of a memory address context, so force it into a register
6166 : before attempting to convert it to the desired mode. */
6167 223 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
6168 223 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
6169 : }
6170 :
6171 : /* If we have an expression in OFFSET_RTX and a non-zero
6172 : byte offset in BITPOS, adding the byte offset before the
6173 : OFFSET_RTX results in better intermediate code, which makes
6174 : later rtl optimization passes perform better.
6175 :
6176 : We prefer intermediate code like this:
6177 :
6178 : r124:DI=r123:DI+0x18
6179 : [r124:DI]=r121:DI
6180 :
6181 : ... instead of ...
6182 :
6183 : r124:DI=r123:DI+0x10
6184 : [r124:DI+0x8]=r121:DI
6185 :
6186 : This is only done for aligned data values, as these can
6187 : be expected to result in single move instructions. */
6188 179004 : poly_int64 bytepos;
6189 179004 : if (mode1 != VOIDmode
6190 178896 : && maybe_ne (bitpos, 0)
6191 47753 : && maybe_gt (bitsize, 0)
6192 226757 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
6193 226631 : && multiple_p (bitpos, bitsize)
6194 95254 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
6195 226631 : && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
6196 : {
6197 47378 : to_rtx = adjust_address (to_rtx, mode1, bytepos);
6198 47378 : bitregion_start = 0;
6199 47378 : if (known_ge (bitregion_end, poly_uint64 (bitpos)))
6200 47378 : bitregion_end -= bitpos;
6201 47378 : bitpos = 0;
6202 : }
6203 :
6204 179004 : to_rtx = offset_address (to_rtx, offset_rtx,
6205 : highest_pow2_factor_for_target (to,
6206 : offset));
6207 : }
6208 :
6209 : /* No action is needed if the target is not a memory and the field
6210 : lies completely outside that target. This can occur if the source
6211 : code contains an out-of-bounds access to a small array. */
6212 4774780 : if (!MEM_P (to_rtx)
6213 691908 : && GET_MODE (to_rtx) != BLKmode
6214 5466688 : && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
6215 : {
6216 3 : expand_normal (from);
6217 3 : result = NULL;
6218 : }
6219 : /* Handle expand_expr of a complex value returning a CONCAT. */
6220 4774777 : else if (GET_CODE (to_rtx) == CONCAT)
6221 : {
6222 122 : machine_mode to_mode = GET_MODE (to_rtx);
6223 122 : gcc_checking_assert (COMPLEX_MODE_P (to_mode));
6224 244 : poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode);
6225 122 : unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
6226 122 : if (TYPE_MODE (TREE_TYPE (from)) == to_mode
6227 0 : && known_eq (bitpos, 0)
6228 122 : && known_eq (bitsize, mode_bitsize))
6229 0 : result = store_expr (from, to_rtx, false, nontemporal, reversep);
6230 122 : else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
6231 70 : && known_eq (bitsize, inner_bitsize)
6232 192 : && (known_eq (bitpos, 0)
6233 31 : || known_eq (bitpos, inner_bitsize)))
6234 70 : result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
6235 : false, nontemporal, reversep);
6236 52 : else if (known_le (bitpos + bitsize, inner_bitsize))
6237 5 : result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
6238 : bitregion_start, bitregion_end,
6239 : mode1, from, get_alias_set (to),
6240 : nontemporal, reversep);
6241 47 : else if (known_ge (bitpos, inner_bitsize))
6242 3 : result = store_field (XEXP (to_rtx, 1), bitsize,
6243 : bitpos - inner_bitsize,
6244 : bitregion_start, bitregion_end,
6245 : mode1, from, get_alias_set (to),
6246 : nontemporal, reversep);
6247 44 : else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
6248 : {
6249 37 : result = expand_normal (from);
6250 37 : if (GET_CODE (result) == CONCAT)
6251 : {
6252 0 : to_mode = GET_MODE_INNER (to_mode);
6253 0 : machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
6254 0 : rtx from_real
6255 0 : = force_subreg (to_mode, XEXP (result, 0), from_mode, 0);
6256 0 : rtx from_imag
6257 0 : = force_subreg (to_mode, XEXP (result, 1), from_mode, 0);
6258 0 : if (!from_real || !from_imag)
6259 0 : goto concat_store_slow;
6260 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6261 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6262 : }
6263 : else
6264 : {
6265 37 : machine_mode from_mode
6266 37 : = GET_MODE (result) == VOIDmode
6267 37 : ? TYPE_MODE (TREE_TYPE (from))
6268 37 : : GET_MODE (result);
6269 37 : rtx from_rtx;
6270 37 : if (MEM_P (result))
6271 1 : from_rtx = change_address (result, to_mode, NULL_RTX);
6272 : else
6273 36 : from_rtx = force_subreg (to_mode, result, from_mode, 0);
6274 37 : if (from_rtx)
6275 : {
6276 37 : emit_move_insn (XEXP (to_rtx, 0),
6277 : read_complex_part (from_rtx, false));
6278 37 : emit_move_insn (XEXP (to_rtx, 1),
6279 : read_complex_part (from_rtx, true));
6280 : }
6281 : else
6282 : {
6283 0 : to_mode = GET_MODE_INNER (to_mode);
6284 0 : rtx from_real
6285 0 : = force_subreg (to_mode, result, from_mode, 0);
6286 0 : rtx from_imag
6287 0 : = force_subreg (to_mode, result, from_mode,
6288 0 : GET_MODE_SIZE (to_mode));
6289 0 : if (!from_real || !from_imag)
6290 0 : goto concat_store_slow;
6291 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6292 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6293 : }
6294 : }
6295 : }
6296 : else
6297 : {
6298 7 : concat_store_slow:;
6299 7 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6300 14 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6301 7 : write_complex_part (temp, XEXP (to_rtx, 0), false, true);
6302 7 : write_complex_part (temp, XEXP (to_rtx, 1), true, false);
6303 7 : result = store_field (temp, bitsize, bitpos,
6304 : bitregion_start, bitregion_end,
6305 : mode1, from, get_alias_set (to),
6306 : nontemporal, reversep);
6307 7 : emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
6308 7 : emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
6309 : }
6310 : }
6311 : /* For calls to functions returning variable length structures, if TO_RTX
6312 : is not a MEM, go through a MEM because we must not create temporaries
6313 : of the VLA type. */
6314 4774655 : else if (!MEM_P (to_rtx)
6315 691783 : && TREE_CODE (from) == CALL_EXPR
6316 232 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6317 4774887 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
6318 : {
6319 6 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6320 12 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6321 6 : result = store_field (temp, bitsize, bitpos, bitregion_start,
6322 : bitregion_end, mode1, from, get_alias_set (to),
6323 : nontemporal, reversep);
6324 6 : emit_move_insn (to_rtx, temp);
6325 : }
6326 : else
6327 : {
6328 4774649 : if (MEM_P (to_rtx))
6329 : {
6330 : /* If the field is at offset zero, we could have been given the
6331 : DECL_RTX of the parent struct. Don't munge it. */
6332 4082872 : to_rtx = shallow_copy_rtx (to_rtx);
6333 4082872 : set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
6334 4082872 : if (volatilep)
6335 8693 : MEM_VOLATILE_P (to_rtx) = 1;
6336 : }
6337 :
6338 4774649 : gcc_checking_assert (known_ge (bitpos, 0));
6339 4774649 : if (optimize_bitfield_assignment_op (bitsize, bitpos,
6340 : bitregion_start, bitregion_end,
6341 : mode1, to_rtx, to, from,
6342 : reversep))
6343 : result = NULL;
6344 4774483 : else if (SUBREG_P (to_rtx)
6345 4774483 : && SUBREG_PROMOTED_VAR_P (to_rtx))
6346 : {
6347 : /* If to_rtx is a promoted subreg, we need to zero or sign
6348 : extend the value afterwards. */
6349 0 : if (TREE_CODE (to) == MEM_REF
6350 0 : && TYPE_MODE (TREE_TYPE (from)) != BLKmode
6351 0 : && !REF_REVERSE_STORAGE_ORDER (to)
6352 0 : && known_eq (bitpos, 0)
6353 0 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
6354 0 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6355 : /* Check if the field overlaps the MSB, requiring extension. */
6356 0 : else if (store_field_updates_msb_p (bitpos, bitsize, to_rtx))
6357 : {
6358 0 : scalar_int_mode imode = subreg_unpromoted_mode (to_rtx);
6359 0 : scalar_int_mode omode = subreg_promoted_mode (to_rtx);
6360 0 : rtx to_rtx1 = lowpart_subreg (imode, SUBREG_REG (to_rtx),
6361 : omode);
6362 0 : result = store_field (to_rtx1, bitsize, bitpos,
6363 : bitregion_start, bitregion_end,
6364 : mode1, from, get_alias_set (to),
6365 : nontemporal, reversep);
6366 : /* If the target usually keeps IMODE appropriately
6367 : extended in OMODE it's unsafe to refer to it using
6368 : a SUBREG whilst this invariant doesn't hold. */
6369 0 : if (targetm.mode_rep_extended (imode, omode) != UNKNOWN)
6370 0 : to_rtx1 = simplify_gen_unary (TRUNCATE, imode,
6371 : SUBREG_REG (to_rtx), omode);
6372 0 : convert_move (SUBREG_REG (to_rtx), to_rtx1,
6373 0 : SUBREG_PROMOTED_SIGN (to_rtx));
6374 : }
6375 : else
6376 0 : result = store_field (to_rtx, bitsize, bitpos,
6377 : bitregion_start, bitregion_end,
6378 : mode1, from, get_alias_set (to),
6379 : nontemporal, reversep);
6380 : }
6381 : else
6382 4774483 : result = store_field (to_rtx, bitsize, bitpos,
6383 : bitregion_start, bitregion_end,
6384 : mode1, from, get_alias_set (to),
6385 : nontemporal, reversep);
6386 : /* Move the temporary storage back to the non-MEM_P. */
6387 4774649 : if (stemp)
6388 3 : emit_move_insn (old_to_rtx, stemp);
6389 : }
6390 :
6391 4774780 : if (result)
6392 833089 : preserve_temp_slots (result);
6393 4774780 : pop_temp_slots ();
6394 4774780 : return;
6395 : }
6396 :
6397 : /* If the rhs is a function call and its value is not an aggregate,
6398 : call the function before we start to compute the lhs.
6399 : This is needed for correct code for cases such as
6400 : val = setjmp (buf) on machines where reference to val
6401 : requires loading up part of an address in a separate insn.
6402 :
6403 : Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
6404 : since it might be a promoted variable where the zero- or sign- extension
6405 : needs to be done. Handling this in the normal way is safe because no
6406 : computation is done before the call. The same is true for SSA names. */
6407 2345654 : if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
6408 2146297 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6409 2146297 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
6410 15656243 : && ! (((VAR_P (to)
6411 : || TREE_CODE (to) == PARM_DECL
6412 : || TREE_CODE (to) == RESULT_DECL)
6413 121137 : && REG_P (DECL_RTL (to)))
6414 2035228 : || TREE_CODE (to) == SSA_NAME))
6415 : {
6416 10390 : rtx value;
6417 :
6418 10390 : push_temp_slots ();
6419 10390 : value = expand_normal (from);
6420 :
6421 10390 : if (to_rtx == 0)
6422 10390 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6423 :
6424 : /* Handle calls that return values in multiple non-contiguous locations.
6425 : The Irix 6 ABI has examples of this. */
6426 10390 : if (GET_CODE (to_rtx) == PARALLEL)
6427 : {
6428 0 : if (GET_CODE (value) == PARALLEL)
6429 0 : emit_group_move (to_rtx, value);
6430 : else
6431 0 : emit_group_load (to_rtx, value, TREE_TYPE (from),
6432 0 : int_size_in_bytes (TREE_TYPE (from)));
6433 : }
6434 10390 : else if (GET_CODE (value) == PARALLEL)
6435 1956 : emit_group_store (to_rtx, value, TREE_TYPE (from),
6436 1956 : int_size_in_bytes (TREE_TYPE (from)));
6437 8434 : else if (GET_MODE (to_rtx) == BLKmode)
6438 : {
6439 : /* Handle calls that return BLKmode values in registers. */
6440 254 : if (REG_P (value))
6441 254 : copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
6442 : else
6443 0 : emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
6444 : }
6445 : else
6446 : {
6447 8180 : if (POINTER_TYPE_P (TREE_TYPE (to)))
6448 0 : value = convert_memory_address_addr_space
6449 0 : (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
6450 0 : TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
6451 :
6452 8180 : emit_move_insn (to_rtx, value);
6453 : }
6454 :
6455 10390 : preserve_temp_slots (to_rtx);
6456 10390 : pop_temp_slots ();
6457 10390 : return;
6458 : }
6459 :
6460 : /* Ordinary treatment. Expand TO to get a REG or MEM rtx. */
6461 13499556 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6462 :
6463 : /* Don't move directly into a return register. */
6464 13499556 : if (TREE_CODE (to) == RESULT_DECL
6465 29219 : && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
6466 : {
6467 0 : rtx temp;
6468 :
6469 0 : push_temp_slots ();
6470 :
6471 : /* If the source is itself a return value, it still is in a pseudo at
6472 : this point so we can move it back to the return register directly. */
6473 0 : if (REG_P (to_rtx)
6474 0 : && TYPE_MODE (TREE_TYPE (from)) == BLKmode
6475 0 : && TREE_CODE (from) != CALL_EXPR)
6476 0 : temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
6477 : else
6478 0 : temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
6479 :
6480 : /* Handle calls that return values in multiple non-contiguous locations.
6481 : The Irix 6 ABI has examples of this. */
6482 0 : if (GET_CODE (to_rtx) == PARALLEL)
6483 : {
6484 0 : if (GET_CODE (temp) == PARALLEL)
6485 0 : emit_group_move (to_rtx, temp);
6486 : else
6487 0 : emit_group_load (to_rtx, temp, TREE_TYPE (from),
6488 0 : int_size_in_bytes (TREE_TYPE (from)));
6489 : }
6490 0 : else if (temp)
6491 0 : emit_move_insn (to_rtx, temp);
6492 :
6493 0 : preserve_temp_slots (to_rtx);
6494 0 : pop_temp_slots ();
6495 0 : return;
6496 : }
6497 :
6498 : /* In case we are returning the contents of an object which overlaps
6499 : the place the value is being stored, use a safe function when copying
6500 : a value through a pointer into a structure value return block. */
6501 13499556 : if (TREE_CODE (to) == RESULT_DECL
6502 29219 : && TREE_CODE (from) == INDIRECT_REF
6503 0 : && ADDR_SPACE_GENERIC_P
6504 : (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
6505 0 : && refs_may_alias_p (to, from)
6506 0 : && cfun->returns_struct
6507 13499556 : && !cfun->returns_pcc_struct)
6508 : {
6509 0 : rtx from_rtx, size;
6510 :
6511 0 : push_temp_slots ();
6512 0 : size = expr_size (from);
6513 0 : from_rtx = expand_normal (from);
6514 :
6515 0 : emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
6516 :
6517 0 : preserve_temp_slots (to_rtx);
6518 0 : pop_temp_slots ();
6519 0 : return;
6520 : }
6521 :
6522 : /* Compute FROM and store the value in the rtx we got. */
6523 :
6524 13499556 : push_temp_slots ();
6525 13499556 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6526 13499554 : preserve_temp_slots (result);
6527 13499554 : pop_temp_slots ();
6528 13499554 : return;
6529 : }
6530 :
6531 : /* Emits nontemporal store insn that moves FROM to TO. Returns true if this
6532 : succeeded, false otherwise. */
6533 :
6534 : bool
6535 17 : emit_storent_insn (rtx to, rtx from)
6536 : {
6537 17 : class expand_operand ops[2];
6538 17 : machine_mode mode = GET_MODE (to);
6539 17 : enum insn_code code = optab_handler (storent_optab, mode);
6540 :
6541 17 : if (code == CODE_FOR_nothing)
6542 : return false;
6543 :
6544 17 : create_fixed_operand (&ops[0], to);
6545 17 : create_input_operand (&ops[1], from, mode);
6546 17 : return maybe_expand_insn (code, 2, ops);
6547 : }
6548 :
6549 : /* Helper function for store_expr storing of STRING_CST. */
6550 :
6551 : static rtx
6552 79395 : string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6553 : fixed_size_mode mode)
6554 : {
6555 79395 : tree str = (tree) data;
6556 :
6557 79395 : gcc_assert (offset >= 0);
6558 79395 : if (offset >= TREE_STRING_LENGTH (str))
6559 3328 : return const0_rtx;
6560 :
6561 76067 : if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6562 76067 : > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
6563 : {
6564 2460 : char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6565 2460 : size_t l = TREE_STRING_LENGTH (str) - offset;
6566 2460 : memcpy (p, TREE_STRING_POINTER (str) + offset, l);
6567 2460 : memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
6568 2460 : return c_readstr (p, mode, false);
6569 : }
6570 :
6571 73607 : return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
6572 : }
6573 :
6574 : /* Helper function for store_expr storing of RAW_DATA_CST. */
6575 :
6576 : static rtx
6577 36 : raw_data_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6578 : fixed_size_mode mode)
6579 : {
6580 36 : tree cst = (tree) data;
6581 :
6582 36 : gcc_assert (offset >= 0);
6583 36 : if (offset >= RAW_DATA_LENGTH (cst))
6584 0 : return const0_rtx;
6585 :
6586 36 : if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6587 36 : > (unsigned HOST_WIDE_INT) RAW_DATA_LENGTH (cst))
6588 : {
6589 0 : char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6590 0 : size_t l = RAW_DATA_LENGTH (cst) - offset;
6591 0 : memcpy (p, RAW_DATA_POINTER (cst) + offset, l);
6592 0 : memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
6593 0 : return c_readstr (p, mode, false);
6594 : }
6595 :
6596 36 : return c_readstr (RAW_DATA_POINTER (cst) + offset, mode, false);
6597 : }
6598 :
6599 : /* Generate code for computing expression EXP,
6600 : and storing the value into TARGET.
6601 :
6602 : If the mode is BLKmode then we may return TARGET itself.
6603 : It turns out that in BLKmode it doesn't cause a problem.
6604 : because C has no operators that could combine two different
6605 : assignments into the same BLKmode object with different values
6606 : with no sequence point. Will other languages need this to
6607 : be more thorough?
6608 :
6609 : If CALL_PARAM_P is nonzero, this is a store into a call param on the
6610 : stack, and block moves may need to be treated specially.
6611 :
6612 : If NONTEMPORAL is true, try using a nontemporal store instruction.
6613 :
6614 : If REVERSE is true, the store is to be done in reverse order. */
6615 :
6616 : rtx
6617 17483461 : store_expr (tree exp, rtx target, int call_param_p,
6618 : bool nontemporal, bool reverse)
6619 : {
6620 17483461 : rtx temp;
6621 17483461 : rtx alt_rtl = NULL_RTX;
6622 17483461 : location_t loc = curr_insn_location ();
6623 17483461 : bool shortened_string_cst = false;
6624 :
6625 17483461 : if (VOID_TYPE_P (TREE_TYPE (exp)))
6626 : {
6627 : /* C++ can generate ?: expressions with a throw expression in one
6628 : branch and an rvalue in the other. Here, we resolve attempts to
6629 : store the throw expression's nonexistent result. */
6630 0 : gcc_assert (!call_param_p);
6631 0 : expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
6632 0 : return NULL_RTX;
6633 : }
6634 17483461 : if (TREE_CODE (exp) == COMPOUND_EXPR)
6635 : {
6636 : /* Perform first part of compound expression, then assign from second
6637 : part. */
6638 0 : expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
6639 : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6640 0 : return store_expr (TREE_OPERAND (exp, 1), target,
6641 0 : call_param_p, nontemporal, reverse);
6642 : }
6643 17483461 : else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
6644 : {
6645 : /* For conditional expression, get safe form of the target. Then
6646 : test the condition, doing the appropriate assignment on either
6647 : side. This avoids the creation of unnecessary temporaries.
6648 : For non-BLKmode, it is more efficient not to do this. */
6649 :
6650 0 : rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
6651 :
6652 0 : do_pending_stack_adjust ();
6653 0 : NO_DEFER_POP;
6654 0 : jumpifnot (TREE_OPERAND (exp, 0), lab1,
6655 : profile_probability::uninitialized ());
6656 0 : store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
6657 : nontemporal, reverse);
6658 0 : emit_jump_insn (targetm.gen_jump (lab2));
6659 0 : emit_barrier ();
6660 0 : emit_label (lab1);
6661 0 : store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
6662 : nontemporal, reverse);
6663 0 : emit_label (lab2);
6664 0 : OK_DEFER_POP;
6665 :
6666 0 : return NULL_RTX;
6667 : }
6668 17483461 : else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
6669 : /* If this is a scalar in a register that is stored in a wider mode
6670 : than the declared mode, compute the result into its declared mode
6671 : and then convert to the wider mode. Our value is the computed
6672 : expression. */
6673 : {
6674 7 : rtx inner_target = 0;
6675 7 : scalar_int_mode outer_mode = subreg_unpromoted_mode (target);
6676 7 : scalar_int_mode inner_mode = subreg_promoted_mode (target);
6677 :
6678 : /* We can do the conversion inside EXP, which will often result
6679 : in some optimizations. Do the conversion in two steps: first
6680 : change the signedness, if needed, then the extend. But don't
6681 : do this if the type of EXP is a subtype of something else
6682 : since then the conversion might involve more than just
6683 : converting modes. */
6684 14 : if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
6685 0 : && TREE_TYPE (TREE_TYPE (exp)) == 0
6686 7 : && GET_MODE_PRECISION (outer_mode)
6687 0 : == TYPE_PRECISION (TREE_TYPE (exp)))
6688 : {
6689 0 : if (!SUBREG_CHECK_PROMOTED_SIGN (target,
6690 : TYPE_UNSIGNED (TREE_TYPE (exp))))
6691 : {
6692 : /* Some types, e.g. Fortran's logical*4, won't have a signed
6693 : version, so use the mode instead. */
6694 0 : tree ntype
6695 : = (signed_or_unsigned_type_for
6696 0 : (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
6697 0 : if (ntype == NULL)
6698 0 : ntype = lang_hooks.types.type_for_mode
6699 0 : (TYPE_MODE (TREE_TYPE (exp)),
6700 0 : SUBREG_PROMOTED_SIGN (target));
6701 :
6702 0 : exp = fold_convert_loc (loc, ntype, exp);
6703 : }
6704 :
6705 0 : exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
6706 0 : (inner_mode, SUBREG_PROMOTED_SIGN (target)),
6707 : exp);
6708 :
6709 0 : inner_target = SUBREG_REG (target);
6710 : }
6711 :
6712 7 : temp = expand_expr (exp, inner_target, VOIDmode,
6713 : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6714 :
6715 :
6716 : /* If TEMP is a VOIDmode constant, use convert_modes to make
6717 : sure that we properly convert it. */
6718 7 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
6719 : {
6720 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6721 0 : temp, SUBREG_PROMOTED_SIGN (target));
6722 0 : temp = convert_modes (inner_mode, outer_mode, temp,
6723 0 : SUBREG_PROMOTED_SIGN (target));
6724 0 : }
6725 7 : else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
6726 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6727 0 : temp, SUBREG_PROMOTED_SIGN (target));
6728 :
6729 21 : convert_move (SUBREG_REG (target), temp,
6730 7 : SUBREG_PROMOTED_SIGN (target));
6731 :
6732 7 : return NULL_RTX;
6733 : }
6734 17483454 : else if ((TREE_CODE (exp) == STRING_CST
6735 17476230 : || (TREE_CODE (exp) == MEM_REF
6736 1354693 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
6737 443077 : && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
6738 : == STRING_CST
6739 6401 : && integer_zerop (TREE_OPERAND (exp, 1))))
6740 13625 : && !nontemporal && !call_param_p
6741 17497079 : && MEM_P (target))
6742 : {
6743 : /* Optimize initialization of an array with a STRING_CST. */
6744 13607 : HOST_WIDE_INT exp_len, str_copy_len;
6745 13607 : rtx dest_mem;
6746 13607 : tree str = TREE_CODE (exp) == STRING_CST
6747 13607 : ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6748 :
6749 13607 : exp_len = int_expr_size (exp);
6750 13607 : if (exp_len <= 0)
6751 0 : goto normal_expr;
6752 :
6753 13607 : if (TREE_STRING_LENGTH (str) <= 0)
6754 0 : goto normal_expr;
6755 :
6756 27214 : if (can_store_by_pieces (exp_len, string_cst_read_str, (void *) str,
6757 13607 : MEM_ALIGN (target), false))
6758 : {
6759 13415 : store_by_pieces (target, exp_len, string_cst_read_str, (void *) str,
6760 13415 : MEM_ALIGN (target), false, RETURN_BEGIN);
6761 13415 : return NULL_RTX;
6762 : }
6763 :
6764 192 : str_copy_len = TREE_STRING_LENGTH (str);
6765 :
6766 : /* Trailing NUL bytes in EXP will be handled by the call to
6767 : clear_storage, which is more efficient than copying them from
6768 : the STRING_CST, so trim those from STR_COPY_LEN. */
6769 325 : while (str_copy_len)
6770 : {
6771 272 : if (TREE_STRING_POINTER (str)[str_copy_len - 1])
6772 : break;
6773 133 : str_copy_len--;
6774 : }
6775 :
6776 192 : if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
6777 : {
6778 192 : str_copy_len += STORE_MAX_PIECES - 1;
6779 192 : str_copy_len &= ~(STORE_MAX_PIECES - 1);
6780 : }
6781 192 : if (str_copy_len >= exp_len)
6782 131 : goto normal_expr;
6783 :
6784 122 : if (!can_store_by_pieces (str_copy_len, string_cst_read_str,
6785 61 : (void *) str, MEM_ALIGN (target), false))
6786 2 : goto normal_expr;
6787 :
6788 59 : dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
6789 59 : (void *) str, MEM_ALIGN (target), false,
6790 : RETURN_END);
6791 59 : clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
6792 59 : exp_len - str_copy_len),
6793 : GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
6794 59 : return NULL_RTX;
6795 : }
6796 : else
6797 : {
6798 17469980 : rtx tmp_target;
6799 :
6800 17469980 : normal_expr:
6801 : /* If we want to use a nontemporal or a reverse order store, force the
6802 : value into a register first. */
6803 17469980 : tmp_target = nontemporal || reverse ? NULL_RTX : target;
6804 17469980 : tree rexp = exp;
6805 17469980 : if (TREE_CODE (exp) == STRING_CST
6806 20 : && tmp_target == target
6807 20 : && GET_MODE (target) == BLKmode
6808 17470000 : && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
6809 : {
6810 20 : rtx size = expr_size (exp);
6811 20 : if (CONST_INT_P (size)
6812 20 : && size != const0_rtx
6813 40 : && (UINTVAL (size)
6814 20 : > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
6815 : {
6816 : /* If the STRING_CST has much larger array type than
6817 : TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
6818 : it into the rodata section as the code later on will use
6819 : memset zero for the remainder anyway. See PR95052. */
6820 2 : tmp_target = NULL_RTX;
6821 2 : rexp = copy_node (exp);
6822 2 : tree index
6823 2 : = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
6824 2 : TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
6825 : index);
6826 2 : shortened_string_cst = true;
6827 : }
6828 : }
6829 34939960 : temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
6830 : (call_param_p
6831 : ? EXPAND_STACK_PARM : EXPAND_NORMAL),
6832 : &alt_rtl, false);
6833 17469978 : if (shortened_string_cst)
6834 : {
6835 2 : gcc_assert (MEM_P (temp));
6836 2 : temp = change_address (temp, BLKmode, NULL_RTX);
6837 : }
6838 : }
6839 :
6840 : /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
6841 : the same as that of TARGET, adjust the constant. This is needed, for
6842 : example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
6843 : only a word-sized value. */
6844 3609572 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
6845 2603138 : && TREE_CODE (exp) != ERROR_MARK
6846 20073116 : && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
6847 : {
6848 0 : gcc_assert (!shortened_string_cst);
6849 0 : if (GET_MODE_CLASS (GET_MODE (target))
6850 0 : != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
6851 0 : && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
6852 : GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
6853 : {
6854 0 : rtx t = simplify_gen_subreg (GET_MODE (target), temp,
6855 0 : TYPE_MODE (TREE_TYPE (exp)), 0);
6856 0 : if (t)
6857 0 : temp = t;
6858 : }
6859 0 : if (GET_MODE (temp) == VOIDmode)
6860 0 : temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
6861 0 : temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6862 : }
6863 :
6864 : /* If value was not generated in the target, store it there.
6865 : Convert the value to TARGET's type first if necessary and emit the
6866 : pending incrementations that have been queued when expanding EXP.
6867 : Note that we cannot emit the whole queue blindly because this will
6868 : effectively disable the POST_INC optimization later.
6869 :
6870 : If TEMP and TARGET compare equal according to rtx_equal_p, but
6871 : one or both of them are volatile memory refs, we have to distinguish
6872 : two cases:
6873 : - expand_expr has used TARGET. In this case, we must not generate
6874 : another copy. This can be detected by TARGET being equal according
6875 : to == .
6876 : - expand_expr has not used TARGET - that means that the source just
6877 : happens to have the same RTX form. Since temp will have been created
6878 : by expand_expr, it will compare unequal according to == .
6879 : We must generate a copy in this case, to reach the correct number
6880 : of volatile memory references. */
6881 :
6882 17469978 : if ((! rtx_equal_p (temp, target)
6883 3109124 : || (temp != target && (side_effects_p (temp)
6884 46905 : || side_effects_p (target)
6885 46905 : || (MEM_P (temp)
6886 46426 : && !mems_same_for_tbaa_p (temp, target)))))
6887 14360858 : && TREE_CODE (exp) != ERROR_MARK
6888 : /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
6889 : but TARGET is not valid memory reference, TEMP will differ
6890 : from TARGET although it is really the same location. */
6891 14360858 : && !(alt_rtl
6892 1981347 : && rtx_equal_p (alt_rtl, target)
6893 1 : && !side_effects_p (alt_rtl)
6894 0 : && !side_effects_p (target))
6895 : /* If there's nothing to copy, don't bother. Don't call
6896 : expr_size unless necessary, because some front-ends (C++)
6897 : expr_size-hook must not be given objects that are not
6898 : supposed to be bit-copied or bit-initialized. */
6899 31830836 : && expr_size (exp) != const0_rtx)
6900 : {
6901 14360858 : if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
6902 : {
6903 1633 : gcc_assert (!shortened_string_cst);
6904 1633 : if (GET_MODE (target) == BLKmode)
6905 : {
6906 : /* Handle calls that return BLKmode values in registers. */
6907 2 : if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
6908 2 : copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
6909 : else
6910 0 : store_bit_field (target,
6911 0 : rtx_to_poly_int64 (expr_size (exp))
6912 0 : * BITS_PER_UNIT,
6913 : 0, 0, 0, GET_MODE (temp), temp, reverse,
6914 : false);
6915 : }
6916 : else
6917 1631 : convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6918 : }
6919 :
6920 14359225 : else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
6921 : {
6922 : /* Handle copying a string constant into an array. The string
6923 : constant may be shorter than the array. So copy just the string's
6924 : actual length, and clear the rest. First get the size of the data
6925 : type of the string, which is actually the size of the target. */
6926 20 : rtx size = expr_size (exp);
6927 :
6928 20 : if (CONST_INT_P (size)
6929 20 : && INTVAL (size) < TREE_STRING_LENGTH (exp))
6930 0 : emit_block_move (target, temp, size,
6931 : (call_param_p
6932 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6933 : else
6934 : {
6935 20 : machine_mode pointer_mode
6936 20 : = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
6937 20 : machine_mode address_mode = get_address_mode (target);
6938 :
6939 : /* Compute the size of the data to copy from the string. */
6940 20 : tree copy_size
6941 20 : = size_binop_loc (loc, MIN_EXPR,
6942 : make_tree (sizetype, size),
6943 20 : size_int (TREE_STRING_LENGTH (exp)));
6944 20 : rtx copy_size_rtx
6945 20 : = expand_expr (copy_size, NULL_RTX, VOIDmode,
6946 : (call_param_p
6947 : ? EXPAND_STACK_PARM : EXPAND_NORMAL));
6948 20 : rtx_code_label *label = 0;
6949 :
6950 : /* Copy that much. */
6951 60 : copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
6952 20 : TYPE_UNSIGNED (sizetype));
6953 40 : emit_block_move (target, temp, copy_size_rtx,
6954 : (call_param_p
6955 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6956 :
6957 : /* Figure out how much is left in TARGET that we have to clear.
6958 : Do all calculations in pointer_mode. */
6959 20 : poly_int64 const_copy_size;
6960 20 : if (poly_int_rtx_p (copy_size_rtx, &const_copy_size))
6961 : {
6962 20 : size = plus_constant (address_mode, size, -const_copy_size);
6963 20 : target = adjust_address (target, BLKmode, const_copy_size);
6964 : }
6965 : else
6966 : {
6967 0 : size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
6968 : copy_size_rtx, NULL_RTX, 0,
6969 : OPTAB_LIB_WIDEN);
6970 :
6971 0 : if (GET_MODE (copy_size_rtx) != address_mode)
6972 0 : copy_size_rtx = convert_to_mode (address_mode,
6973 : copy_size_rtx,
6974 0 : TYPE_UNSIGNED (sizetype));
6975 :
6976 0 : target = offset_address (target, copy_size_rtx,
6977 : highest_pow2_factor (copy_size));
6978 0 : label = gen_label_rtx ();
6979 0 : emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
6980 0 : GET_MODE (size), 0, label);
6981 : }
6982 :
6983 20 : if (size != const0_rtx)
6984 2 : clear_storage (target, size, BLOCK_OP_NORMAL);
6985 :
6986 20 : if (label)
6987 0 : emit_label (label);
6988 : }
6989 : }
6990 14359205 : else if (shortened_string_cst)
6991 0 : gcc_unreachable ();
6992 : /* Handle calls that return values in multiple non-contiguous locations.
6993 : The Irix 6 ABI has examples of this. */
6994 14359205 : else if (GET_CODE (target) == PARALLEL)
6995 : {
6996 0 : if (GET_CODE (temp) == PARALLEL)
6997 0 : emit_group_move (target, temp);
6998 : else
6999 0 : emit_group_load (target, temp, TREE_TYPE (exp),
7000 0 : int_size_in_bytes (TREE_TYPE (exp)));
7001 : }
7002 14359205 : else if (GET_CODE (temp) == PARALLEL)
7003 0 : emit_group_store (target, temp, TREE_TYPE (exp),
7004 0 : int_size_in_bytes (TREE_TYPE (exp)));
7005 14359205 : else if (GET_MODE (temp) == BLKmode)
7006 601838 : emit_block_move (target, temp, expr_size (exp),
7007 : (call_param_p
7008 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
7009 : /* If we emit a nontemporal store, there is nothing else to do. */
7010 14058286 : else if (nontemporal && emit_storent_insn (target, temp))
7011 : ;
7012 : else
7013 : {
7014 14058269 : if (reverse)
7015 722 : temp = flip_storage_order (GET_MODE (target), temp);
7016 14058269 : temp = force_operand (temp, target);
7017 14058269 : if (temp != target)
7018 14056762 : emit_move_insn (target, temp);
7019 : }
7020 : }
7021 : else
7022 3109120 : gcc_assert (!shortened_string_cst);
7023 :
7024 : return NULL_RTX;
7025 : }
7026 :
7027 : /* Return true if field F of structure TYPE is a flexible array. */
7028 :
7029 : static bool
7030 3882950 : flexible_array_member_p (const_tree f, const_tree type)
7031 : {
7032 3882950 : const_tree tf;
7033 :
7034 3882950 : tf = TREE_TYPE (f);
7035 3882950 : return (DECL_CHAIN (f) == NULL
7036 1080449 : && TREE_CODE (tf) == ARRAY_TYPE
7037 2525 : && TYPE_DOMAIN (tf)
7038 2525 : && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
7039 2525 : && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
7040 2525 : && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
7041 3882989 : && int_size_in_bytes (type) >= 0);
7042 : }
7043 :
7044 : /* If FOR_CTOR_P, return the number of top-level elements that a constructor
7045 : must have in order for it to completely initialize a value of type TYPE.
7046 : Return -1 if the number isn't known.
7047 :
7048 : If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
7049 :
7050 : static HOST_WIDE_INT
7051 3707150 : count_type_elements (const_tree type, bool for_ctor_p)
7052 : {
7053 3707150 : switch (TREE_CODE (type))
7054 : {
7055 154924 : case ARRAY_TYPE:
7056 154924 : {
7057 154924 : tree nelts_minus_one;
7058 :
7059 154924 : nelts_minus_one = array_type_nelts_minus_one (type);
7060 154924 : if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one))
7061 : {
7062 154913 : unsigned HOST_WIDE_INT n;
7063 :
7064 154913 : n = tree_to_uhwi (nelts_minus_one) + 1;
7065 154913 : if (n == 0 || for_ctor_p)
7066 153573 : return n;
7067 : else
7068 1340 : return n * count_type_elements (TREE_TYPE (type), false);
7069 : }
7070 11 : return for_ctor_p ? -1 : 1;
7071 : }
7072 :
7073 1802597 : case RECORD_TYPE:
7074 1802597 : {
7075 1802597 : unsigned HOST_WIDE_INT n;
7076 1802597 : tree f;
7077 :
7078 1802597 : n = 0;
7079 16944307 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7080 15141710 : if (TREE_CODE (f) == FIELD_DECL)
7081 : {
7082 4346648 : if (!for_ctor_p)
7083 463698 : n += count_type_elements (TREE_TYPE (f), false);
7084 3882950 : else if (!flexible_array_member_p (f, type))
7085 : /* Don't count flexible arrays, which are not supposed
7086 : to be initialized. */
7087 3882911 : n += 1;
7088 : }
7089 :
7090 1802597 : return n;
7091 : }
7092 :
7093 3334 : case UNION_TYPE:
7094 3334 : case QUAL_UNION_TYPE:
7095 3334 : {
7096 3334 : tree f;
7097 3334 : HOST_WIDE_INT n, m;
7098 :
7099 3334 : gcc_assert (!for_ctor_p);
7100 : /* Estimate the number of scalars in each field and pick the
7101 : maximum. Other estimates would do instead; the idea is simply
7102 : to make sure that the estimate is not sensitive to the ordering
7103 : of the fields. */
7104 3334 : n = 1;
7105 75775 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7106 72441 : if (TREE_CODE (f) == FIELD_DECL)
7107 : {
7108 67980 : m = count_type_elements (TREE_TYPE (f), false);
7109 : /* If the field doesn't span the whole union, add an extra
7110 : scalar for the rest. */
7111 67980 : if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
7112 67980 : TYPE_SIZE (type)) != 1)
7113 48450 : m++;
7114 67980 : if (n < m)
7115 72441 : n = m;
7116 : }
7117 : return n;
7118 : }
7119 :
7120 : case COMPLEX_TYPE:
7121 : return 2;
7122 :
7123 421 : case VECTOR_TYPE:
7124 421 : {
7125 421 : unsigned HOST_WIDE_INT nelts;
7126 421 : if (TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
7127 421 : return nelts;
7128 : else
7129 : return -1;
7130 : }
7131 :
7132 : case INTEGER_TYPE:
7133 : case REAL_TYPE:
7134 : case FIXED_POINT_TYPE:
7135 : case ENUMERAL_TYPE:
7136 : case BOOLEAN_TYPE:
7137 : case POINTER_TYPE:
7138 : case OFFSET_TYPE:
7139 : case REFERENCE_TYPE:
7140 : case NULLPTR_TYPE:
7141 : case OPAQUE_TYPE:
7142 : case BITINT_TYPE:
7143 : return 1;
7144 :
7145 0 : case ERROR_MARK:
7146 0 : return 0;
7147 :
7148 0 : case VOID_TYPE:
7149 0 : case METHOD_TYPE:
7150 0 : case FUNCTION_TYPE:
7151 0 : case LANG_TYPE:
7152 0 : default:
7153 0 : gcc_unreachable ();
7154 : }
7155 : }
7156 :
7157 : /* Helper for categorize_ctor_elements. Identical interface. */
7158 :
7159 : static bool
7160 1543909 : categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7161 : HOST_WIDE_INT *p_unique_nz_elts,
7162 : HOST_WIDE_INT *p_init_elts,
7163 : ctor_completeness *p_complete)
7164 : {
7165 1543909 : unsigned HOST_WIDE_INT idx;
7166 1543909 : HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
7167 1543909 : tree value, purpose, elt_type;
7168 :
7169 : /* Whether CTOR is a valid constant initializer, in accordance with what
7170 : initializer_constant_valid_p does. If inferred from the constructor
7171 : elements, true until proven otherwise. */
7172 1543909 : bool const_from_elts_p = constructor_static_from_elts_p (ctor);
7173 1543909 : bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
7174 :
7175 1543909 : nz_elts = 0;
7176 1543909 : unique_nz_elts = 0;
7177 1543909 : init_elts = 0;
7178 1543909 : num_fields = 0;
7179 1543909 : elt_type = NULL_TREE;
7180 :
7181 5854991 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
7182 : {
7183 4311082 : HOST_WIDE_INT mult = 1;
7184 :
7185 4311082 : if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
7186 : {
7187 692 : tree lo_index = TREE_OPERAND (purpose, 0);
7188 692 : tree hi_index = TREE_OPERAND (purpose, 1);
7189 :
7190 692 : if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
7191 692 : mult = (tree_to_uhwi (hi_index)
7192 692 : - tree_to_uhwi (lo_index) + 1);
7193 : }
7194 4311082 : num_fields += mult;
7195 4311082 : elt_type = TREE_TYPE (value);
7196 :
7197 4311082 : switch (TREE_CODE (value))
7198 : {
7199 543884 : case CONSTRUCTOR:
7200 543884 : {
7201 543884 : HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
7202 :
7203 543884 : bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
7204 : &ic, p_complete);
7205 :
7206 543884 : nz_elts += mult * nz;
7207 543884 : unique_nz_elts += unz;
7208 543884 : init_elts += mult * ic;
7209 :
7210 543884 : if (const_from_elts_p && const_p)
7211 330726 : const_p = const_elt_p;
7212 : }
7213 543884 : break;
7214 :
7215 2298214 : case INTEGER_CST:
7216 2298214 : case REAL_CST:
7217 2298214 : case FIXED_CST:
7218 2298214 : if (!initializer_zerop (value))
7219 : {
7220 1685110 : nz_elts += mult;
7221 1685110 : unique_nz_elts++;
7222 : }
7223 2298214 : init_elts += mult;
7224 2298214 : break;
7225 :
7226 6298 : case STRING_CST:
7227 6298 : nz_elts += mult * TREE_STRING_LENGTH (value);
7228 6298 : unique_nz_elts += TREE_STRING_LENGTH (value);
7229 6298 : init_elts += mult * TREE_STRING_LENGTH (value);
7230 6298 : break;
7231 :
7232 166 : case RAW_DATA_CST:
7233 166 : nz_elts += mult * RAW_DATA_LENGTH (value);
7234 166 : unique_nz_elts += RAW_DATA_LENGTH (value);
7235 166 : init_elts += mult * RAW_DATA_LENGTH (value);
7236 166 : num_fields += mult * (RAW_DATA_LENGTH (value) - 1);
7237 166 : break;
7238 :
7239 3234 : case COMPLEX_CST:
7240 3234 : if (!initializer_zerop (TREE_REALPART (value)))
7241 : {
7242 2630 : nz_elts += mult;
7243 2630 : unique_nz_elts++;
7244 : }
7245 3234 : if (!initializer_zerop (TREE_IMAGPART (value)))
7246 : {
7247 2272 : nz_elts += mult;
7248 2272 : unique_nz_elts++;
7249 : }
7250 3234 : init_elts += 2 * mult;
7251 3234 : break;
7252 :
7253 6372 : case VECTOR_CST:
7254 6372 : {
7255 6372 : unsigned int nunits
7256 : = constant_lower_bound
7257 6372 : (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value)));
7258 39739 : for (unsigned int i = 0; i < nunits; ++i)
7259 : {
7260 33367 : tree v = VECTOR_CST_ELT (value, i);
7261 33367 : if (!initializer_zerop (v))
7262 : {
7263 18925 : nz_elts += mult;
7264 18925 : unique_nz_elts++;
7265 : }
7266 33367 : init_elts += mult;
7267 : }
7268 : }
7269 : break;
7270 :
7271 1452914 : default:
7272 1452914 : {
7273 1452914 : HOST_WIDE_INT tc = count_type_elements (elt_type, false);
7274 1452914 : nz_elts += mult * tc;
7275 1452914 : unique_nz_elts += tc;
7276 1452914 : init_elts += mult * tc;
7277 :
7278 1452914 : if (const_from_elts_p && const_p)
7279 599569 : const_p
7280 599569 : = initializer_constant_valid_p (value,
7281 : elt_type,
7282 599569 : TYPE_REVERSE_STORAGE_ORDER
7283 : (TREE_TYPE (ctor)))
7284 : != NULL_TREE;
7285 : }
7286 : break;
7287 : }
7288 : }
7289 :
7290 1543909 : if (!p_complete->sparse && !complete_ctor_at_level_p (TREE_TYPE (ctor),
7291 : num_fields, elt_type))
7292 183770 : p_complete->sparse = true;
7293 1360139 : else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
7294 1360139 : || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
7295 : {
7296 12104 : if (!p_complete->sparse
7297 7871 : && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7298 22193 : && (num_fields
7299 5046 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7300 5043 : TYPE_SIZE (elt_type)) != 1
7301 3 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7302 3367 : p_complete->sparse = true;
7303 4504 : else if (!p_complete->sparse && !p_complete->padded_union
7304 17737 : && (num_fields
7305 4500 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7306 4500 : TYPE_SIZE (elt_type)) != 1
7307 0 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7308 380 : p_complete->padded_union = true;
7309 : }
7310 1348035 : else if (!p_complete->sparse
7311 1232388 : && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7312 1212797 : || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
7313 1367655 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7314 2764 : p_complete->sparse = true;
7315 1229624 : else if (!p_complete->sparse && !p_complete->padded_non_union
7316 2527198 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7317 15317 : p_complete->padded_non_union = true;
7318 :
7319 1543909 : *p_nz_elts += nz_elts;
7320 1543909 : *p_unique_nz_elts += unique_nz_elts;
7321 1543909 : *p_init_elts += init_elts;
7322 :
7323 1543909 : return const_p;
7324 : }
7325 :
7326 : /* Examine CTOR to discover:
7327 : * how many scalar fields are set to nonzero values,
7328 : and place it in *P_NZ_ELTS;
7329 : * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
7330 : high - low + 1 (this can be useful for callers to determine ctors
7331 : that could be cheaply initialized with - perhaps nested - loops
7332 : compared to copied from huge read-only data),
7333 : and place it in *P_UNIQUE_NZ_ELTS;
7334 : * how many scalar fields in total are in CTOR,
7335 : and place it in *P_ELT_COUNT.
7336 : * whether the constructor is complete -- in the sense that every
7337 : meaningful byte is explicitly given a value --
7338 : and place it in *P_COMPLETE:
7339 :
7340 : Return whether or not CTOR is a valid static constant initializer, the same
7341 : as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
7342 :
7343 : bool
7344 1000025 : categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7345 : HOST_WIDE_INT *p_unique_nz_elts,
7346 : HOST_WIDE_INT *p_init_elts,
7347 : ctor_completeness *p_complete)
7348 : {
7349 1000025 : *p_nz_elts = 0;
7350 1000025 : *p_unique_nz_elts = 0;
7351 1000025 : *p_init_elts = 0;
7352 1000025 : *p_complete = {};
7353 :
7354 1000025 : return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
7355 1000025 : p_init_elts, p_complete);
7356 : }
7357 :
7358 : /* Return true if constructor CTOR is simple enough to be materialized
7359 : in an integer mode register. Limit the size to WORDS words, which
7360 : is 1 by default. */
7361 :
7362 : bool
7363 23688 : immediate_const_ctor_p (const_tree ctor, unsigned int words)
7364 : {
7365 : /* Allow function to be called with a VAR_DECL's DECL_INITIAL. */
7366 23688 : if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
7367 : return false;
7368 :
7369 2817 : return TREE_CONSTANT (ctor)
7370 2817 : && !TREE_ADDRESSABLE (ctor)
7371 2711 : && CONSTRUCTOR_NELTS (ctor)
7372 2688 : && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
7373 633 : && int_expr_size (ctor) <= words * UNITS_PER_WORD
7374 3006 : && initializer_constant_valid_for_bitfield_p (ctor);
7375 : }
7376 :
7377 : /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
7378 : of which had type LAST_TYPE. Each element was itself a complete
7379 : initializer, in the sense that every meaningful byte was explicitly
7380 : given a value. Return true if the same is true for the constructor
7381 : as a whole. */
7382 :
7383 : bool
7384 1730309 : complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
7385 : const_tree last_type)
7386 : {
7387 1730309 : if (TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE)
7388 : {
7389 9091 : if (num_elts == 0)
7390 : {
7391 24 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7392 : return false;
7393 :
7394 : /* If the CONSTRUCTOR doesn't have any elts, it is
7395 : incomplete if the union has at least one field. */
7396 327 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
7397 324 : if (TREE_CODE (f) == FIELD_DECL)
7398 : return false;
7399 :
7400 : return true;
7401 : }
7402 :
7403 9067 : gcc_assert (num_elts == 1 && last_type);
7404 :
7405 9067 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7406 : /* ??? We could look at each element of the union, and find the
7407 : largest element. Which would avoid comparing the size of the
7408 : initialized element against any tail padding in the union.
7409 : Doesn't seem worth the effort... */
7410 102 : return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
7411 :
7412 : return true;
7413 : }
7414 :
7415 1721218 : return count_type_elements (type, true) == num_elts;
7416 : }
7417 :
7418 : /* Return true if EXP contains mostly (3/4) zeros. */
7419 :
7420 : static bool
7421 360079 : mostly_zeros_p (const_tree exp)
7422 : {
7423 360079 : if (TREE_CODE (exp) == CONSTRUCTOR)
7424 : {
7425 197 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7426 197 : ctor_completeness complete_p;
7427 :
7428 197 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7429 : &complete_p);
7430 197 : return complete_p.sparse || nz_elts < init_elts / 4;
7431 : }
7432 :
7433 359882 : return initializer_zerop (exp);
7434 : }
7435 :
7436 : /* Return true if EXP contains all zeros. */
7437 :
7438 : static bool
7439 1085 : all_zeros_p (const_tree exp)
7440 : {
7441 1085 : if (TREE_CODE (exp) == CONSTRUCTOR)
7442 : {
7443 1085 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7444 1085 : ctor_completeness complete_p;
7445 :
7446 1085 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7447 : &complete_p);
7448 1085 : return nz_elts == 0;
7449 : }
7450 :
7451 0 : return initializer_zerop (exp);
7452 : }
7453 :
7454 : /* Helper function for store_constructor.
7455 : TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
7456 : CLEARED is as for store_constructor.
7457 : ALIAS_SET is the alias set to use for any stores.
7458 : If REVERSE is true, the store is to be done in reverse order.
7459 :
7460 : This provides a recursive shortcut back to store_constructor when it isn't
7461 : necessary to go through store_field. This is so that we can pass through
7462 : the cleared field to let store_constructor know that we may not have to
7463 : clear a substructure if the outer structure has already been cleared. */
7464 :
7465 : static void
7466 36600 : store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
7467 : poly_uint64 bitregion_start,
7468 : poly_uint64 bitregion_end,
7469 : machine_mode mode,
7470 : tree exp, int cleared,
7471 : alias_set_type alias_set, bool reverse)
7472 : {
7473 36600 : poly_int64 bytepos;
7474 36600 : poly_uint64 bytesize;
7475 36600 : if (TREE_CODE (exp) == CONSTRUCTOR
7476 : /* We can only call store_constructor recursively if the size and
7477 : bit position are on a byte boundary. */
7478 82 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
7479 82 : && maybe_ne (bitsize, 0U)
7480 36600 : && multiple_p (bitsize, BITS_PER_UNIT, &bytesize)
7481 : /* If we have a nonzero bitpos for a register target, then we just
7482 : let store_field do the bitfield handling. This is unlikely to
7483 : generate unnecessary clear instructions anyways. */
7484 36682 : && (known_eq (bitpos, 0) || MEM_P (target)))
7485 : {
7486 82 : if (MEM_P (target))
7487 : {
7488 40 : machine_mode target_mode = GET_MODE (target);
7489 40 : if (target_mode != BLKmode
7490 40 : && !multiple_p (bitpos, GET_MODE_ALIGNMENT (target_mode)))
7491 : target_mode = BLKmode;
7492 40 : target = adjust_address (target, target_mode, bytepos);
7493 : }
7494 :
7495 :
7496 : /* Update the alias set, if required. */
7497 40 : if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
7498 122 : && MEM_ALIAS_SET (target) != 0)
7499 : {
7500 36 : target = copy_rtx (target);
7501 36 : set_mem_alias_set (target, alias_set);
7502 : }
7503 :
7504 82 : store_constructor (exp, target, cleared, bytesize, reverse);
7505 : }
7506 : else
7507 36518 : store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
7508 : exp, alias_set, false, reverse);
7509 36600 : }
7510 :
7511 :
7512 : /* Returns the number of FIELD_DECLs in TYPE. */
7513 :
7514 : static int
7515 68146 : fields_length (const_tree type)
7516 : {
7517 68146 : tree t = TYPE_FIELDS (type);
7518 68146 : int count = 0;
7519 :
7520 865487 : for (; t; t = DECL_CHAIN (t))
7521 797341 : if (TREE_CODE (t) == FIELD_DECL)
7522 297715 : ++count;
7523 :
7524 68146 : return count;
7525 : }
7526 :
7527 : /* Store the value of constructor EXP into the rtx TARGET.
7528 : TARGET is either a REG or a MEM; we know it cannot conflict, since
7529 : safe_from_p has been called.
7530 : CLEARED is true if TARGET is known to have been zero'd.
7531 : If the constructor EXP has a vector type then elements of TARGET for which
7532 : there is no corresponding element in EXP are zero'd. For a variable-length
7533 : vector type, only elements up to the minimum number of subparts of the type
7534 : are explicitly zero'd; any elements beyond that are implicitly zero.
7535 : SIZE is the number of bytes of TARGET we are allowed to modify: this
7536 : may not be the same as the size of EXP if we are assigning to a field
7537 : which has been packed to exclude padding bits.
7538 : If REVERSE is true, the store is to be done in reverse order. */
7539 :
7540 : void
7541 246140 : store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
7542 : bool reverse)
7543 : {
7544 246140 : tree type = TREE_TYPE (exp);
7545 246140 : HOST_WIDE_INT exp_size = int_size_in_bytes (type);
7546 246140 : poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
7547 :
7548 246140 : switch (TREE_CODE (type))
7549 : {
7550 68605 : case RECORD_TYPE:
7551 68605 : case UNION_TYPE:
7552 68605 : case QUAL_UNION_TYPE:
7553 68605 : {
7554 68605 : unsigned HOST_WIDE_INT idx;
7555 68605 : tree field, value;
7556 :
7557 : /* The storage order is specified for every aggregate type. */
7558 68605 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7559 :
7560 : /* If size is zero or the target is already cleared, do nothing. */
7561 68605 : if (known_eq (size, 0) || cleared)
7562 : cleared = 1;
7563 : /* We either clear the aggregate or indicate the value is dead. */
7564 68605 : else if ((TREE_CODE (type) == UNION_TYPE
7565 68605 : || TREE_CODE (type) == QUAL_UNION_TYPE)
7566 68909 : && ! CONSTRUCTOR_ELTS (exp))
7567 : /* If the constructor is empty, clear the union. */
7568 : {
7569 255 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
7570 255 : cleared = 1;
7571 : }
7572 :
7573 : /* If we are building a static constructor into a register,
7574 : set the initial value as zero so we can fold the value into
7575 : a constant. But if more than one register is involved,
7576 : this probably loses. */
7577 4210 : else if (REG_P (target) && TREE_STATIC (exp)
7578 68880 : && known_le (GET_MODE_SIZE (GET_MODE (target)),
7579 : REGMODE_NATURAL_SIZE (GET_MODE (target))))
7580 : {
7581 204 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7582 204 : cleared = 1;
7583 : }
7584 :
7585 : /* If the constructor has fewer fields than the structure or
7586 : if we are initializing the structure to mostly zeros, clear
7587 : the whole structure first. Don't do this if TARGET is a
7588 : register whose mode size isn't equal to SIZE since
7589 : clear_storage can't handle this case. */
7590 68146 : else if (known_size_p (size)
7591 68315 : && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
7592 156 : || mostly_zeros_p (exp))
7593 136140 : && (!REG_P (target)
7594 8002 : || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
7595 : {
7596 78707 : clear_storage (target, gen_int_mode (size, Pmode),
7597 : BLOCK_OP_NORMAL);
7598 67994 : cleared = 1;
7599 : }
7600 :
7601 68605 : if (REG_P (target) && !cleared)
7602 5 : emit_clobber (target);
7603 :
7604 : /* Store each element of the constructor into the
7605 : corresponding field of TARGET. */
7606 68951 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
7607 : {
7608 346 : machine_mode mode;
7609 346 : HOST_WIDE_INT bitsize;
7610 346 : HOST_WIDE_INT bitpos = 0;
7611 346 : tree offset;
7612 346 : rtx to_rtx = target;
7613 :
7614 : /* Just ignore missing fields. We cleared the whole
7615 : structure, above, if any fields are missing. */
7616 346 : if (field == 0)
7617 346 : continue;
7618 :
7619 346 : if (cleared && initializer_zerop (value))
7620 17 : continue;
7621 :
7622 : /* Variable sized arrays are ignored. */
7623 329 : tree decl_size = DECL_SIZE (field);
7624 329 : if (!decl_size)
7625 4 : continue;
7626 :
7627 325 : if (tree_fits_uhwi_p (decl_size))
7628 325 : bitsize = tree_to_uhwi (decl_size);
7629 : else
7630 0 : gcc_unreachable ();
7631 :
7632 325 : mode = DECL_MODE (field);
7633 325 : if (DECL_BIT_FIELD (field))
7634 24 : mode = VOIDmode;
7635 :
7636 325 : offset = DECL_FIELD_OFFSET (field);
7637 325 : if (tree_fits_shwi_p (offset)
7638 325 : && tree_fits_shwi_p (bit_position (field)))
7639 : {
7640 325 : bitpos = int_bit_position (field);
7641 325 : offset = NULL_TREE;
7642 : }
7643 : else
7644 0 : gcc_unreachable ();
7645 :
7646 : /* If this initializes a field that is smaller than a
7647 : word, at the start of a word, try to widen it to a full
7648 : word. This special case allows us to output C++ member
7649 : function initializations in a form that the optimizers
7650 : can understand. */
7651 325 : if (WORD_REGISTER_OPERATIONS
7652 : && REG_P (target)
7653 : && bitsize < BITS_PER_WORD
7654 : && bitpos % BITS_PER_WORD == 0
7655 : && GET_MODE_CLASS (mode) == MODE_INT
7656 : && TREE_CODE (value) == INTEGER_CST
7657 : && exp_size >= 0
7658 : && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
7659 : {
7660 : type = TREE_TYPE (value);
7661 :
7662 : if (TYPE_PRECISION (type) < BITS_PER_WORD)
7663 : {
7664 : type = lang_hooks.types.type_for_mode
7665 : (word_mode, TYPE_UNSIGNED (type));
7666 : value = fold_convert (type, value);
7667 : /* Make sure the bits beyond the original bitsize are zero
7668 : so that we can correctly avoid extra zeroing stores in
7669 : later constructor elements. */
7670 : tree bitsize_mask
7671 : = wide_int_to_tree (type, wi::mask (bitsize, false,
7672 : BITS_PER_WORD));
7673 : value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
7674 : }
7675 :
7676 : if (BYTES_BIG_ENDIAN)
7677 : value
7678 : = fold_build2 (LSHIFT_EXPR, type, value,
7679 : build_int_cst (type,
7680 : BITS_PER_WORD - bitsize));
7681 : bitsize = BITS_PER_WORD;
7682 : mode = word_mode;
7683 : }
7684 :
7685 207 : if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
7686 532 : && DECL_NONADDRESSABLE_P (field))
7687 : {
7688 0 : to_rtx = copy_rtx (to_rtx);
7689 0 : MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
7690 : }
7691 :
7692 325 : store_constructor_field (to_rtx, bitsize, bitpos,
7693 325 : 0, bitregion_end, mode,
7694 : value, cleared,
7695 325 : get_alias_set (TREE_TYPE (field)),
7696 : reverse);
7697 : }
7698 : break;
7699 : }
7700 39523 : case ARRAY_TYPE:
7701 39523 : {
7702 39523 : tree value, index;
7703 39523 : unsigned HOST_WIDE_INT i, j = 0;
7704 39523 : bool need_to_clear;
7705 39523 : tree domain;
7706 39523 : tree elttype = TREE_TYPE (type);
7707 39523 : bool const_bounds_p;
7708 39523 : unsigned HOST_WIDE_INT minelt = 0;
7709 39523 : unsigned HOST_WIDE_INT maxelt = 0;
7710 :
7711 : /* The storage order is specified for every aggregate type. */
7712 39523 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7713 :
7714 39523 : domain = TYPE_DOMAIN (type);
7715 39523 : const_bounds_p = (TYPE_MIN_VALUE (domain)
7716 39523 : && TYPE_MAX_VALUE (domain)
7717 39523 : && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain))
7718 79046 : && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain)));
7719 :
7720 : /* If we have constant bounds for the range of the type, get them. */
7721 39523 : if (const_bounds_p)
7722 : {
7723 39523 : minelt = tree_to_uhwi (TYPE_MIN_VALUE (domain));
7724 39523 : maxelt = tree_to_uhwi (TYPE_MAX_VALUE (domain));
7725 : }
7726 :
7727 : /* If the constructor has fewer elements than the array, clear
7728 : the whole array first. Similarly if this is static
7729 : constructor of a non-BLKmode object. */
7730 39523 : if (cleared)
7731 : need_to_clear = false;
7732 39477 : else if (REG_P (target) && TREE_STATIC (exp))
7733 : need_to_clear = true;
7734 : else
7735 : {
7736 39370 : unsigned HOST_WIDE_INT idx;
7737 39370 : unsigned HOST_WIDE_INT count = 0, zero_count = 0;
7738 39370 : need_to_clear = ! const_bounds_p;
7739 :
7740 : /* This loop is a more accurate version of the loop in
7741 : mostly_zeros_p (it handles RANGE_EXPR in an index). It
7742 : is also needed to check for missing elements. */
7743 39418 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
7744 : {
7745 48 : unsigned HOST_WIDE_INT this_node_count;
7746 :
7747 48 : if (need_to_clear)
7748 : break;
7749 :
7750 48 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7751 : {
7752 0 : tree lo_index = TREE_OPERAND (index, 0);
7753 0 : tree hi_index = TREE_OPERAND (index, 1);
7754 :
7755 0 : if (! tree_fits_uhwi_p (lo_index)
7756 0 : || ! tree_fits_uhwi_p (hi_index))
7757 : {
7758 : need_to_clear = true;
7759 : break;
7760 : }
7761 :
7762 0 : this_node_count = (tree_to_uhwi (hi_index)
7763 0 : - tree_to_uhwi (lo_index) + 1);
7764 0 : }
7765 48 : else if (TREE_CODE (value) == RAW_DATA_CST)
7766 0 : this_node_count = RAW_DATA_LENGTH (value);
7767 : else
7768 : this_node_count = 1;
7769 :
7770 48 : count += this_node_count;
7771 48 : if (mostly_zeros_p (value))
7772 0 : zero_count += this_node_count;
7773 : }
7774 :
7775 : /* Clear the entire array first if there are any missing
7776 : elements, or if the incidence of zero elements is >=
7777 : 75%. */
7778 39370 : if (! need_to_clear
7779 39370 : && (count < maxelt - minelt + 1
7780 6 : || 4 * zero_count >= 3 * count))
7781 : need_to_clear = true;
7782 : }
7783 :
7784 39471 : if (need_to_clear && maybe_gt (size, 0))
7785 : {
7786 39471 : if (REG_P (target))
7787 1605 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7788 : else
7789 42630 : clear_storage (target, gen_int_mode (size, Pmode),
7790 : BLOCK_OP_NORMAL);
7791 : cleared = 1;
7792 : }
7793 :
7794 52 : if (!cleared && REG_P (target))
7795 : /* Inform later passes that the old value is dead. */
7796 0 : emit_clobber (target);
7797 :
7798 : /* Store each element of the constructor into the
7799 : corresponding element of TARGET, determined by counting the
7800 : elements. */
7801 40679 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
7802 : {
7803 1156 : machine_mode mode;
7804 1156 : poly_int64 bitsize;
7805 1156 : HOST_WIDE_INT bitpos;
7806 1156 : rtx xtarget = target;
7807 :
7808 1156 : if (cleared && initializer_zerop (value))
7809 : {
7810 672 : if (TREE_CODE (value) == RAW_DATA_CST)
7811 0 : j += RAW_DATA_LENGTH (value) - 1;
7812 674 : continue;
7813 : }
7814 :
7815 484 : mode = TYPE_MODE (elttype);
7816 484 : if (mode != BLKmode)
7817 968 : bitsize = GET_MODE_BITSIZE (mode);
7818 0 : else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
7819 0 : bitsize = -1;
7820 :
7821 484 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7822 : {
7823 0 : tree lo_index = TREE_OPERAND (index, 0);
7824 0 : tree hi_index = TREE_OPERAND (index, 1);
7825 0 : rtx index_r;
7826 0 : unsigned HOST_WIDE_INT lo, hi, count;
7827 0 : tree offset;
7828 :
7829 0 : gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
7830 :
7831 : /* If the range is constant and "small", unroll the loop. */
7832 0 : if (const_bounds_p
7833 0 : && tree_fits_uhwi_p (lo_index)
7834 0 : && tree_fits_uhwi_p (hi_index)
7835 0 : && (lo = tree_to_uhwi (lo_index),
7836 0 : hi = tree_to_uhwi (hi_index),
7837 0 : count = hi - lo + 1,
7838 0 : (!MEM_P (target)
7839 0 : || count <= 2
7840 0 : || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
7841 0 : && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
7842 : <= 40 * 8)))))
7843 : {
7844 0 : lo -= minelt; hi -= minelt;
7845 0 : for (; lo <= hi; lo++)
7846 : {
7847 0 : bitpos = lo * tree_to_uhwi (TYPE_SIZE (elttype));
7848 :
7849 0 : if (MEM_P (target)
7850 0 : && !MEM_KEEP_ALIAS_SET_P (target)
7851 0 : && TREE_CODE (type) == ARRAY_TYPE
7852 0 : && TYPE_NONALIASED_COMPONENT (type))
7853 : {
7854 0 : target = copy_rtx (target);
7855 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7856 : }
7857 :
7858 0 : store_constructor_field
7859 0 : (target, bitsize, bitpos, 0, bitregion_end,
7860 : mode, value, cleared,
7861 : get_alias_set (elttype), reverse);
7862 : }
7863 : }
7864 : else
7865 : {
7866 0 : rtx_code_label *loop_start = gen_label_rtx ();
7867 0 : rtx_code_label *loop_end = gen_label_rtx ();
7868 0 : tree exit_cond;
7869 :
7870 0 : expand_normal (hi_index);
7871 :
7872 0 : index = build_decl (EXPR_LOCATION (exp),
7873 : VAR_DECL, NULL_TREE, domain);
7874 0 : index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
7875 0 : SET_DECL_RTL (index, index_r);
7876 0 : store_expr (lo_index, index_r, 0, false, reverse);
7877 :
7878 : /* Build the head of the loop. */
7879 0 : do_pending_stack_adjust ();
7880 0 : emit_label (loop_start);
7881 :
7882 : /* Assign value to element index. */
7883 0 : offset = fold_build2 (MINUS_EXPR,
7884 : TREE_TYPE (index),
7885 : index,
7886 : TYPE_MIN_VALUE (domain));
7887 :
7888 0 : offset = size_binop (MULT_EXPR,
7889 : fold_convert (sizetype, offset),
7890 : TYPE_SIZE_UNIT (elttype));
7891 :
7892 0 : xtarget = offset_address (target,
7893 : expand_normal (offset),
7894 : highest_pow2_factor (offset));
7895 0 : xtarget = adjust_address (xtarget, mode, 0);
7896 0 : if (TREE_CODE (value) == CONSTRUCTOR)
7897 0 : store_constructor (value, xtarget, cleared,
7898 : exact_div (bitsize, BITS_PER_UNIT),
7899 : reverse);
7900 : else
7901 0 : store_expr (value, xtarget, 0, false, reverse);
7902 :
7903 : /* Generate a conditional jump to exit the loop. */
7904 0 : exit_cond = build2 (LT_EXPR, integer_type_node,
7905 : index, hi_index);
7906 0 : jumpif (exit_cond, loop_end,
7907 : profile_probability::uninitialized ());
7908 :
7909 : /* Update the loop counter, and jump to the head of
7910 : the loop. */
7911 0 : expand_assignment (index,
7912 0 : build2 (PLUS_EXPR, TREE_TYPE (index),
7913 : index, integer_one_node),
7914 : false);
7915 :
7916 0 : emit_jump (loop_start);
7917 :
7918 : /* Build the end of the loop. */
7919 0 : emit_label (loop_end);
7920 : }
7921 : }
7922 484 : else if ((index && !tree_fits_uhwi_p (index))
7923 484 : || !tree_fits_uhwi_p (TYPE_SIZE (elttype)))
7924 : {
7925 0 : tree offset;
7926 :
7927 0 : gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
7928 0 : if (index)
7929 0 : offset = fold_build2 (MINUS_EXPR,
7930 : TREE_TYPE (index),
7931 : index,
7932 : TYPE_MIN_VALUE (domain));
7933 : else
7934 0 : offset = size_int (i + j);
7935 :
7936 0 : offset = size_binop (MULT_EXPR,
7937 : fold_convert (sizetype, offset),
7938 : TYPE_SIZE_UNIT (elttype));
7939 0 : xtarget = offset_address (target,
7940 : expand_normal (offset),
7941 : highest_pow2_factor (offset));
7942 0 : xtarget = adjust_address (xtarget, mode, 0);
7943 0 : store_expr (value, xtarget, 0, false, reverse);
7944 : }
7945 : else
7946 : {
7947 484 : if (index)
7948 968 : bitpos = ((tree_to_uhwi (index) - minelt)
7949 484 : * tree_to_uhwi (TYPE_SIZE (elttype)));
7950 : else
7951 0 : bitpos = ((i + j) * tree_to_uhwi (TYPE_SIZE (elttype)));
7952 :
7953 52 : if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
7954 52 : && TREE_CODE (type) == ARRAY_TYPE
7955 536 : && TYPE_NONALIASED_COMPONENT (type))
7956 : {
7957 0 : target = copy_rtx (target);
7958 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7959 : }
7960 484 : if (TREE_CODE (value) != RAW_DATA_CST)
7961 480 : store_constructor_field (target, bitsize, bitpos, 0,
7962 480 : bitregion_end, mode, value,
7963 : cleared, get_alias_set (elttype),
7964 : reverse);
7965 : else
7966 : {
7967 4 : j += RAW_DATA_LENGTH (value) - 1;
7968 4 : gcc_assert (known_eq (bitsize, BITS_PER_UNIT));
7969 4 : rtx to_rtx = adjust_address (target, mode,
7970 : bitpos / BITS_PER_UNIT);
7971 :
7972 4 : if (to_rtx == target)
7973 0 : to_rtx = copy_rtx (to_rtx);
7974 :
7975 4 : if (!MEM_KEEP_ALIAS_SET_P (to_rtx)
7976 8 : && MEM_ALIAS_SET (to_rtx) != 0)
7977 0 : set_mem_alias_set (to_rtx, get_alias_set (elttype));
7978 :
7979 8 : if (can_store_by_pieces (RAW_DATA_LENGTH (value),
7980 : raw_data_cst_read_str,
7981 : (void *) value,
7982 4 : MEM_ALIGN (target), false))
7983 : {
7984 4 : store_by_pieces (target, RAW_DATA_LENGTH (value),
7985 : raw_data_cst_read_str, (void *) value,
7986 2 : MEM_ALIGN (target), false,
7987 : RETURN_BEGIN);
7988 2 : continue;
7989 : }
7990 :
7991 2 : elttype
7992 2 : = build_array_type_nelts (TREE_TYPE (value),
7993 2 : RAW_DATA_LENGTH (value));
7994 2 : tree ctor = build_constructor_single (elttype, NULL_TREE,
7995 : value);
7996 2 : ctor = tree_output_constant_def (ctor);
7997 2 : mode = TYPE_MODE (type);
7998 2 : store_constructor_field (target,
7999 2 : bitsize * RAW_DATA_LENGTH (value),
8000 2 : bitpos, 0, bitregion_end, mode,
8001 : ctor, cleared,
8002 : get_alias_set (elttype), reverse);
8003 : }
8004 : }
8005 : }
8006 : break;
8007 : }
8008 :
8009 138012 : case VECTOR_TYPE:
8010 138012 : {
8011 138012 : unsigned HOST_WIDE_INT idx;
8012 138012 : constructor_elt *ce;
8013 138012 : bool need_to_clear;
8014 138012 : insn_code icode = CODE_FOR_nothing;
8015 138012 : tree elt;
8016 138012 : tree elttype = TREE_TYPE (type);
8017 138012 : int elt_size = vector_element_bits (type);
8018 138012 : machine_mode eltmode = TYPE_MODE (elttype);
8019 138012 : poly_int64 bitsize;
8020 138012 : poly_int64 bitpos;
8021 138012 : rtvec vector = NULL;
8022 138012 : poly_uint64 n_elts;
8023 138012 : unsigned HOST_WIDE_INT const_n_elts;
8024 138012 : alias_set_type alias;
8025 138012 : bool vec_vec_init_p = false;
8026 138012 : machine_mode mode = GET_MODE (target);
8027 :
8028 138012 : gcc_assert (eltmode != BLKmode);
8029 :
8030 : /* Try using vec_duplicate_optab for uniform vectors. */
8031 138012 : icode = optab_handler (vec_duplicate_optab, mode);
8032 138012 : if (!TREE_SIDE_EFFECTS (exp)
8033 138012 : && VECTOR_MODE_P (mode)
8034 134586 : && icode != CODE_FOR_nothing
8035 : /* If the vec_duplicate target pattern does not specify an element
8036 : mode check that eltmode is the normal inner mode of the
8037 : requested vector mode. But if the target allows eltmode
8038 : explicitly go ahead and use it. */
8039 92574 : && (eltmode == GET_MODE_INNER (mode)
8040 0 : || insn_data[icode].operand[1].mode == eltmode)
8041 92574 : && (elt = uniform_vector_p (exp))
8042 155688 : && !VECTOR_TYPE_P (TREE_TYPE (elt)))
8043 : {
8044 17676 : class expand_operand ops[2];
8045 17676 : create_output_operand (&ops[0], target, mode);
8046 17676 : create_input_operand (&ops[1], expand_normal (elt), eltmode);
8047 17676 : expand_insn (icode, 2, ops);
8048 17676 : if (!rtx_equal_p (target, ops[0].value))
8049 0 : emit_move_insn (target, ops[0].value);
8050 17676 : break;
8051 : }
8052 : /* Use sign-extension for uniform boolean vectors with
8053 : integer modes and single-bit mask entries.
8054 : Effectively "vec_duplicate" for bitmasks. */
8055 120336 : if (elt_size == 1
8056 146 : && !TREE_SIDE_EFFECTS (exp)
8057 146 : && VECTOR_BOOLEAN_TYPE_P (type)
8058 146 : && SCALAR_INT_MODE_P (TYPE_MODE (type))
8059 146 : && (elt = uniform_vector_p (exp))
8060 143 : && !VECTOR_TYPE_P (TREE_TYPE (elt))
8061 120336 : && !BYTES_BIG_ENDIAN)
8062 : {
8063 143 : rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
8064 : expand_normal (elt));
8065 143 : rtx tmp = gen_reg_rtx (mode);
8066 143 : convert_move (tmp, op0, 0);
8067 :
8068 : /* Ensure no excess bits are set.
8069 : GCN needs this for nunits < 64.
8070 : x86 needs this for nunits < 8. */
8071 143 : unsigned int nunits = TYPE_VECTOR_SUBPARTS (type).to_constant ();
8072 143 : if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
8073 2 : tmp = expand_binop (mode, and_optab, tmp,
8074 2 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
8075 : target, true, OPTAB_WIDEN);
8076 143 : if (tmp != target)
8077 141 : emit_move_insn (target, tmp);
8078 : break;
8079 : }
8080 :
8081 120193 : n_elts = TYPE_VECTOR_SUBPARTS (type);
8082 120193 : if (REG_P (target)
8083 117070 : && VECTOR_MODE_P (mode))
8084 : {
8085 116910 : const_n_elts = 0;
8086 116910 : if (CONSTRUCTOR_NELTS (exp)
8087 116910 : && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
8088 : == VECTOR_TYPE))
8089 : {
8090 1438 : tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
8091 1438 : gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
8092 : * TYPE_VECTOR_SUBPARTS (etype),
8093 : n_elts));
8094 :
8095 4314 : icode = convert_optab_handler (vec_init_optab, mode,
8096 1438 : TYPE_MODE (etype));
8097 1438 : const_n_elts = CONSTRUCTOR_NELTS (exp);
8098 1438 : vec_vec_init_p = icode != CODE_FOR_nothing;
8099 : }
8100 230944 : else if (exact_div (n_elts, GET_MODE_NUNITS (eltmode))
8101 115472 : .is_constant (&const_n_elts))
8102 : {
8103 : /* For a non-const type vector, we check it is made up of
8104 : similarly non-const type vectors. */
8105 115472 : icode = convert_optab_handler (vec_init_optab, mode, eltmode);
8106 : }
8107 : else
8108 : {
8109 : /* Handle variable-length vector types. */
8110 : icode = convert_optab_handler (vec_init_optab, mode, eltmode);
8111 : const_n_elts = constant_lower_bound (n_elts);
8112 : }
8113 :
8114 116910 : if (const_n_elts && icode != CODE_FOR_nothing)
8115 : {
8116 116179 : vector = rtvec_alloc (const_n_elts);
8117 433617 : for (unsigned int k = 0; k < const_n_elts; k++)
8118 317438 : RTVEC_ELT (vector, k) = CONST0_RTX (eltmode);
8119 : }
8120 : }
8121 : else
8122 : gcc_assert (n_elts.is_constant ());
8123 :
8124 : /* Compute the size of the elements in the CTOR. It differs
8125 : from the size of the vector type elements only when the
8126 : CTOR elements are vectors themselves. */
8127 120193 : tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
8128 120193 : ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
8129 120193 : : elttype);
8130 120193 : if (VECTOR_TYPE_P (val_type))
8131 1760 : bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
8132 : else
8133 118433 : bitsize = elt_size;
8134 :
8135 : /* If the constructor has fewer elements than the vector,
8136 : clear the whole array first. Similarly if this is static
8137 : constructor of a non-BLKmode object. */
8138 120193 : if (cleared)
8139 : need_to_clear = false;
8140 120193 : else if (REG_P (target) && TREE_STATIC (exp))
8141 : need_to_clear = true;
8142 : else
8143 : {
8144 : poly_uint64 count = 0, zero_count = 0;
8145 : tree value;
8146 :
8147 480027 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
8148 : {
8149 359834 : poly_int64 n_elts_here = exact_div (bitsize, elt_size);
8150 359834 : count += n_elts_here;
8151 359834 : if (mostly_zeros_p (value))
8152 359834 : zero_count += n_elts_here;
8153 : }
8154 :
8155 : /* Clear the entire vector first if there are any missing elements,
8156 : or if the incidence of zero elements is >= 75%. */
8157 120193 : need_to_clear = (maybe_lt (count, n_elts)
8158 120193 : || maybe_gt (4 * zero_count, 3 * count));
8159 : }
8160 :
8161 1164 : if (need_to_clear && maybe_gt (size, 0) && !vector)
8162 : {
8163 682 : if (REG_P (target))
8164 1 : emit_move_insn (target, CONST0_RTX (mode));
8165 : else
8166 681 : clear_storage (target, gen_int_mode (size, Pmode),
8167 : BLOCK_OP_NORMAL);
8168 : cleared = 1;
8169 : }
8170 :
8171 : /* Inform later passes that the old value is dead. */
8172 120193 : if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
8173 : {
8174 573 : emit_move_insn (target, CONST0_RTX (mode));
8175 573 : cleared = 1;
8176 : }
8177 :
8178 120193 : if (MEM_P (target))
8179 3123 : alias = MEM_ALIAS_SET (target);
8180 : else
8181 117070 : alias = get_alias_set (elttype);
8182 :
8183 : /* Store each element of the constructor into the corresponding
8184 : element of TARGET, determined by counting the elements. */
8185 120193 : HOST_WIDE_INT chunk_size = 0;
8186 120193 : bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
8187 : &chunk_size);
8188 120193 : gcc_assert (chunk_multiple_p || vec_vec_init_p);
8189 :
8190 480027 : for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
8191 : idx++)
8192 : {
8193 359834 : HOST_WIDE_INT eltpos;
8194 359834 : tree value = ce->value;
8195 :
8196 359834 : if (cleared && initializer_zerop (value))
8197 7683 : continue;
8198 :
8199 352151 : if (ce->index)
8200 48049 : eltpos = tree_to_uhwi (ce->index);
8201 : else
8202 304102 : eltpos = idx * chunk_size;
8203 :
8204 352151 : if (vector)
8205 : {
8206 316358 : if (vec_vec_init_p)
8207 : {
8208 2772 : gcc_assert (ce->index == NULL_TREE);
8209 2772 : gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
8210 2772 : eltpos = idx;
8211 : }
8212 : else
8213 313586 : gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
8214 316358 : RTVEC_ELT (vector, eltpos) = expand_normal (value);
8215 : }
8216 : else
8217 : {
8218 35793 : machine_mode value_mode
8219 35793 : = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
8220 35793 : ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
8221 35793 : bitpos = eltpos * elt_size;
8222 35793 : store_constructor_field (target, bitsize, bitpos, 0,
8223 35793 : bitregion_end, value_mode,
8224 : value, cleared, alias, reverse);
8225 : }
8226 : }
8227 :
8228 120193 : if (vector)
8229 116179 : emit_insn (GEN_FCN (icode) (target,
8230 : gen_rtx_PARALLEL (mode, vector)));
8231 : break;
8232 : }
8233 :
8234 0 : default:
8235 0 : gcc_unreachable ();
8236 : }
8237 246140 : }
8238 :
8239 : /* Store the value of EXP (an expression tree)
8240 : into a subfield of TARGET which has mode MODE and occupies
8241 : BITSIZE bits, starting BITPOS bits from the start of TARGET.
8242 : If MODE is VOIDmode, it means that we are storing into a bit-field.
8243 :
8244 : BITREGION_START is bitpos of the first bitfield in this region.
8245 : BITREGION_END is the bitpos of the ending bitfield in this region.
8246 : These two fields are 0, if the C++ memory model does not apply,
8247 : or we are not interested in keeping track of bitfield regions.
8248 :
8249 : Always return const0_rtx unless we have something particular to
8250 : return.
8251 :
8252 : ALIAS_SET is the alias set for the destination. This value will
8253 : (in general) be different from that for TARGET, since TARGET is a
8254 : reference to the containing structure.
8255 :
8256 : If NONTEMPORAL is true, try generating a nontemporal store.
8257 :
8258 : If REVERSE is true, the store is to be done in reverse order. */
8259 :
8260 : static rtx
8261 4811022 : store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
8262 : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
8263 : machine_mode mode, tree exp,
8264 : alias_set_type alias_set, bool nontemporal, bool reverse)
8265 : {
8266 4811022 : if (TREE_CODE (exp) == ERROR_MARK)
8267 0 : return const0_rtx;
8268 :
8269 : /* If we have nothing to store, do nothing unless the expression has
8270 : side-effects. Don't do that for zero sized addressable lhs of
8271 : calls. */
8272 4811022 : if (known_eq (bitsize, 0)
8273 4811022 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8274 3 : || TREE_CODE (exp) != CALL_EXPR))
8275 0 : return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
8276 :
8277 4811022 : if (GET_CODE (target) == CONCAT)
8278 : {
8279 : /* We're storing into a struct containing a single __complex. */
8280 :
8281 0 : gcc_assert (known_eq (bitpos, 0));
8282 0 : return store_expr (exp, target, 0, nontemporal, reverse);
8283 : }
8284 :
8285 : /* If the structure is in a register or if the component
8286 : is a bit field, we cannot use addressing to access it.
8287 : Use bit-field techniques or SUBREG to store in it. */
8288 :
8289 4811022 : poly_int64 decl_bitsize;
8290 4811022 : if (mode == VOIDmode
8291 4744003 : || (mode != BLKmode && ! direct_store[(int) mode]
8292 5338 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
8293 5336 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
8294 4738696 : || REG_P (target)
8295 4045550 : || GET_CODE (target) == SUBREG
8296 : /* If the field isn't aligned enough to store as an ordinary memref,
8297 : store it as a bit field. */
8298 4045550 : || (mode != BLKmode
8299 3930142 : && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
8300 7772356 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
8301 46733 : && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
8302 3930142 : || !multiple_p (bitpos, BITS_PER_UNIT)))
8303 4045550 : || (known_size_p (bitsize)
8304 4045538 : && mode != BLKmode
8305 3930142 : && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
8306 : /* If the RHS and field are a constant size and the size of the
8307 : RHS isn't the same size as the bitfield, we must use bitfield
8308 : operations. */
8309 4045541 : || (known_size_p (bitsize)
8310 4045529 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
8311 4045529 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
8312 : bitsize)
8313 : /* Except for initialization of full bytes from a CONSTRUCTOR, which
8314 : we will handle specially below. */
8315 34 : && !(TREE_CODE (exp) == CONSTRUCTOR
8316 11 : && multiple_p (bitsize, BITS_PER_UNIT))
8317 : /* And except for bitwise copying of TREE_ADDRESSABLE types,
8318 : where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
8319 : includes some extra padding. store_expr / expand_expr will in
8320 : that case call get_inner_reference that will have the bitsize
8321 : we check here and thus the block move will not clobber the
8322 : padding that shouldn't be clobbered. In the future we could
8323 : replace the TREE_ADDRESSABLE check with a check that
8324 : get_base_address needs to live in memory. */
8325 23 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8326 9 : || TREE_CODE (exp) != COMPONENT_REF
8327 6 : || !multiple_p (bitsize, BITS_PER_UNIT)
8328 6 : || !multiple_p (bitpos, BITS_PER_UNIT)
8329 6 : || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
8330 : &decl_bitsize)
8331 6 : || maybe_ne (decl_bitsize, bitsize))
8332 : /* A call with an addressable return type and return-slot
8333 : optimization must not need bitfield operations but we must
8334 : pass down the original target. */
8335 17 : && (TREE_CODE (exp) != CALL_EXPR
8336 6 : || !TREE_ADDRESSABLE (TREE_TYPE (exp))
8337 0 : || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
8338 : /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
8339 : decl we must use bitfield operations. */
8340 8856546 : || (known_size_p (bitsize)
8341 4045512 : && TREE_CODE (exp) == MEM_REF
8342 32751 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
8343 26740 : && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8344 20371 : && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8345 5646 : && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
8346 : {
8347 765767 : rtx temp;
8348 765767 : gimple *nop_def;
8349 :
8350 : /* If EXP is a NOP_EXPR of precision less than its mode, then that
8351 : implies a mask operation. If the precision is the same size as
8352 : the field we're storing into, that mask is redundant. This is
8353 : particularly common with bit field assignments generated by the
8354 : C front end. */
8355 765767 : nop_def = get_def_for_expr (exp, NOP_EXPR);
8356 765767 : if (nop_def)
8357 : {
8358 5626 : tree type = TREE_TYPE (exp);
8359 5626 : if (INTEGRAL_TYPE_P (type)
8360 5415 : && maybe_ne (TYPE_PRECISION (type),
8361 10830 : GET_MODE_BITSIZE (TYPE_MODE (type)))
8362 9019 : && known_eq (bitsize, TYPE_PRECISION (type)))
8363 : {
8364 3288 : tree op = gimple_assign_rhs1 (nop_def);
8365 3288 : type = TREE_TYPE (op);
8366 3288 : if (INTEGRAL_TYPE_P (type)
8367 3288 : && known_ge (TYPE_PRECISION (type), bitsize))
8368 : exp = op;
8369 : }
8370 : }
8371 :
8372 765767 : temp = expand_normal (exp);
8373 :
8374 : /* We don't support variable-sized BLKmode bitfields, since our
8375 : handling of BLKmode is bound up with the ability to break
8376 : things into words. */
8377 765767 : gcc_assert (mode != BLKmode || bitsize.is_constant ());
8378 :
8379 : /* Handle calls that return values in multiple non-contiguous locations.
8380 : The Irix 6 ABI has examples of this. */
8381 765767 : if (GET_CODE (temp) == PARALLEL)
8382 : {
8383 6 : HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
8384 6 : machine_mode temp_mode = GET_MODE (temp);
8385 6 : if (temp_mode == BLKmode || temp_mode == VOIDmode)
8386 6 : temp_mode
8387 6 : = smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
8388 6 : rtx temp_target = gen_reg_rtx (temp_mode);
8389 6 : emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
8390 6 : temp = temp_target;
8391 : }
8392 :
8393 : /* Handle calls that return BLKmode values in registers. */
8394 765761 : else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
8395 : {
8396 0 : rtx temp_target = gen_reg_rtx (GET_MODE (temp));
8397 0 : copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
8398 0 : temp = temp_target;
8399 : }
8400 :
8401 : /* If the value has aggregate type and an integral mode then, if BITSIZE
8402 : is narrower than this mode and this is for big-endian data, we first
8403 : need to put the value into the low-order bits for store_bit_field,
8404 : except when MODE is BLKmode and BITSIZE larger than the word size
8405 : (see the handling of fields larger than a word in store_bit_field).
8406 : Moreover, the field may be not aligned on a byte boundary; in this
8407 : case, if it has reverse storage order, it needs to be accessed as a
8408 : scalar field with reverse storage order and we must first put the
8409 : value into target order. */
8410 765767 : scalar_int_mode temp_mode;
8411 1529506 : if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
8412 766514 : && is_int_mode (GET_MODE (temp), &temp_mode))
8413 : {
8414 2448 : HOST_WIDE_INT size = GET_MODE_BITSIZE (temp_mode);
8415 :
8416 2448 : reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
8417 :
8418 2448 : if (reverse)
8419 0 : temp = flip_storage_order (temp_mode, temp);
8420 :
8421 2448 : gcc_checking_assert (known_le (bitsize, size));
8422 2448 : if (maybe_lt (bitsize, size)
8423 2448 : && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
8424 : /* Use of to_constant for BLKmode was checked above. */
8425 : && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
8426 0 : temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
8427 : size - bitsize, NULL_RTX, 1);
8428 : }
8429 :
8430 : /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE. */
8431 698748 : if (mode != VOIDmode && mode != BLKmode
8432 1464238 : && mode != TYPE_MODE (TREE_TYPE (exp)))
8433 4 : temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
8434 :
8435 : /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
8436 : and BITPOS must be aligned on a byte boundary. If so, we simply do
8437 : a block copy. Likewise for a BLKmode-like TARGET. */
8438 765767 : if (GET_MODE (temp) == BLKmode
8439 765767 : && (GET_MODE (target) == BLKmode
8440 182 : || (MEM_P (target)
8441 0 : && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
8442 0 : && multiple_p (bitpos, BITS_PER_UNIT)
8443 0 : && multiple_p (bitsize, BITS_PER_UNIT))))
8444 : {
8445 89 : gcc_assert (MEM_P (target) && MEM_P (temp));
8446 89 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
8447 89 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
8448 :
8449 89 : target = adjust_address (target, VOIDmode, bytepos);
8450 89 : emit_block_move (target, temp,
8451 89 : gen_int_mode (bytesize, Pmode),
8452 : BLOCK_OP_NORMAL);
8453 :
8454 89 : return const0_rtx;
8455 : }
8456 :
8457 : /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
8458 : word size, we need to load the value (see again store_bit_field). */
8459 765696 : if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
8460 : {
8461 61 : temp_mode = smallest_int_mode_for_size (bitsize).require ();
8462 61 : temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
8463 : temp_mode, false, NULL);
8464 : }
8465 :
8466 : /* Store the value in the bitfield. */
8467 765678 : gcc_checking_assert (known_ge (bitpos, 0));
8468 765678 : store_bit_field (target, bitsize, bitpos,
8469 : bitregion_start, bitregion_end,
8470 : mode, temp, reverse, false);
8471 :
8472 765678 : return const0_rtx;
8473 : }
8474 : else
8475 : {
8476 : /* Now build a reference to just the desired component. */
8477 4045255 : rtx to_rtx = adjust_address (target, mode,
8478 : exact_div (bitpos, BITS_PER_UNIT));
8479 :
8480 4045255 : if (to_rtx == target)
8481 1292279 : to_rtx = copy_rtx (to_rtx);
8482 :
8483 7815198 : if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
8484 3511065 : set_mem_alias_set (to_rtx, alias_set);
8485 :
8486 : /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
8487 : into a target smaller than its type; handle that case now. */
8488 4045255 : if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (bitsize))
8489 : {
8490 69726 : poly_int64 bytesize = exact_div (bitsize, BITS_PER_UNIT);
8491 69726 : store_constructor (exp, to_rtx, 0, bytesize, reverse);
8492 69726 : return to_rtx;
8493 : }
8494 :
8495 3975529 : return store_expr (exp, to_rtx, 0, nontemporal, reverse);
8496 : }
8497 : }
8498 :
8499 : /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
8500 : an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
8501 : codes and find the ultimate containing object, which we return.
8502 :
8503 : We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
8504 : bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
8505 : storage order of the field.
8506 : If the position of the field is variable, we store a tree
8507 : giving the variable offset (in units) in *POFFSET.
8508 : This offset is in addition to the bit position.
8509 : If the position is not variable, we store 0 in *POFFSET.
8510 :
8511 : If any of the extraction expressions is volatile,
8512 : we store 1 in *PVOLATILEP. Otherwise we don't change that.
8513 :
8514 : If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
8515 : Otherwise, it is a mode that can be used to access the field.
8516 :
8517 : If the field describes a variable-sized object, *PMODE is set to
8518 : BLKmode and *PBITSIZE is set to -1. An access cannot be made in
8519 : this case, but the address of the object can be found. */
8520 :
8521 : tree
8522 288751956 : get_inner_reference (tree exp, poly_int64 *pbitsize,
8523 : poly_int64 *pbitpos, tree *poffset,
8524 : machine_mode *pmode, int *punsignedp,
8525 : int *preversep, int *pvolatilep)
8526 : {
8527 288751956 : tree size_tree = 0;
8528 288751956 : machine_mode mode = VOIDmode;
8529 288751956 : bool blkmode_bitfield = false;
8530 288751956 : tree offset = size_zero_node;
8531 288751956 : poly_offset_int bit_offset = 0;
8532 :
8533 : /* First get the mode, signedness, storage order and size. We do this from
8534 : just the outermost expression. */
8535 288751956 : *pbitsize = -1;
8536 288751956 : if (TREE_CODE (exp) == COMPONENT_REF)
8537 : {
8538 121495195 : tree field = TREE_OPERAND (exp, 1);
8539 121495195 : size_tree = DECL_SIZE (field);
8540 121495195 : if (flag_strict_volatile_bitfields > 0
8541 58 : && TREE_THIS_VOLATILE (exp)
8542 40 : && DECL_BIT_FIELD_TYPE (field)
8543 121495217 : && DECL_MODE (field) != BLKmode)
8544 : /* Volatile bitfields should be accessed in the mode of the
8545 : field's type, not the mode computed based on the bit
8546 : size. */
8547 22 : mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
8548 121495173 : else if (!DECL_BIT_FIELD (field))
8549 : {
8550 120208880 : mode = DECL_MODE (field);
8551 : /* For vector fields re-check the target flags, as DECL_MODE
8552 : could have been set with different target flags than
8553 : the current function has. */
8554 120208880 : if (VECTOR_TYPE_P (TREE_TYPE (field))
8555 120208880 : && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
8556 380853 : mode = TYPE_MODE (TREE_TYPE (field));
8557 : }
8558 1286293 : else if (DECL_MODE (field) == BLKmode)
8559 624 : blkmode_bitfield = true;
8560 :
8561 121495195 : *punsignedp = DECL_UNSIGNED (field);
8562 : }
8563 167256761 : else if (TREE_CODE (exp) == BIT_FIELD_REF)
8564 : {
8565 594946 : size_tree = TREE_OPERAND (exp, 1);
8566 1189473 : *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
8567 1043042 : || TYPE_UNSIGNED (TREE_TYPE (exp)));
8568 :
8569 : /* For vector element types with the correct size of access or for
8570 : vector typed accesses use the mode of the access type. */
8571 594946 : if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
8572 447115 : && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
8573 402232 : && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
8574 639864 : || VECTOR_TYPE_P (TREE_TYPE (exp)))
8575 425378 : mode = TYPE_MODE (TREE_TYPE (exp));
8576 : }
8577 : else
8578 : {
8579 166661815 : mode = TYPE_MODE (TREE_TYPE (exp));
8580 166661815 : *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
8581 :
8582 166661815 : if (mode == BLKmode)
8583 73057798 : size_tree = TYPE_SIZE (TREE_TYPE (exp));
8584 : else
8585 187208034 : *pbitsize = GET_MODE_BITSIZE (mode);
8586 : }
8587 :
8588 288751956 : if (size_tree != 0)
8589 : {
8590 194320953 : if (!poly_int_tree_p (size_tree, pbitsize))
8591 474633 : mode = BLKmode, *pbitsize = -1;
8592 : }
8593 :
8594 288751956 : *preversep = reverse_storage_order_for_component_p (exp);
8595 :
8596 : /* Compute cumulative bit-offset for nested component-refs and array-refs,
8597 : and find the ultimate containing object. */
8598 732499506 : while (1)
8599 : {
8600 510625731 : switch (TREE_CODE (exp))
8601 : {
8602 594946 : case BIT_FIELD_REF:
8603 594946 : bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
8604 594946 : break;
8605 :
8606 185476234 : case COMPONENT_REF:
8607 185476234 : {
8608 185476234 : tree field = TREE_OPERAND (exp, 1);
8609 185476234 : tree this_offset = component_ref_field_offset (exp);
8610 :
8611 : /* If this field hasn't been filled in yet, don't go past it.
8612 : This should only happen when folding expressions made during
8613 : type construction. */
8614 185476234 : if (this_offset == 0)
8615 : break;
8616 :
8617 185476234 : offset = size_binop (PLUS_EXPR, offset, this_offset);
8618 185476234 : bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
8619 :
8620 : /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */
8621 : }
8622 185476234 : break;
8623 :
8624 32565710 : case ARRAY_REF:
8625 32565710 : case ARRAY_RANGE_REF:
8626 32565710 : {
8627 32565710 : tree index = TREE_OPERAND (exp, 1);
8628 32565710 : tree low_bound = array_ref_low_bound (exp);
8629 32565710 : tree unit_size = array_ref_element_size (exp);
8630 :
8631 : /* We assume all arrays have sizes that are a multiple of a byte.
8632 : First subtract the lower bound, if any, in the type of the
8633 : index, then convert to sizetype and multiply by the size of
8634 : the array element. */
8635 32565710 : if (! integer_zerop (low_bound))
8636 965197 : index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
8637 : index, low_bound);
8638 :
8639 32565710 : offset = size_binop (PLUS_EXPR, offset,
8640 : size_binop (MULT_EXPR,
8641 : fold_convert (sizetype, index),
8642 : unit_size));
8643 : }
8644 32565710 : break;
8645 :
8646 : case REALPART_EXPR:
8647 : break;
8648 :
8649 : case IMAGPART_EXPR:
8650 221873775 : bit_offset += *pbitsize;
8651 : break;
8652 :
8653 : case VIEW_CONVERT_EXPR:
8654 : break;
8655 :
8656 92233261 : case MEM_REF:
8657 : /* Hand back the decl for MEM[&decl, off]. */
8658 92233261 : if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
8659 : {
8660 21556191 : tree off = TREE_OPERAND (exp, 1);
8661 21556191 : if (!integer_zerop (off))
8662 : {
8663 12165171 : poly_offset_int boff = mem_ref_offset (exp);
8664 12165171 : boff <<= LOG2_BITS_PER_UNIT;
8665 12165171 : bit_offset += boff;
8666 : }
8667 21556191 : exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8668 : }
8669 92233261 : goto done;
8670 :
8671 196518695 : default:
8672 196518695 : goto done;
8673 : }
8674 :
8675 : /* If any reference in the chain is volatile, the effect is volatile. */
8676 221873775 : if (TREE_THIS_VOLATILE (exp))
8677 564613 : *pvolatilep = 1;
8678 :
8679 221873775 : exp = TREE_OPERAND (exp, 0);
8680 221873775 : }
8681 288751956 : done:
8682 :
8683 : /* If OFFSET is constant, see if we can return the whole thing as a
8684 : constant bit position. Make sure to handle overflow during
8685 : this conversion. */
8686 288751956 : if (poly_int_tree_p (offset))
8687 : {
8688 275000851 : poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
8689 275000851 : TYPE_PRECISION (sizetype));
8690 275000851 : tem <<= LOG2_BITS_PER_UNIT;
8691 275000851 : tem += bit_offset;
8692 275000851 : if (tem.to_shwi (pbitpos))
8693 274999428 : *poffset = offset = NULL_TREE;
8694 : }
8695 :
8696 : /* Otherwise, split it up. */
8697 275000851 : if (offset)
8698 : {
8699 : /* Avoid returning a negative bitpos as this may wreak havoc later. */
8700 13752528 : if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
8701 : {
8702 303 : *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
8703 303 : poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
8704 303 : offset = size_binop (PLUS_EXPR, offset,
8705 : build_int_cst (sizetype, bytes.force_shwi ()));
8706 : }
8707 :
8708 13752528 : *poffset = offset;
8709 : }
8710 :
8711 : /* We can use BLKmode for a byte-aligned BLKmode bitfield. */
8712 288751956 : if (mode == VOIDmode
8713 5386425 : && blkmode_bitfield
8714 624 : && multiple_p (*pbitpos, BITS_PER_UNIT)
8715 288752444 : && multiple_p (*pbitsize, BITS_PER_UNIT))
8716 5 : *pmode = BLKmode;
8717 : else
8718 288751951 : *pmode = mode;
8719 :
8720 288751956 : return exp;
8721 : }
8722 :
8723 : /* Alignment in bits the TARGET of an assignment may be assumed to have. */
8724 :
8725 : static unsigned HOST_WIDE_INT
8726 514042 : target_align (const_tree target)
8727 : {
8728 : /* We might have a chain of nested references with intermediate misaligning
8729 : bitfields components, so need to recurse to find out. */
8730 :
8731 514042 : unsigned HOST_WIDE_INT this_align, outer_align;
8732 :
8733 514042 : switch (TREE_CODE (target))
8734 : {
8735 : case BIT_FIELD_REF:
8736 : return 1;
8737 :
8738 140086 : case COMPONENT_REF:
8739 140086 : this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
8740 140086 : outer_align = target_align (TREE_OPERAND (target, 0));
8741 140086 : return MIN (this_align, outer_align);
8742 :
8743 190269 : case ARRAY_REF:
8744 190269 : case ARRAY_RANGE_REF:
8745 190269 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8746 190269 : outer_align = target_align (TREE_OPERAND (target, 0));
8747 190269 : return MIN (this_align, outer_align);
8748 :
8749 4683 : CASE_CONVERT:
8750 4683 : case NON_LVALUE_EXPR:
8751 4683 : case VIEW_CONVERT_EXPR:
8752 4683 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8753 4683 : outer_align = target_align (TREE_OPERAND (target, 0));
8754 4683 : return MAX (this_align, outer_align);
8755 :
8756 178999 : default:
8757 178999 : return TYPE_ALIGN (TREE_TYPE (target));
8758 : }
8759 : }
8760 :
8761 :
8762 : /* Given an rtx VALUE that may contain additions and multiplications, return
8763 : an equivalent value that just refers to a register, memory, or constant.
8764 : This is done by generating instructions to perform the arithmetic and
8765 : returning a pseudo-register containing the value.
8766 :
8767 : The returned value may be a REG, SUBREG, MEM or constant. */
8768 :
8769 : rtx
8770 31441005 : force_operand (rtx value, rtx target)
8771 : {
8772 31441005 : rtx op1, op2;
8773 : /* Use subtarget as the target for operand 0 of a binary operation. */
8774 31441005 : rtx subtarget = get_subtarget (target);
8775 31441005 : enum rtx_code code = GET_CODE (value);
8776 :
8777 : /* Check for subreg applied to an expression produced by loop optimizer. */
8778 31441005 : if (code == SUBREG
8779 305644 : && !REG_P (SUBREG_REG (value))
8780 172 : && !MEM_P (SUBREG_REG (value)))
8781 : {
8782 172 : value
8783 172 : = simplify_gen_subreg (GET_MODE (value),
8784 172 : force_reg (GET_MODE (SUBREG_REG (value)),
8785 : force_operand (SUBREG_REG (value),
8786 : NULL_RTX)),
8787 172 : GET_MODE (SUBREG_REG (value)),
8788 172 : SUBREG_BYTE (value));
8789 172 : code = GET_CODE (value);
8790 : }
8791 :
8792 : /* Check for a PIC address load. */
8793 31441005 : if ((code == PLUS || code == MINUS)
8794 3711832 : && XEXP (value, 0) == pic_offset_table_rtx
8795 1927 : && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
8796 1927 : || GET_CODE (XEXP (value, 1)) == LABEL_REF
8797 1927 : || GET_CODE (XEXP (value, 1)) == CONST))
8798 : {
8799 184 : if (!subtarget)
8800 184 : subtarget = gen_reg_rtx (GET_MODE (value));
8801 184 : emit_move_insn (subtarget, value);
8802 184 : return subtarget;
8803 : }
8804 :
8805 31440821 : if (ARITHMETIC_P (value))
8806 : {
8807 3824075 : op2 = XEXP (value, 1);
8808 3824075 : if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
8809 3824075 : subtarget = 0;
8810 3824075 : if (code == MINUS && CONST_INT_P (op2))
8811 : {
8812 0 : code = PLUS;
8813 0 : op2 = negate_rtx (GET_MODE (value), op2);
8814 : }
8815 :
8816 : /* Check for an addition with OP2 a constant integer and our first
8817 : operand a PLUS of a virtual register and something else. In that
8818 : case, we want to emit the sum of the virtual register and the
8819 : constant first and then add the other value. This allows virtual
8820 : register instantiation to simply modify the constant rather than
8821 : creating another one around this addition. */
8822 3651634 : if (code == PLUS && CONST_INT_P (op2)
8823 3280569 : && GET_CODE (XEXP (value, 0)) == PLUS
8824 64266 : && REG_P (XEXP (XEXP (value, 0), 0))
8825 3831339 : && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
8826 : {
8827 1132 : rtx temp = expand_simple_binop (GET_MODE (value), code,
8828 : XEXP (XEXP (value, 0), 0), op2,
8829 : subtarget, 0, OPTAB_LIB_WIDEN);
8830 1132 : return expand_simple_binop (GET_MODE (value), code, temp,
8831 1132 : force_operand (XEXP (XEXP (value,
8832 : 0), 1), 0),
8833 1132 : target, 0, OPTAB_LIB_WIDEN);
8834 : }
8835 :
8836 3822943 : op1 = force_operand (XEXP (value, 0), subtarget);
8837 3822943 : op2 = force_operand (op2, NULL_RTX);
8838 3822943 : switch (code)
8839 : {
8840 96686 : case MULT:
8841 96686 : return expand_mult (GET_MODE (value), op1, op2, target, 1);
8842 222 : case DIV:
8843 222 : if (!INTEGRAL_MODE_P (GET_MODE (value)))
8844 222 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8845 222 : target, 1, OPTAB_LIB_WIDEN);
8846 : else
8847 0 : return expand_divmod (0,
8848 : FLOAT_MODE_P (GET_MODE (value))
8849 : ? RDIV_EXPR : TRUNC_DIV_EXPR,
8850 0 : GET_MODE (value), op1, op2, target, 0);
8851 0 : case MOD:
8852 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8853 0 : target, 0);
8854 348 : case UDIV:
8855 348 : return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
8856 348 : target, 1);
8857 0 : case UMOD:
8858 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8859 0 : target, 1);
8860 46 : case ASHIFTRT:
8861 46 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8862 46 : target, 0, OPTAB_LIB_WIDEN);
8863 3725641 : default:
8864 3725641 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8865 3725641 : target, 1, OPTAB_LIB_WIDEN);
8866 : }
8867 : }
8868 27616746 : if (UNARY_P (value))
8869 : {
8870 21740 : if (!target)
8871 11523 : target = gen_reg_rtx (GET_MODE (value));
8872 : /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
8873 : while FIX with floating point mode rounds toward zero. So, some
8874 : targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
8875 : to express rounding toward zero during the conversion to int.
8876 : expand_fix isn't able to handle that, it can only handle
8877 : FIX/UNSIGNED_FIX from floating point mode to integral one. */
8878 21740 : if ((code == FIX || code == UNSIGNED_FIX)
8879 8 : && GET_CODE (XEXP (value, 0)) == FIX
8880 0 : && (GET_MODE (XEXP (value, 0))
8881 0 : == GET_MODE (XEXP (XEXP (value, 0), 0))))
8882 0 : op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
8883 : else
8884 21740 : op1 = force_operand (XEXP (value, 0), NULL_RTX);
8885 21740 : switch (code)
8886 : {
8887 10135 : case ZERO_EXTEND:
8888 10135 : case SIGN_EXTEND:
8889 10135 : case TRUNCATE:
8890 10135 : case FLOAT_EXTEND:
8891 10135 : case FLOAT_TRUNCATE:
8892 10135 : convert_move (target, op1, code == ZERO_EXTEND);
8893 10135 : return target;
8894 :
8895 8 : case FIX:
8896 8 : case UNSIGNED_FIX:
8897 8 : expand_fix (target, op1, code == UNSIGNED_FIX);
8898 8 : return target;
8899 :
8900 120 : case FLOAT:
8901 120 : case UNSIGNED_FLOAT:
8902 120 : expand_float (target, op1, code == UNSIGNED_FLOAT);
8903 120 : return target;
8904 :
8905 11477 : default:
8906 11477 : return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
8907 : }
8908 : }
8909 :
8910 : #ifdef INSN_SCHEDULING
8911 : /* On machines that have insn scheduling, we want all memory reference to be
8912 : explicit, so we need to deal with such paradoxical SUBREGs. */
8913 27595006 : if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
8914 0 : value
8915 0 : = simplify_gen_subreg (GET_MODE (value),
8916 0 : force_reg (GET_MODE (SUBREG_REG (value)),
8917 : force_operand (SUBREG_REG (value),
8918 : NULL_RTX)),
8919 : GET_MODE (SUBREG_REG (value)),
8920 0 : SUBREG_BYTE (value));
8921 : #endif
8922 :
8923 : return value;
8924 : }
8925 :
8926 : /* Subroutine of expand_expr: return true iff there is no way that
8927 : EXP can reference X, which is being modified. TOP_P is nonzero if this
8928 : call is going to be used to determine whether we need a temporary
8929 : for EXP, as opposed to a recursive call to this function.
8930 :
8931 : It is always safe for this routine to return false since it merely
8932 : searches for optimization opportunities. */
8933 :
8934 : bool
8935 8861660 : safe_from_p (const_rtx x, tree exp, int top_p)
8936 : {
8937 8861676 : rtx exp_rtl = 0;
8938 8861676 : int i, nops;
8939 :
8940 8861676 : if (x == 0
8941 : /* If EXP has varying size, we MUST use a target since we currently
8942 : have no way of allocating temporaries of variable size
8943 : (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
8944 : So we assume here that something at a higher level has prevented a
8945 : clash. This is somewhat bogus, but the best we can do. Only
8946 : do this when X is BLKmode and when we are at the top level. */
8947 2015187 : || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
8948 1881023 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
8949 0 : && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
8950 0 : || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
8951 0 : || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
8952 : != INTEGER_CST)
8953 0 : && GET_MODE (x) == BLKmode)
8954 : /* If X is in the outgoing argument area, it is always safe. */
8955 10876863 : || (MEM_P (x)
8956 179758 : && (XEXP (x, 0) == virtual_outgoing_args_rtx
8957 179758 : || (GET_CODE (XEXP (x, 0)) == PLUS
8958 131783 : && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
8959 : return true;
8960 :
8961 : /* If this is a subreg of a hard register, declare it unsafe, otherwise,
8962 : find the underlying pseudo. */
8963 2015187 : if (GET_CODE (x) == SUBREG)
8964 : {
8965 0 : x = SUBREG_REG (x);
8966 0 : if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8967 : return false;
8968 : }
8969 :
8970 : /* Now look at our tree code and possibly recurse. */
8971 2015187 : switch (TREE_CODE_CLASS (TREE_CODE (exp)))
8972 : {
8973 600 : case tcc_declaration:
8974 600 : exp_rtl = DECL_RTL_IF_SET (exp);
8975 : break;
8976 :
8977 : case tcc_constant:
8978 : return true;
8979 :
8980 875291 : case tcc_exceptional:
8981 875291 : if (TREE_CODE (exp) == TREE_LIST)
8982 : {
8983 0 : while (1)
8984 : {
8985 0 : if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
8986 : return false;
8987 0 : exp = TREE_CHAIN (exp);
8988 0 : if (!exp)
8989 : return true;
8990 0 : if (TREE_CODE (exp) != TREE_LIST)
8991 : return safe_from_p (x, exp, 0);
8992 : }
8993 : }
8994 875291 : else if (TREE_CODE (exp) == CONSTRUCTOR)
8995 : {
8996 : constructor_elt *ce;
8997 : unsigned HOST_WIDE_INT idx;
8998 :
8999 8154056 : FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
9000 4932 : if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
9001 133739 : || !safe_from_p (x, ce->value, 0))
9002 106125 : return false;
9003 : return true;
9004 : }
9005 731530 : else if (TREE_CODE (exp) == ERROR_MARK)
9006 : return true; /* An already-visited SAVE_EXPR? */
9007 : else
9008 : return false;
9009 :
9010 0 : case tcc_statement:
9011 : /* The only case we look at here is the DECL_INITIAL inside a
9012 : DECL_EXPR. */
9013 0 : return (TREE_CODE (exp) != DECL_EXPR
9014 0 : || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
9015 0 : || !DECL_INITIAL (DECL_EXPR_DECL (exp))
9016 0 : || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
9017 :
9018 0 : case tcc_binary:
9019 0 : case tcc_comparison:
9020 0 : if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
9021 : return false;
9022 : /* Fall through. */
9023 :
9024 16 : case tcc_unary:
9025 16 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
9026 :
9027 471 : case tcc_expression:
9028 471 : case tcc_reference:
9029 471 : case tcc_vl_exp:
9030 : /* Now do code-specific tests. EXP_RTL is set to any rtx we find in
9031 : the expression. If it is set, we conflict iff we are that rtx or
9032 : both are in memory. Otherwise, we check all operands of the
9033 : expression recursively. */
9034 :
9035 471 : switch (TREE_CODE (exp))
9036 : {
9037 383 : case ADDR_EXPR:
9038 : /* If the operand is static or we are static, we can't conflict.
9039 : Likewise if we don't conflict with the operand at all. */
9040 383 : if (staticp (TREE_OPERAND (exp, 0))
9041 233 : || TREE_STATIC (exp)
9042 616 : || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
9043 383 : return true;
9044 :
9045 : /* Otherwise, the only way this can conflict is if we are taking
9046 : the address of a DECL a that address if part of X, which is
9047 : very rare. */
9048 0 : exp = TREE_OPERAND (exp, 0);
9049 0 : if (DECL_P (exp))
9050 : {
9051 0 : if (!DECL_RTL_SET_P (exp)
9052 0 : || !MEM_P (DECL_RTL (exp)))
9053 0 : return false;
9054 : else
9055 0 : exp_rtl = XEXP (DECL_RTL (exp), 0);
9056 : }
9057 : break;
9058 :
9059 73 : case MEM_REF:
9060 73 : if (MEM_P (x)
9061 73 : && alias_sets_conflict_p (MEM_ALIAS_SET (x),
9062 : get_alias_set (exp)))
9063 : return false;
9064 : break;
9065 :
9066 0 : case CALL_EXPR:
9067 : /* Assume that the call will clobber all hard registers and
9068 : all of memory. */
9069 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
9070 0 : || MEM_P (x))
9071 : return false;
9072 : break;
9073 :
9074 0 : case WITH_CLEANUP_EXPR:
9075 0 : case CLEANUP_POINT_EXPR:
9076 : /* Lowered by gimplify.cc. */
9077 0 : gcc_unreachable ();
9078 :
9079 0 : case SAVE_EXPR:
9080 0 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
9081 :
9082 : default:
9083 : break;
9084 : }
9085 :
9086 : /* If we have an rtx, we do not need to scan our operands. */
9087 0 : if (exp_rtl)
9088 : break;
9089 :
9090 88 : nops = TREE_OPERAND_LENGTH (exp);
9091 371 : for (i = 0; i < nops; i++)
9092 195 : if (TREE_OPERAND (exp, i) != 0
9093 195 : && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
9094 : return false;
9095 :
9096 : break;
9097 :
9098 0 : case tcc_type:
9099 : /* Should never get a type here. */
9100 0 : gcc_unreachable ();
9101 : }
9102 :
9103 : /* If we have an rtl, find any enclosed object. Then see if we conflict
9104 : with it. */
9105 392 : if (exp_rtl)
9106 : {
9107 304 : if (GET_CODE (exp_rtl) == SUBREG)
9108 : {
9109 0 : exp_rtl = SUBREG_REG (exp_rtl);
9110 0 : if (REG_P (exp_rtl)
9111 0 : && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
9112 : return false;
9113 : }
9114 :
9115 : /* If the rtl is X, then it is not safe. Otherwise, it is unless both
9116 : are memory and they conflict. */
9117 304 : return ! (rtx_equal_p (x, exp_rtl)
9118 304 : || (MEM_P (x) && MEM_P (exp_rtl)
9119 4 : && true_dependence (exp_rtl, VOIDmode, x)));
9120 : }
9121 :
9122 : /* If we reach here, it is safe. */
9123 : return true;
9124 : }
9125 :
9126 :
9127 : /* Return the highest power of two that EXP is known to be a multiple of.
9128 : This is used in updating alignment of MEMs in array references. */
9129 :
9130 : unsigned HOST_WIDE_INT
9131 33208475 : highest_pow2_factor (const_tree exp)
9132 : {
9133 33208475 : unsigned HOST_WIDE_INT ret;
9134 33208475 : int trailing_zeros = tree_ctz (exp);
9135 33208475 : if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
9136 45835721 : return BIGGEST_ALIGNMENT;
9137 9947425 : ret = HOST_WIDE_INT_1U << trailing_zeros;
9138 19429159 : if (ret > BIGGEST_ALIGNMENT)
9139 13115454 : return BIGGEST_ALIGNMENT;
9140 : return ret;
9141 : }
9142 :
9143 : /* Similar, except that the alignment requirements of TARGET are
9144 : taken into account. Assume it is at least as aligned as its
9145 : type, unless it is a COMPONENT_REF in which case the layout of
9146 : the structure gives the alignment. */
9147 :
9148 : static unsigned HOST_WIDE_INT
9149 179004 : highest_pow2_factor_for_target (const_tree target, const_tree exp)
9150 : {
9151 179004 : unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
9152 179004 : unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
9153 :
9154 179004 : return MAX (factor, talign);
9155 : }
9156 :
9157 : /* Convert the tree comparison code TCODE to the rtl one where the
9158 : signedness is UNSIGNEDP. */
9159 :
9160 : enum rtx_code
9161 21141 : convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
9162 : {
9163 21141 : enum rtx_code code;
9164 21141 : switch (tcode)
9165 : {
9166 : case EQ_EXPR:
9167 : code = EQ;
9168 : break;
9169 2395 : case NE_EXPR:
9170 2395 : code = NE;
9171 2395 : break;
9172 4086 : case LT_EXPR:
9173 4086 : code = unsignedp ? LTU : LT;
9174 : break;
9175 2716 : case LE_EXPR:
9176 2716 : code = unsignedp ? LEU : LE;
9177 : break;
9178 3185 : case GT_EXPR:
9179 3185 : code = unsignedp ? GTU : GT;
9180 : break;
9181 4371 : case GE_EXPR:
9182 4371 : code = unsignedp ? GEU : GE;
9183 : break;
9184 31 : case UNORDERED_EXPR:
9185 31 : code = UNORDERED;
9186 31 : break;
9187 31 : case ORDERED_EXPR:
9188 31 : code = ORDERED;
9189 31 : break;
9190 10 : case UNLT_EXPR:
9191 10 : code = UNLT;
9192 10 : break;
9193 19 : case UNLE_EXPR:
9194 19 : code = UNLE;
9195 19 : break;
9196 10 : case UNGT_EXPR:
9197 10 : code = UNGT;
9198 10 : break;
9199 11 : case UNGE_EXPR:
9200 11 : code = UNGE;
9201 11 : break;
9202 4 : case UNEQ_EXPR:
9203 4 : code = UNEQ;
9204 4 : break;
9205 4 : case LTGT_EXPR:
9206 4 : code = LTGT;
9207 4 : break;
9208 :
9209 0 : default:
9210 0 : gcc_unreachable ();
9211 : }
9212 21141 : return code;
9213 : }
9214 :
9215 : /* Subroutine of expand_expr. Expand the two operands of a binary
9216 : expression EXP0 and EXP1 placing the results in OP0 and OP1.
9217 : The value may be stored in TARGET if TARGET is nonzero. The
9218 : MODIFIER argument is as documented by expand_expr. */
9219 :
9220 : void
9221 8261224 : expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
9222 : enum expand_modifier modifier)
9223 : {
9224 8261224 : if (! safe_from_p (target, exp1, 1))
9225 608162 : target = 0;
9226 8261224 : if (operand_equal_p (exp0, exp1, 0))
9227 : {
9228 47705 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9229 47705 : *op1 = copy_rtx (*op0);
9230 : }
9231 : else
9232 : {
9233 8213519 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9234 8213519 : *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
9235 : }
9236 8261224 : }
9237 :
9238 :
9239 : /* Return a MEM that contains constant EXP. DEFER is as for
9240 : output_constant_def and MODIFIER is as for expand_expr. */
9241 :
9242 : static rtx
9243 2977933 : expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
9244 : {
9245 2977933 : rtx mem;
9246 :
9247 2977933 : mem = output_constant_def (exp, defer);
9248 2977933 : if (modifier != EXPAND_INITIALIZER)
9249 1902756 : mem = use_anchored_address (mem);
9250 2977933 : return mem;
9251 : }
9252 :
9253 : /* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP.
9254 : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9255 :
9256 : static rtx
9257 14521089 : expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
9258 : enum expand_modifier modifier, addr_space_t as)
9259 : {
9260 14521089 : rtx result, subtarget;
9261 14521089 : tree inner, offset;
9262 14521089 : poly_int64 bitsize, bitpos;
9263 14521089 : int unsignedp, reversep, volatilep = 0;
9264 14521089 : machine_mode mode1;
9265 :
9266 : /* If we are taking the address of a constant and are at the top level,
9267 : we have to use output_constant_def since we can't call force_const_mem
9268 : at top level. */
9269 : /* ??? This should be considered a front-end bug. We should not be
9270 : generating ADDR_EXPR of something that isn't an LVALUE. The only
9271 : exception here is STRING_CST. */
9272 14521089 : if (CONSTANT_CLASS_P (exp))
9273 : {
9274 2717552 : result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
9275 2717552 : if (modifier < EXPAND_SUM)
9276 1812196 : result = force_operand (result, target);
9277 2717552 : return result;
9278 : }
9279 :
9280 : /* Everything must be something allowed by is_gimple_addressable. */
9281 11803537 : switch (TREE_CODE (exp))
9282 : {
9283 46 : case INDIRECT_REF:
9284 : /* This case will happen via recursion for &a->b. */
9285 46 : return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
9286 :
9287 571865 : case MEM_REF:
9288 571865 : {
9289 571865 : tree tem = TREE_OPERAND (exp, 0);
9290 571865 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
9291 299193 : tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
9292 571865 : return expand_expr (tem, target, tmode, modifier);
9293 : }
9294 :
9295 1128 : case TARGET_MEM_REF:
9296 1128 : return addr_for_mem_ref (exp, as, true);
9297 :
9298 59662 : case CONST_DECL:
9299 : /* Expand the initializer like constants above. */
9300 59662 : result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
9301 : 0, modifier), 0);
9302 59662 : if (modifier < EXPAND_SUM)
9303 59656 : result = force_operand (result, target);
9304 : return result;
9305 :
9306 199 : case REALPART_EXPR:
9307 : /* The real part of the complex number is always first, therefore
9308 : the address is the same as the address of the parent object. */
9309 199 : offset = 0;
9310 199 : bitpos = 0;
9311 199 : inner = TREE_OPERAND (exp, 0);
9312 199 : break;
9313 :
9314 116 : case IMAGPART_EXPR:
9315 : /* The imaginary part of the complex number is always second.
9316 : The expression is therefore always offset by the size of the
9317 : scalar type. */
9318 116 : offset = 0;
9319 232 : bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
9320 116 : inner = TREE_OPERAND (exp, 0);
9321 116 : break;
9322 :
9323 13 : case COMPOUND_LITERAL_EXPR:
9324 : /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
9325 : initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
9326 : with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
9327 : array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
9328 : the initializers aren't gimplified. */
9329 13 : if (COMPOUND_LITERAL_EXPR_DECL (exp)
9330 13 : && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
9331 13 : return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
9332 13 : target, tmode, modifier, as);
9333 : /* FALLTHRU */
9334 11170508 : default:
9335 : /* If the object is a DECL, then expand it for its rtl. Don't bypass
9336 : expand_expr, as that can have various side effects; LABEL_DECLs for
9337 : example, may not have their DECL_RTL set yet. Expand the rtl of
9338 : CONSTRUCTORs too, which should yield a memory reference for the
9339 : constructor's contents. Assume language specific tree nodes can
9340 : be expanded in some interesting way. */
9341 11170508 : gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
9342 11170508 : if (DECL_P (exp)
9343 1329488 : || TREE_CODE (exp) == CONSTRUCTOR
9344 1329488 : || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
9345 : {
9346 16170239 : result = expand_expr (exp, target, tmode,
9347 : modifier == EXPAND_INITIALIZER
9348 : ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
9349 :
9350 : /* If the DECL isn't in memory, then the DECL wasn't properly
9351 : marked TREE_ADDRESSABLE, which will be either a front-end
9352 : or a tree optimizer bug. */
9353 :
9354 9841020 : gcc_assert (MEM_P (result));
9355 9841018 : result = XEXP (result, 0);
9356 :
9357 : /* ??? Is this needed anymore? */
9358 9841018 : if (DECL_P (exp))
9359 9841018 : TREE_USED (exp) = 1;
9360 :
9361 9841018 : if (modifier != EXPAND_INITIALIZER
9362 : && modifier != EXPAND_CONST_ADDRESS
9363 9841018 : && modifier != EXPAND_SUM)
9364 4290918 : result = force_operand (result, target);
9365 9841018 : return result;
9366 : }
9367 :
9368 : /* Pass FALSE as the last argument to get_inner_reference although
9369 : we are expanding to RTL. The rationale is that we know how to
9370 : handle "aligning nodes" here: we can just bypass them because
9371 : they won't change the final object whose address will be returned
9372 : (they actually exist only for that purpose). */
9373 1329488 : inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
9374 : &unsignedp, &reversep, &volatilep);
9375 1329488 : break;
9376 : }
9377 :
9378 : /* We must have made progress. */
9379 1329803 : gcc_assert (inner != exp);
9380 :
9381 1329803 : subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
9382 : /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
9383 : inner alignment, force the inner to be sufficiently aligned. */
9384 1329803 : if (CONSTANT_CLASS_P (inner)
9385 1329803 : && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
9386 : {
9387 0 : inner = copy_node (inner);
9388 0 : TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
9389 0 : SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
9390 0 : TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
9391 : }
9392 1329803 : result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
9393 :
9394 1329803 : if (offset)
9395 : {
9396 55370 : rtx tmp;
9397 :
9398 55370 : if (modifier != EXPAND_NORMAL)
9399 1625 : result = force_operand (result, NULL);
9400 56995 : tmp = expand_expr (offset, NULL_RTX, tmode,
9401 : modifier == EXPAND_INITIALIZER
9402 : ? EXPAND_INITIALIZER : EXPAND_NORMAL);
9403 :
9404 : /* expand_expr is allowed to return an object in a mode other
9405 : than TMODE. If it did, we need to convert. */
9406 55370 : if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
9407 0 : tmp = convert_modes (tmode, GET_MODE (tmp),
9408 0 : tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
9409 55370 : result = convert_memory_address_addr_space (tmode, result, as);
9410 55370 : tmp = convert_memory_address_addr_space (tmode, tmp, as);
9411 :
9412 55370 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
9413 1625 : result = simplify_gen_binary (PLUS, tmode, result, tmp);
9414 : else
9415 : {
9416 53745 : subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
9417 53745 : result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
9418 : 1, OPTAB_LIB_WIDEN);
9419 : }
9420 : }
9421 :
9422 1329803 : if (maybe_ne (bitpos, 0))
9423 : {
9424 : /* Someone beforehand should have rejected taking the address
9425 : of an object that isn't byte-aligned. */
9426 629335 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
9427 629335 : result = convert_memory_address_addr_space (tmode, result, as);
9428 629335 : result = plus_constant (tmode, result, bytepos);
9429 629335 : if (modifier < EXPAND_SUM)
9430 591807 : result = force_operand (result, target);
9431 : }
9432 :
9433 : return result;
9434 : }
9435 :
9436 : /* A subroutine of expand_expr. Evaluate EXP, which is an ADDR_EXPR.
9437 : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9438 :
9439 : static rtx
9440 13191271 : expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
9441 : enum expand_modifier modifier)
9442 : {
9443 13191271 : addr_space_t as = ADDR_SPACE_GENERIC;
9444 13191271 : scalar_int_mode address_mode = Pmode;
9445 13191271 : scalar_int_mode pointer_mode = ptr_mode;
9446 13191271 : machine_mode rmode;
9447 13191271 : rtx result;
9448 :
9449 : /* Target mode of VOIDmode says "whatever's natural". */
9450 13191271 : if (tmode == VOIDmode)
9451 11230199 : tmode = TYPE_MODE (TREE_TYPE (exp));
9452 :
9453 13191271 : if (POINTER_TYPE_P (TREE_TYPE (exp)))
9454 : {
9455 13191271 : as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
9456 13191271 : address_mode = targetm.addr_space.address_mode (as);
9457 13191271 : pointer_mode = targetm.addr_space.pointer_mode (as);
9458 : }
9459 :
9460 : /* We can get called with some Weird Things if the user does silliness
9461 : like "(short) &a". In that case, convert_memory_address won't do
9462 : the right thing, so ignore the given target mode. */
9463 13191271 : scalar_int_mode new_tmode = (tmode == pointer_mode
9464 13191271 : ? pointer_mode
9465 13191271 : : address_mode);
9466 :
9467 13191271 : result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
9468 : new_tmode, modifier, as);
9469 :
9470 : /* Despite expand_expr claims concerning ignoring TMODE when not
9471 : strictly convenient, stuff breaks if we don't honor it. Note
9472 : that combined with the above, we only do this for pointer modes. */
9473 13191269 : rmode = GET_MODE (result);
9474 13191269 : if (rmode == VOIDmode)
9475 6 : rmode = new_tmode;
9476 13191269 : if (rmode != new_tmode)
9477 74 : result = convert_memory_address_addr_space (new_tmode, result, as);
9478 :
9479 13191269 : return result;
9480 : }
9481 :
9482 : /* Generate code for computing CONSTRUCTOR EXP.
9483 : An rtx for the computed value is returned. If AVOID_TEMP_MEM
9484 : is TRUE, instead of creating a temporary variable in memory
9485 : NULL is returned and the caller needs to handle it differently. */
9486 :
9487 : static rtx
9488 177381 : expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
9489 : bool avoid_temp_mem)
9490 : {
9491 177381 : tree type = TREE_TYPE (exp);
9492 177381 : machine_mode mode = TYPE_MODE (type);
9493 :
9494 : /* Try to avoid creating a temporary at all. This is possible
9495 : if all of the initializer is zero.
9496 : FIXME: try to handle all [0..255] initializers we can handle
9497 : with memset. */
9498 177381 : if (TREE_STATIC (exp)
9499 2176 : && !TREE_ADDRESSABLE (exp)
9500 2176 : && target != 0 && mode == BLKmode
9501 178466 : && all_zeros_p (exp))
9502 : {
9503 1076 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
9504 1076 : return target;
9505 : }
9506 :
9507 : /* All elts simple constants => refer to a constant in memory. But
9508 : if this is a non-BLKmode mode, let it store a field at a time
9509 : since that should make a CONST_INT, CONST_WIDE_INT or
9510 : CONST_DOUBLE when we fold. Likewise, if we have a target we can
9511 : use, it is best to store directly into the target unless the type
9512 : is large enough that memcpy will be used. If we are making an
9513 : initializer and all operands are constant, put it in memory as
9514 : well.
9515 :
9516 : FIXME: Avoid trying to fill vector constructors piece-meal.
9517 : Output them with output_constant_def below unless we're sure
9518 : they're zeros. This should go away when vector initializers
9519 : are treated like VECTOR_CST instead of arrays. */
9520 176305 : if ((TREE_STATIC (exp)
9521 1100 : && ((mode == BLKmode
9522 46 : && ! (target != 0 && safe_from_p (target, exp, 1)))
9523 1063 : || TREE_ADDRESSABLE (exp)
9524 1063 : || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9525 1063 : && (! can_move_by_pieces
9526 1063 : (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9527 1063 : TYPE_ALIGN (type)))
9528 4 : && ! mostly_zeros_p (exp))))
9529 177366 : || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
9530 0 : && TREE_CONSTANT (exp)))
9531 : {
9532 39 : rtx constructor;
9533 :
9534 39 : if (avoid_temp_mem)
9535 : return NULL_RTX;
9536 :
9537 37 : constructor = expand_expr_constant (exp, 1, modifier);
9538 :
9539 37 : if (modifier != EXPAND_CONST_ADDRESS
9540 : && modifier != EXPAND_INITIALIZER
9541 37 : && modifier != EXPAND_SUM)
9542 37 : constructor = validize_mem (constructor);
9543 :
9544 37 : return constructor;
9545 : }
9546 :
9547 : /* If the CTOR is available in static storage and not mostly
9548 : zeros and we can move it by pieces prefer to do so since
9549 : that's usually more efficient than performing a series of
9550 : stores from immediates. */
9551 176266 : if (avoid_temp_mem
9552 97 : && TREE_STATIC (exp)
9553 38 : && TREE_CONSTANT (exp)
9554 38 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9555 38 : && can_move_by_pieces (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9556 38 : TYPE_ALIGN (type))
9557 176303 : && ! mostly_zeros_p (exp))
9558 : return NULL_RTX;
9559 :
9560 : /* Handle calls that pass values in multiple non-contiguous
9561 : locations. The Irix 6 ABI has examples of this. */
9562 143708 : if (target == 0 || ! safe_from_p (target, exp, 1)
9563 37583 : || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
9564 : /* Also make a temporary if the store is to volatile memory, to
9565 : avoid individual accesses to aggregate members. */
9566 213807 : || (GET_CODE (target) == MEM
9567 33481 : && MEM_VOLATILE_P (target)
9568 134 : && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
9569 : {
9570 138793 : if (avoid_temp_mem)
9571 : return NULL_RTX;
9572 :
9573 138782 : target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
9574 : }
9575 :
9576 176225 : store_constructor (exp, target, 0, int_expr_size (exp), false);
9577 176225 : return target;
9578 : }
9579 :
9580 :
9581 : /* expand_expr: generate code for computing expression EXP.
9582 : An rtx for the computed value is returned. The value is never null.
9583 : In the case of a void EXP, const0_rtx is returned.
9584 :
9585 : The value may be stored in TARGET if TARGET is nonzero.
9586 : TARGET is just a suggestion; callers must assume that
9587 : the rtx returned may not be the same as TARGET.
9588 :
9589 : If TARGET is CONST0_RTX, it means that the value will be ignored.
9590 :
9591 : If TMODE is not VOIDmode, it suggests generating the
9592 : result in mode TMODE. But this is done only when convenient.
9593 : Otherwise, TMODE is ignored and the value generated in its natural mode.
9594 : TMODE is just a suggestion; callers must assume that
9595 : the rtx returned may not have mode TMODE.
9596 :
9597 : Note that TARGET may have neither TMODE nor MODE. In that case, it
9598 : probably will not be used.
9599 :
9600 : If MODIFIER is EXPAND_SUM then when EXP is an addition
9601 : we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
9602 : or a nest of (PLUS ...) and (MINUS ...) where the terms are
9603 : products as above, or REG or MEM, or constant.
9604 : Ordinarily in such cases we would output mul or add instructions
9605 : and then return a pseudo reg containing the sum.
9606 :
9607 : EXPAND_INITIALIZER is much like EXPAND_SUM except that
9608 : it also marks a label as absolutely required (it can't be dead).
9609 : It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
9610 : This is used for outputting expressions used in initializers.
9611 :
9612 : EXPAND_CONST_ADDRESS says that it is okay to return a MEM
9613 : with a constant address even if that address is not normally legitimate.
9614 : EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
9615 :
9616 : EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
9617 : a call parameter. Such targets require special care as we haven't yet
9618 : marked TARGET so that it's safe from being trashed by libcalls. We
9619 : don't want to use TARGET for anything but the final result;
9620 : Intermediate values must go elsewhere. Additionally, calls to
9621 : emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
9622 :
9623 : If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
9624 : address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
9625 : DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
9626 : COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
9627 : recursively.
9628 : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9629 : then *ALT_RTL is set to TARGET (before legitimziation).
9630 :
9631 : If INNER_REFERENCE_P is true, we are expanding an inner reference.
9632 : In this case, we don't adjust a returned MEM rtx that wouldn't be
9633 : sufficiently aligned for its mode; instead, it's up to the caller
9634 : to deal with it afterwards. This is used to make sure that unaligned
9635 : base objects for which out-of-bounds accesses are supported, for
9636 : example record types with trailing arrays, aren't realigned behind
9637 : the back of the caller.
9638 : The normal operating mode is to pass FALSE for this parameter. */
9639 :
9640 : rtx
9641 158139719 : expand_expr_real (tree exp, rtx target, machine_mode tmode,
9642 : enum expand_modifier modifier, rtx *alt_rtl,
9643 : bool inner_reference_p)
9644 : {
9645 158139719 : rtx ret;
9646 :
9647 : /* Handle ERROR_MARK before anybody tries to access its type. */
9648 158139719 : if (TREE_CODE (exp) == ERROR_MARK
9649 158139719 : || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
9650 : {
9651 0 : ret = CONST0_RTX (tmode);
9652 0 : return ret ? ret : const0_rtx;
9653 : }
9654 :
9655 158139719 : ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
9656 : inner_reference_p);
9657 158139719 : return ret;
9658 : }
9659 :
9660 : /* Try to expand the conditional expression which is represented by
9661 : TREEOP0 ? TREEOP1 : TREEOP2 using conditional moves. If it succeeds
9662 : return the rtl reg which represents the result. Otherwise return
9663 : NULL_RTX. */
9664 :
9665 : static rtx
9666 18080 : expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
9667 : tree treeop1 ATTRIBUTE_UNUSED,
9668 : tree treeop2 ATTRIBUTE_UNUSED)
9669 : {
9670 18080 : rtx insn;
9671 18080 : rtx op00, op01, op1, op2;
9672 18080 : enum rtx_code comparison_code;
9673 18080 : machine_mode comparison_mode;
9674 18080 : gimple *srcstmt;
9675 18080 : rtx temp;
9676 18080 : tree type = TREE_TYPE (treeop1);
9677 18080 : int unsignedp = TYPE_UNSIGNED (type);
9678 18080 : machine_mode mode = TYPE_MODE (type);
9679 18080 : machine_mode orig_mode = mode;
9680 18080 : static bool expanding_cond_expr_using_cmove = false;
9681 :
9682 : /* Conditional move expansion can end up TERing two operands which,
9683 : when recursively hitting conditional expressions can result in
9684 : exponential behavior if the cmove expansion ultimatively fails.
9685 : It's hardly profitable to TER a cmove into a cmove so avoid doing
9686 : that by failing early if we end up recursing. */
9687 18080 : if (expanding_cond_expr_using_cmove)
9688 : return NULL_RTX;
9689 :
9690 : /* If we cannot do a conditional move on the mode, try doing it
9691 : with the promoted mode. */
9692 17094 : if (!can_conditionally_move_p (mode))
9693 : {
9694 287 : mode = promote_mode (type, mode, &unsignedp);
9695 287 : if (!can_conditionally_move_p (mode))
9696 : return NULL_RTX;
9697 0 : temp = assign_temp (type, 0, 0); /* Use promoted mode for temp. */
9698 : }
9699 : else
9700 16807 : temp = assign_temp (type, 0, 1);
9701 :
9702 16807 : expanding_cond_expr_using_cmove = true;
9703 16807 : start_sequence ();
9704 16807 : expand_operands (treeop1, treeop2,
9705 : mode == orig_mode ? temp : NULL_RTX, &op1, &op2,
9706 : EXPAND_NORMAL);
9707 :
9708 16807 : if (TREE_CODE (treeop0) == SSA_NAME
9709 16656 : && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))
9710 31232 : && !VECTOR_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (srcstmt))))
9711 : {
9712 14422 : type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
9713 14422 : enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt);
9714 14422 : op00 = expand_normal (gimple_assign_rhs1 (srcstmt));
9715 14422 : op01 = expand_normal (gimple_assign_rhs2 (srcstmt));
9716 14422 : comparison_mode = TYPE_MODE (type);
9717 14422 : unsignedp = TYPE_UNSIGNED (type);
9718 14422 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9719 : }
9720 2385 : else if (COMPARISON_CLASS_P (treeop0)
9721 2385 : && !VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (treeop0, 0))))
9722 : {
9723 151 : type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
9724 151 : enum tree_code cmpcode = TREE_CODE (treeop0);
9725 151 : op00 = expand_normal (TREE_OPERAND (treeop0, 0));
9726 151 : op01 = expand_normal (TREE_OPERAND (treeop0, 1));
9727 151 : unsignedp = TYPE_UNSIGNED (type);
9728 151 : comparison_mode = TYPE_MODE (type);
9729 151 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9730 : }
9731 : else
9732 : {
9733 2234 : op00 = expand_normal (treeop0);
9734 2234 : op01 = const0_rtx;
9735 2234 : comparison_code = NE;
9736 2234 : comparison_mode = GET_MODE (op00);
9737 2234 : if (comparison_mode == VOIDmode)
9738 0 : comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
9739 : }
9740 16807 : expanding_cond_expr_using_cmove = false;
9741 :
9742 16807 : if (GET_MODE (op1) != mode)
9743 2355 : op1 = gen_lowpart (mode, op1);
9744 :
9745 16807 : if (GET_MODE (op2) != mode)
9746 9061 : op2 = gen_lowpart (mode, op2);
9747 :
9748 : /* Try to emit the conditional move. */
9749 16807 : insn = emit_conditional_move (temp,
9750 : { comparison_code, op00, op01,
9751 : comparison_mode },
9752 : op1, op2, mode,
9753 : unsignedp);
9754 :
9755 : /* If we could do the conditional move, emit the sequence,
9756 : and return. */
9757 16807 : if (insn)
9758 : {
9759 14220 : rtx_insn *seq = end_sequence ();
9760 14220 : emit_insn (seq);
9761 14220 : return convert_modes (orig_mode, mode, temp, 0);
9762 : }
9763 :
9764 : /* Otherwise discard the sequence and fall back to code with
9765 : branches. */
9766 2587 : end_sequence ();
9767 2587 : return NULL_RTX;
9768 : }
9769 :
9770 : /* A helper function for expand_expr_real_2 to be used with a
9771 : misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP
9772 : is nonzero, with alignment ALIGN in bits.
9773 : Store the value at TARGET if possible (if TARGET is nonzero).
9774 : Regardless of TARGET, we return the rtx for where the value is placed.
9775 : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9776 : then *ALT_RTL is set to TARGET (before legitimziation). */
9777 :
9778 : static rtx
9779 209361 : expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
9780 : unsigned int align, rtx target, rtx *alt_rtl)
9781 : {
9782 209361 : enum insn_code icode;
9783 :
9784 209361 : if ((icode = optab_handler (movmisalign_optab, mode))
9785 : != CODE_FOR_nothing)
9786 : {
9787 133799 : class expand_operand ops[2];
9788 :
9789 : /* We've already validated the memory, and we're creating a
9790 : new pseudo destination. The predicates really can't fail,
9791 : nor can the generator. */
9792 133799 : create_output_operand (&ops[0], NULL_RTX, mode);
9793 133799 : create_fixed_operand (&ops[1], temp);
9794 133799 : expand_insn (icode, 2, ops);
9795 133799 : temp = ops[0].value;
9796 : }
9797 75562 : else if (targetm.slow_unaligned_access (mode, align))
9798 0 : temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
9799 : 0, unsignedp, target,
9800 : mode, mode, false, alt_rtl);
9801 209361 : return temp;
9802 : }
9803 :
9804 : /* Helper function of expand_expr_2, expand a division or modulo.
9805 : op0 and op1 should be already expanded treeop0 and treeop1, using
9806 : expand_operands. */
9807 :
9808 : static rtx
9809 173050 : expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
9810 : tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
9811 : {
9812 346100 : bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
9813 173050 : || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
9814 173050 : if (SCALAR_INT_MODE_P (mode)
9815 173050 : && optimize >= 2
9816 146154 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1
9817 220226 : && get_range_pos_neg (treeop1, currently_expanding_gimple_stmt) == 1)
9818 : {
9819 : /* If both arguments are known to be positive when interpreted
9820 : as signed, we can expand it as both signed and unsigned
9821 : division or modulo. Choose the cheaper sequence in that case. */
9822 18750 : bool speed_p = optimize_insn_for_speed_p ();
9823 18750 : do_pending_stack_adjust ();
9824 18750 : start_sequence ();
9825 18750 : rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
9826 18750 : rtx_insn *uns_insns = end_sequence ();
9827 18750 : start_sequence ();
9828 18750 : rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
9829 18750 : rtx_insn *sgn_insns = end_sequence ();
9830 18750 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
9831 18750 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
9832 18750 : bool was_tie = false;
9833 :
9834 : /* If costs are the same then use as tie breaker the other other
9835 : factor. */
9836 18750 : if (uns_cost == sgn_cost)
9837 : {
9838 8359 : uns_cost = seq_cost (uns_insns, !speed_p);
9839 8359 : sgn_cost = seq_cost (sgn_insns, !speed_p);
9840 8359 : was_tie = true;
9841 : }
9842 :
9843 18750 : if (dump_file && (dump_flags & TDF_DETAILS))
9844 0 : fprintf (dump_file, ";; positive division:%s unsigned cost: %u; "
9845 : "signed cost: %u\n",
9846 : was_tie ? " (needed tie breaker)" : "", uns_cost, sgn_cost);
9847 :
9848 18750 : if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
9849 : {
9850 11199 : emit_insn (uns_insns);
9851 11199 : return uns_ret;
9852 : }
9853 7551 : emit_insn (sgn_insns);
9854 7551 : return sgn_ret;
9855 : }
9856 154300 : return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
9857 : }
9858 :
9859 : /* Return true if EXP has a range of values [0..1], false
9860 : otherwise. This works for constants and ssa names, calling back into the ranger. */
9861 : static bool
9862 1522562 : expr_has_boolean_range (tree exp, gimple *stmt)
9863 : {
9864 : /* An integral type with a single bit of precision. */
9865 3045111 : if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
9866 1522562 : && TYPE_UNSIGNED (TREE_TYPE (exp))
9867 2533360 : && TYPE_PRECISION (TREE_TYPE (exp)) == 1)
9868 : return true;
9869 :
9870 : /* Signed 1 bit integers are not boolean ranges. */
9871 3045111 : if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
9872 3045111 : || TYPE_PRECISION (TREE_TYPE (exp)) <= 1)
9873 : return false;
9874 :
9875 1522518 : if (TREE_CODE (exp) == SSA_NAME)
9876 902338 : return ssa_name_has_boolean_range (exp, stmt);
9877 620180 : if (TREE_CODE (exp) == INTEGER_CST)
9878 546012 : return wi::leu_p (wi::to_wide (exp), 1);
9879 : return false;
9880 : }
9881 :
9882 : rtx
9883 13548419 : expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
9884 : enum expand_modifier modifier)
9885 : {
9886 13548419 : rtx op0, op1, op2, temp;
9887 13548419 : rtx_code_label *lab;
9888 13548419 : tree type;
9889 13548419 : int unsignedp;
9890 13548419 : machine_mode mode;
9891 13548419 : scalar_int_mode int_mode;
9892 13548419 : enum tree_code code = ops->code;
9893 13548419 : optab this_optab;
9894 13548419 : rtx subtarget, original_target;
9895 13548419 : int ignore;
9896 13548419 : bool reduce_bit_field;
9897 13548419 : location_t loc = ops->location;
9898 13548419 : tree treeop0, treeop1, treeop2;
9899 : #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
9900 : ? reduce_to_bit_field_precision ((expr), \
9901 : target, \
9902 : type) \
9903 : : (expr))
9904 :
9905 13548419 : type = ops->type;
9906 13548419 : mode = TYPE_MODE (type);
9907 13548419 : unsignedp = TYPE_UNSIGNED (type);
9908 :
9909 13548419 : treeop0 = ops->op0;
9910 13548419 : treeop1 = ops->op1;
9911 13548419 : treeop2 = ops->op2;
9912 :
9913 : /* We should be called only on simple (binary or unary) expressions,
9914 : exactly those that are valid in gimple expressions that aren't
9915 : GIMPLE_SINGLE_RHS (or invalid). */
9916 13548419 : gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
9917 : || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
9918 : || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
9919 :
9920 27096838 : ignore = (target == const0_rtx
9921 13548419 : || ((CONVERT_EXPR_CODE_P (code)
9922 9743560 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
9923 3822939 : && TREE_CODE (type) == VOID_TYPE));
9924 :
9925 : /* We should be called only if we need the result. */
9926 0 : gcc_assert (!ignore);
9927 :
9928 : /* An operation in what may be a bit-field type needs the
9929 : result to be reduced to the precision of the bit-field type,
9930 : which is narrower than that of the type's mode. */
9931 27921419 : reduce_bit_field = (INTEGRAL_TYPE_P (type)
9932 13548419 : && !type_has_mode_precision_p (type));
9933 :
9934 824581 : if (reduce_bit_field
9935 824581 : && (modifier == EXPAND_STACK_PARM
9936 824057 : || (target && GET_MODE (target) != mode)))
9937 508015 : target = 0;
9938 :
9939 : /* Use subtarget as the target for operand 0 of a binary operation. */
9940 13548419 : subtarget = get_subtarget (target);
9941 13548419 : original_target = target;
9942 :
9943 13548419 : switch (code)
9944 : {
9945 3808057 : case NON_LVALUE_EXPR:
9946 3808057 : case PAREN_EXPR:
9947 3808057 : CASE_CONVERT:
9948 3808057 : if (treeop0 == error_mark_node)
9949 0 : return const0_rtx;
9950 :
9951 3808057 : if (TREE_CODE (type) == UNION_TYPE)
9952 : {
9953 0 : tree valtype = TREE_TYPE (treeop0);
9954 :
9955 : /* If both input and output are BLKmode, this conversion isn't doing
9956 : anything except possibly changing memory attribute. */
9957 0 : if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
9958 : {
9959 0 : rtx result = expand_expr (treeop0, target, tmode,
9960 : modifier);
9961 :
9962 0 : result = copy_rtx (result);
9963 0 : set_mem_attributes (result, type, 0);
9964 0 : return result;
9965 : }
9966 :
9967 0 : if (target == 0)
9968 : {
9969 0 : if (TYPE_MODE (type) != BLKmode)
9970 0 : target = gen_reg_rtx (TYPE_MODE (type));
9971 : else
9972 0 : target = assign_temp (type, 1, 1);
9973 : }
9974 :
9975 0 : if (MEM_P (target))
9976 : /* Store data into beginning of memory target. */
9977 0 : store_expr (treeop0,
9978 0 : adjust_address (target, TYPE_MODE (valtype), 0),
9979 : modifier == EXPAND_STACK_PARM,
9980 0 : false, TYPE_REVERSE_STORAGE_ORDER (type));
9981 :
9982 : else
9983 : {
9984 0 : gcc_assert (REG_P (target)
9985 : && !TYPE_REVERSE_STORAGE_ORDER (type));
9986 :
9987 : /* Store this field into a union of the proper type. */
9988 0 : poly_uint64 op0_size
9989 0 : = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
9990 0 : poly_uint64 union_size = GET_MODE_BITSIZE (mode);
9991 0 : store_field (target,
9992 : /* The conversion must be constructed so that
9993 : we know at compile time how many bits
9994 : to preserve. */
9995 0 : ordered_min (op0_size, union_size),
9996 0 : 0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
9997 : false, false);
9998 : }
9999 :
10000 : /* Return the entire union. */
10001 0 : return target;
10002 : }
10003 :
10004 3808057 : if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
10005 : {
10006 2262307 : op0 = expand_expr (treeop0, target, VOIDmode,
10007 : modifier);
10008 :
10009 2262307 : return REDUCE_BIT_FIELD (op0);
10010 : }
10011 :
10012 1908088 : op0 = expand_expr (treeop0, NULL_RTX, mode,
10013 : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
10014 1545750 : if (GET_MODE (op0) == mode)
10015 : ;
10016 :
10017 : /* If OP0 is a constant, just convert it into the proper mode. */
10018 1505122 : else if (CONSTANT_P (op0))
10019 : {
10020 908 : tree inner_type = TREE_TYPE (treeop0);
10021 908 : machine_mode inner_mode = GET_MODE (op0);
10022 :
10023 908 : if (inner_mode == VOIDmode)
10024 15 : inner_mode = TYPE_MODE (inner_type);
10025 :
10026 908 : if (modifier == EXPAND_INITIALIZER)
10027 0 : op0 = force_lowpart_subreg (mode, op0, inner_mode);
10028 : else
10029 908 : op0 = convert_modes (mode, inner_mode, op0,
10030 908 : TYPE_UNSIGNED (inner_type));
10031 : }
10032 :
10033 1504214 : else if (modifier == EXPAND_INITIALIZER)
10034 24 : op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
10035 : ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
10036 :
10037 1504202 : else if (SCALAR_INT_MODE_P (GET_MODE (op0))
10038 1330935 : && optimize >= 2
10039 775641 : && SCALAR_INT_MODE_P (mode)
10040 775641 : && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
10041 775438 : && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
10042 1550876 : > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
10043 2049184 : && get_range_pos_neg (treeop0,
10044 : currently_expanding_gimple_stmt) == 1)
10045 : {
10046 : /* If argument is known to be positive when interpreted
10047 : as signed, we can expand it as both sign and zero
10048 : extension. Choose the cheaper sequence in that case. */
10049 140385 : bool speed_p = optimize_insn_for_speed_p ();
10050 140385 : rtx uns_ret = NULL_RTX, sgn_ret = NULL_RTX;
10051 140385 : do_pending_stack_adjust ();
10052 140385 : start_sequence ();
10053 140385 : if (target == NULL_RTX)
10054 116371 : uns_ret = convert_to_mode (mode, op0, 1);
10055 : else
10056 24014 : convert_move (target, op0, 1);
10057 140385 : rtx_insn *uns_insns = end_sequence ();
10058 140385 : start_sequence ();
10059 140385 : if (target == NULL_RTX)
10060 116371 : sgn_ret = convert_to_mode (mode, op0, 0);
10061 : else
10062 24014 : convert_move (target, op0, 0);
10063 140385 : rtx_insn *sgn_insns = end_sequence ();
10064 140385 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
10065 140385 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
10066 140385 : bool was_tie = false;
10067 :
10068 : /* If costs are the same then use as tie breaker the other other
10069 : factor. */
10070 140385 : if (uns_cost == sgn_cost)
10071 : {
10072 38471 : uns_cost = seq_cost (uns_insns, !speed_p);
10073 38471 : sgn_cost = seq_cost (sgn_insns, !speed_p);
10074 38471 : was_tie = true;
10075 : }
10076 :
10077 140385 : if (dump_file && (dump_flags & TDF_DETAILS))
10078 0 : fprintf (dump_file, ";; positive extension:%s unsigned cost: %u; "
10079 : "signed cost: %u\n",
10080 : was_tie ? " (needed tie breaker)" : "",
10081 : uns_cost, sgn_cost);
10082 140385 : if (uns_cost < sgn_cost
10083 140385 : || (uns_cost == sgn_cost && TYPE_UNSIGNED (TREE_TYPE (treeop0))))
10084 : {
10085 125573 : emit_insn (uns_insns);
10086 125573 : sgn_ret = uns_ret;
10087 : }
10088 : else
10089 14812 : emit_insn (sgn_insns);
10090 140385 : if (target == NULL_RTX)
10091 116371 : op0 = sgn_ret;
10092 : else
10093 24014 : op0 = target;
10094 : }
10095 1363817 : else if (target == 0)
10096 863748 : op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10097 : else
10098 : {
10099 500069 : convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10100 500069 : op0 = target;
10101 : }
10102 :
10103 1545750 : return REDUCE_BIT_FIELD (op0);
10104 :
10105 0 : case ADDR_SPACE_CONVERT_EXPR:
10106 0 : {
10107 0 : tree treeop0_type = TREE_TYPE (treeop0);
10108 :
10109 0 : gcc_assert (POINTER_TYPE_P (type));
10110 0 : gcc_assert (POINTER_TYPE_P (treeop0_type));
10111 :
10112 0 : addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
10113 0 : addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
10114 :
10115 : /* Conversions between pointers to the same address space should
10116 : have been implemented via CONVERT_EXPR / NOP_EXPR. */
10117 0 : gcc_assert (as_to != as_from);
10118 :
10119 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
10120 :
10121 : /* Ask target code to handle conversion between pointers
10122 : to overlapping address spaces. */
10123 0 : if (targetm.addr_space.subset_p (as_to, as_from)
10124 0 : || targetm.addr_space.subset_p (as_from, as_to))
10125 : {
10126 0 : op0 = targetm.addr_space.convert (op0, treeop0_type, type);
10127 : }
10128 : else
10129 : {
10130 : /* For disjoint address spaces, converting anything but a null
10131 : pointer invokes undefined behavior. We truncate or extend the
10132 : value as if we'd converted via integers, which handles 0 as
10133 : required, and all others as the programmer likely expects. */
10134 : #ifndef POINTERS_EXTEND_UNSIGNED
10135 : const int POINTERS_EXTEND_UNSIGNED = 1;
10136 : #endif
10137 0 : op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
10138 : op0, POINTERS_EXTEND_UNSIGNED);
10139 : }
10140 0 : gcc_assert (op0);
10141 : return op0;
10142 : }
10143 :
10144 1358001 : case POINTER_PLUS_EXPR:
10145 : /* Even though the sizetype mode and the pointer's mode can be different
10146 : expand is able to handle this correctly and get the correct result out
10147 : of the PLUS_EXPR code. */
10148 : /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
10149 : if sizetype precision is smaller than pointer precision. */
10150 1358001 : if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
10151 0 : treeop1 = fold_convert_loc (loc, type,
10152 : fold_convert_loc (loc, ssizetype,
10153 : treeop1));
10154 : /* If sizetype precision is larger than pointer precision, truncate the
10155 : offset to have matching modes. */
10156 1358001 : else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
10157 0 : treeop1 = fold_convert_loc (loc, type, treeop1);
10158 : /* FALLTHRU */
10159 :
10160 5361693 : case PLUS_EXPR:
10161 : /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
10162 : something else, make sure we add the register to the constant and
10163 : then to the other thing. This case can occur during strength
10164 : reduction and doing it this way will produce better code if the
10165 : frame pointer or argument pointer is eliminated.
10166 :
10167 : fold-const.cc will ensure that the constant is always in the inner
10168 : PLUS_EXPR, so the only case we need to do anything about is if
10169 : sp, ap, or fp is our second argument, in which case we must swap
10170 : the innermost first argument and our second argument. */
10171 :
10172 5361693 : if (TREE_CODE (treeop0) == PLUS_EXPR
10173 6914 : && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
10174 0 : && VAR_P (treeop1)
10175 5361693 : && (DECL_RTL (treeop1) == frame_pointer_rtx
10176 0 : || DECL_RTL (treeop1) == stack_pointer_rtx
10177 0 : || DECL_RTL (treeop1) == arg_pointer_rtx))
10178 : {
10179 0 : gcc_unreachable ();
10180 : }
10181 :
10182 : /* If the result is to be ptr_mode and we are adding an integer to
10183 : something, we might be forming a constant. So try to use
10184 : plus_constant. If it produces a sum and we can't accept it,
10185 : use force_operand. This allows P = &ARR[const] to generate
10186 : efficient code on machines where a SYMBOL_REF is not a valid
10187 : address.
10188 :
10189 : If this is an EXPAND_SUM call, always return the sum. */
10190 5361693 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
10191 5361693 : || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
10192 : {
10193 3500716 : if (modifier == EXPAND_STACK_PARM)
10194 18838 : target = 0;
10195 3500716 : if (TREE_CODE (treeop0) == INTEGER_CST
10196 3501723 : && HWI_COMPUTABLE_MODE_P (mode)
10197 3501727 : && TREE_CONSTANT (treeop1))
10198 : {
10199 4 : rtx constant_part;
10200 4 : HOST_WIDE_INT wc;
10201 4 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
10202 :
10203 4 : op1 = expand_expr (treeop1, subtarget, VOIDmode,
10204 : EXPAND_SUM);
10205 : /* Use wi::shwi to ensure that the constant is
10206 : truncated according to the mode of OP1, then sign extended
10207 : to a HOST_WIDE_INT. Using the constant directly can result
10208 : in non-canonical RTL in a 64x32 cross compile. */
10209 4 : wc = TREE_INT_CST_LOW (treeop0);
10210 4 : constant_part =
10211 4 : immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10212 4 : op1 = plus_constant (mode, op1, INTVAL (constant_part));
10213 4 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10214 1 : op1 = force_operand (op1, target);
10215 4 : return REDUCE_BIT_FIELD (op1);
10216 : }
10217 :
10218 3500712 : else if (TREE_CODE (treeop1) == INTEGER_CST
10219 7444607 : && HWI_COMPUTABLE_MODE_P (mode)
10220 5862840 : && TREE_CONSTANT (treeop0))
10221 : {
10222 279210 : rtx constant_part;
10223 279210 : HOST_WIDE_INT wc;
10224 279210 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
10225 :
10226 487019 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10227 : (modifier == EXPAND_INITIALIZER
10228 : ? EXPAND_INITIALIZER : EXPAND_SUM));
10229 279210 : if (! CONSTANT_P (op0))
10230 : {
10231 6 : op1 = expand_expr (treeop1, NULL_RTX,
10232 : VOIDmode, modifier);
10233 : /* Return a PLUS if modifier says it's OK. */
10234 6 : if (modifier == EXPAND_SUM
10235 : || modifier == EXPAND_INITIALIZER)
10236 6 : return simplify_gen_binary (PLUS, mode, op0, op1);
10237 0 : goto binop2;
10238 : }
10239 : /* Use wi::shwi to ensure that the constant is
10240 : truncated according to the mode of OP1, then sign extended
10241 : to a HOST_WIDE_INT. Using the constant directly can result
10242 : in non-canonical RTL in a 64x32 cross compile. */
10243 279204 : wc = TREE_INT_CST_LOW (treeop1);
10244 279204 : constant_part
10245 279204 : = immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10246 279204 : op0 = plus_constant (mode, op0, INTVAL (constant_part));
10247 279204 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10248 206985 : op0 = force_operand (op0, target);
10249 279204 : return REDUCE_BIT_FIELD (op0);
10250 : }
10251 : }
10252 :
10253 : /* Use TER to expand pointer addition of a negated value
10254 : as pointer subtraction. */
10255 9105172 : if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
10256 4003679 : || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
10257 81153 : && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
10258 1078800 : && TREE_CODE (treeop1) == SSA_NAME
10259 6208217 : && TYPE_MODE (TREE_TYPE (treeop0))
10260 562869 : == TYPE_MODE (TREE_TYPE (treeop1)))
10261 : {
10262 562869 : gimple *def = get_def_for_expr (treeop1, NEGATE_EXPR);
10263 562869 : if (def)
10264 : {
10265 2136 : treeop1 = gimple_assign_rhs1 (def);
10266 2136 : code = MINUS_EXPR;
10267 2136 : goto do_minus;
10268 : }
10269 : }
10270 :
10271 : /* No sense saving up arithmetic to be done
10272 : if it's all in the wrong mode to form part of an address.
10273 : And force_operand won't know whether to sign-extend or
10274 : zero-extend. */
10275 5080343 : if (modifier != EXPAND_INITIALIZER
10276 5080343 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10277 : {
10278 4506157 : expand_operands (treeop0, treeop1,
10279 : subtarget, &op0, &op1, modifier);
10280 4506157 : if (op0 == const0_rtx)
10281 8670 : return op1;
10282 4497487 : if (op1 == const0_rtx)
10283 : return op0;
10284 4497236 : goto binop2;
10285 : }
10286 :
10287 574186 : expand_operands (treeop0, treeop1,
10288 : subtarget, &op0, &op1, modifier);
10289 574186 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10290 :
10291 540004 : case MINUS_EXPR:
10292 540004 : case POINTER_DIFF_EXPR:
10293 540004 : do_minus:
10294 : /* For initializers, we are allowed to return a MINUS of two
10295 : symbolic constants. Here we handle all cases when both operands
10296 : are constant. */
10297 : /* Handle difference of two symbolic constants,
10298 : for the sake of an initializer. */
10299 540004 : if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
10300 2657 : && really_constant_p (treeop0)
10301 540515 : && really_constant_p (treeop1))
10302 : {
10303 68 : expand_operands (treeop0, treeop1,
10304 : NULL_RTX, &op0, &op1, modifier);
10305 68 : return simplify_gen_binary (MINUS, mode, op0, op1);
10306 : }
10307 :
10308 : /* No sense saving up arithmetic to be done
10309 : if it's all in the wrong mode to form part of an address.
10310 : And force_operand won't know whether to sign-extend or
10311 : zero-extend. */
10312 539936 : if (modifier != EXPAND_INITIALIZER
10313 539936 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10314 537347 : goto binop;
10315 :
10316 2589 : expand_operands (treeop0, treeop1,
10317 : subtarget, &op0, &op1, modifier);
10318 :
10319 : /* Convert A - const to A + (-const). */
10320 2589 : if (CONST_INT_P (op1))
10321 : {
10322 0 : op1 = negate_rtx (mode, op1);
10323 0 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10324 : }
10325 :
10326 2589 : goto binop2;
10327 :
10328 0 : case WIDEN_MULT_PLUS_EXPR:
10329 0 : case WIDEN_MULT_MINUS_EXPR:
10330 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
10331 0 : op2 = expand_normal (treeop2);
10332 0 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
10333 : target, unsignedp);
10334 0 : return target;
10335 :
10336 18516 : case WIDEN_MULT_EXPR:
10337 : /* If first operand is constant, swap them.
10338 : Thus the following special case checks need only
10339 : check the second operand. */
10340 18516 : if (TREE_CODE (treeop0) == INTEGER_CST)
10341 368 : std::swap (treeop0, treeop1);
10342 :
10343 : /* First, check if we have a multiplication of one signed and one
10344 : unsigned operand. */
10345 18516 : if (TREE_CODE (treeop1) != INTEGER_CST
10346 18516 : && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
10347 14262 : != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
10348 : {
10349 0 : machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
10350 0 : this_optab = usmul_widen_optab;
10351 0 : if (find_widening_optab_handler (this_optab, mode, innermode)
10352 : != CODE_FOR_nothing)
10353 : {
10354 0 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10355 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10356 : EXPAND_NORMAL);
10357 : else
10358 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
10359 : EXPAND_NORMAL);
10360 : /* op0 and op1 might still be constant, despite the above
10361 : != INTEGER_CST check. Handle it. */
10362 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10363 : {
10364 0 : op0 = convert_modes (mode, innermode, op0, true);
10365 0 : op1 = convert_modes (mode, innermode, op1, false);
10366 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10367 : target, unsignedp));
10368 : }
10369 0 : goto binop3;
10370 : }
10371 : }
10372 : /* Check for a multiplication with matching signedness. */
10373 18516 : else if ((TREE_CODE (treeop1) == INTEGER_CST
10374 4254 : && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
10375 18520 : || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
10376 14266 : == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
10377 : {
10378 18516 : tree op0type = TREE_TYPE (treeop0);
10379 18516 : machine_mode innermode = TYPE_MODE (op0type);
10380 18516 : bool zextend_p = TYPE_UNSIGNED (op0type);
10381 18516 : optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
10382 2614 : this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
10383 :
10384 18516 : if (TREE_CODE (treeop0) != INTEGER_CST)
10385 : {
10386 18516 : if (find_widening_optab_handler (this_optab, mode, innermode)
10387 : != CODE_FOR_nothing)
10388 : {
10389 18516 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10390 : EXPAND_NORMAL);
10391 : /* op0 and op1 might still be constant, despite the above
10392 : != INTEGER_CST check. Handle it. */
10393 18516 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10394 : {
10395 0 : widen_mult_const:
10396 0 : op0 = convert_modes (mode, innermode, op0, zextend_p);
10397 0 : op1
10398 0 : = convert_modes (mode, innermode, op1,
10399 0 : TYPE_UNSIGNED (TREE_TYPE (treeop1)));
10400 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10401 : target,
10402 : unsignedp));
10403 : }
10404 18516 : temp = expand_widening_mult (mode, op0, op1, target,
10405 : unsignedp, this_optab);
10406 18516 : return REDUCE_BIT_FIELD (temp);
10407 : }
10408 0 : if (find_widening_optab_handler (other_optab, mode, innermode)
10409 : != CODE_FOR_nothing
10410 0 : && innermode == word_mode)
10411 : {
10412 0 : rtx htem, hipart;
10413 0 : op0 = expand_normal (treeop0);
10414 0 : op1 = expand_normal (treeop1);
10415 : /* op0 and op1 might be constants, despite the above
10416 : != INTEGER_CST check. Handle it. */
10417 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10418 0 : goto widen_mult_const;
10419 0 : temp = expand_binop (mode, other_optab, op0, op1, target,
10420 : unsignedp, OPTAB_LIB_WIDEN);
10421 0 : hipart = gen_highpart (word_mode, temp);
10422 0 : htem = expand_mult_highpart_adjust (word_mode, hipart,
10423 : op0, op1, hipart,
10424 : zextend_p);
10425 0 : if (htem != hipart)
10426 0 : emit_move_insn (hipart, htem);
10427 0 : return REDUCE_BIT_FIELD (temp);
10428 : }
10429 : }
10430 : }
10431 0 : treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
10432 0 : treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
10433 0 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10434 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10435 :
10436 1423324 : case MULT_EXPR:
10437 : /* If this is a fixed-point operation, then we cannot use the code
10438 : below because "expand_mult" doesn't support sat/no-sat fixed-point
10439 : multiplications. */
10440 1423324 : if (ALL_FIXED_POINT_MODE_P (mode))
10441 0 : goto binop;
10442 :
10443 : /* If first operand is constant, swap them.
10444 : Thus the following special case checks need only
10445 : check the second operand. */
10446 1423324 : if (TREE_CODE (treeop0) == INTEGER_CST)
10447 686 : std::swap (treeop0, treeop1);
10448 :
10449 : /* Attempt to return something suitable for generating an
10450 : indexed address, for machines that support that. */
10451 :
10452 536039 : if (modifier == EXPAND_SUM && mode == ptr_mode
10453 1959363 : && tree_fits_shwi_p (treeop1))
10454 : {
10455 528674 : tree exp1 = treeop1;
10456 :
10457 528674 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10458 : EXPAND_SUM);
10459 :
10460 528674 : if (!REG_P (op0))
10461 244752 : op0 = force_operand (op0, NULL_RTX);
10462 528674 : if (!REG_P (op0))
10463 2344 : op0 = copy_to_mode_reg (mode, op0);
10464 :
10465 528674 : op1 = gen_int_mode (tree_to_shwi (exp1),
10466 528674 : TYPE_MODE (TREE_TYPE (exp1)));
10467 528674 : return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
10468 : }
10469 :
10470 894650 : if (modifier == EXPAND_STACK_PARM)
10471 2963 : target = 0;
10472 :
10473 894650 : if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
10474 : {
10475 540713 : gimple *def_stmt0 = get_def_for_expr (treeop0, TRUNC_DIV_EXPR);
10476 540713 : gimple *def_stmt1 = get_def_for_expr (treeop1, TRUNC_DIV_EXPR);
10477 540713 : if (def_stmt0
10478 540713 : && !operand_equal_p (treeop1, gimple_assign_rhs2 (def_stmt0), 0))
10479 : def_stmt0 = NULL;
10480 540713 : if (def_stmt1
10481 540713 : && !operand_equal_p (treeop0, gimple_assign_rhs2 (def_stmt1), 0))
10482 : def_stmt1 = NULL;
10483 :
10484 540713 : if (def_stmt0 || def_stmt1)
10485 : {
10486 : /* X / Y * Y can be expanded as X - X % Y too.
10487 : Choose the cheaper sequence of those two. */
10488 250 : if (def_stmt0)
10489 250 : treeop0 = gimple_assign_rhs1 (def_stmt0);
10490 : else
10491 : {
10492 0 : treeop1 = treeop0;
10493 0 : treeop0 = gimple_assign_rhs1 (def_stmt1);
10494 : }
10495 250 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
10496 : EXPAND_NORMAL);
10497 250 : bool speed_p = optimize_insn_for_speed_p ();
10498 250 : do_pending_stack_adjust ();
10499 250 : start_sequence ();
10500 250 : rtx divmul_ret
10501 250 : = expand_expr_divmod (TRUNC_DIV_EXPR, mode, treeop0, treeop1,
10502 : op0, op1, NULL_RTX, unsignedp);
10503 250 : divmul_ret = expand_mult (mode, divmul_ret, op1, target,
10504 : unsignedp);
10505 250 : rtx_insn *divmul_insns = end_sequence ();
10506 250 : start_sequence ();
10507 250 : rtx modsub_ret
10508 250 : = expand_expr_divmod (TRUNC_MOD_EXPR, mode, treeop0, treeop1,
10509 : op0, op1, NULL_RTX, unsignedp);
10510 250 : this_optab = optab_for_tree_code (MINUS_EXPR, type,
10511 : optab_default);
10512 250 : modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
10513 : target, unsignedp, OPTAB_LIB_WIDEN);
10514 250 : rtx_insn *modsub_insns = end_sequence ();
10515 250 : unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
10516 250 : unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
10517 : /* If costs are the same then use as tie breaker the other other
10518 : factor. */
10519 250 : if (divmul_cost == modsub_cost)
10520 : {
10521 22 : divmul_cost = seq_cost (divmul_insns, !speed_p);
10522 22 : modsub_cost = seq_cost (modsub_insns, !speed_p);
10523 : }
10524 :
10525 250 : if (divmul_cost <= modsub_cost)
10526 : {
10527 176 : emit_insn (divmul_insns);
10528 176 : return REDUCE_BIT_FIELD (divmul_ret);
10529 : }
10530 74 : emit_insn (modsub_insns);
10531 74 : return REDUCE_BIT_FIELD (modsub_ret);
10532 : }
10533 : }
10534 :
10535 894400 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10536 :
10537 : /* Expand X*Y as X&-Y when Y must be zero or one. */
10538 894400 : if (SCALAR_INT_MODE_P (mode))
10539 : {
10540 761281 : bool bit0_p = expr_has_boolean_range (treeop0, currently_expanding_gimple_stmt);
10541 761281 : bool bit1_p = expr_has_boolean_range (treeop1, currently_expanding_gimple_stmt);
10542 :
10543 : /* Expand X*Y as X&Y when both X and Y must be zero or one. */
10544 761281 : if (bit0_p && bit1_p)
10545 0 : return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
10546 :
10547 761281 : if (bit0_p || bit1_p)
10548 : {
10549 4006 : bool speed = optimize_insn_for_speed_p ();
10550 4006 : int cost = add_cost (speed, mode) + neg_cost (speed, mode);
10551 4006 : struct algorithm algorithm;
10552 4006 : enum mult_variant variant;
10553 4006 : if (CONST_INT_P (op1)
10554 4006 : ? !choose_mult_variant (mode, INTVAL (op1),
10555 : &algorithm, &variant, cost)
10556 625 : : cost < mul_cost (speed, mode))
10557 : {
10558 1970 : temp = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
10559 : op1, target)
10560 244 : : expand_and (mode, op0,
10561 : negate_rtx (mode, op1),
10562 : target);
10563 1970 : return REDUCE_BIT_FIELD (temp);
10564 : }
10565 : }
10566 : }
10567 :
10568 892430 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10569 :
10570 172550 : case TRUNC_MOD_EXPR:
10571 172550 : case FLOOR_MOD_EXPR:
10572 172550 : case CEIL_MOD_EXPR:
10573 172550 : case ROUND_MOD_EXPR:
10574 :
10575 172550 : case TRUNC_DIV_EXPR:
10576 172550 : case FLOOR_DIV_EXPR:
10577 172550 : case CEIL_DIV_EXPR:
10578 172550 : case ROUND_DIV_EXPR:
10579 172550 : case EXACT_DIV_EXPR:
10580 : /* If this is a fixed-point operation, then we cannot use the code
10581 : below because "expand_divmod" doesn't support sat/no-sat fixed-point
10582 : divisions. */
10583 172550 : if (ALL_FIXED_POINT_MODE_P (mode))
10584 0 : goto binop;
10585 :
10586 172550 : if (modifier == EXPAND_STACK_PARM)
10587 325 : target = 0;
10588 : /* Possible optimization: compute the dividend with EXPAND_SUM
10589 : then if the divisor is constant can optimize the case
10590 : where some terms of the dividend have coeffs divisible by it. */
10591 172550 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10592 172550 : return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
10593 172550 : target, unsignedp);
10594 :
10595 31200 : case RDIV_EXPR:
10596 31200 : goto binop;
10597 :
10598 1771 : case MULT_HIGHPART_EXPR:
10599 1771 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10600 1771 : temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
10601 1771 : gcc_assert (temp);
10602 : return temp;
10603 :
10604 0 : case FIXED_CONVERT_EXPR:
10605 0 : op0 = expand_normal (treeop0);
10606 0 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10607 0 : target = gen_reg_rtx (mode);
10608 :
10609 0 : if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
10610 0 : && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10611 0 : || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
10612 0 : expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
10613 : else
10614 0 : expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
10615 : return target;
10616 :
10617 48095 : case FIX_TRUNC_EXPR:
10618 48095 : op0 = expand_normal (treeop0);
10619 48095 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10620 3202 : target = gen_reg_rtx (mode);
10621 48095 : expand_fix (target, op0, unsignedp);
10622 48095 : return target;
10623 :
10624 133489 : case FLOAT_EXPR:
10625 133489 : op0 = expand_normal (treeop0);
10626 133489 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10627 63033 : target = gen_reg_rtx (mode);
10628 : /* expand_float can't figure out what to do if FROM has VOIDmode.
10629 : So give it the correct mode. With -O, cse will optimize this. */
10630 133489 : if (GET_MODE (op0) == VOIDmode)
10631 109 : op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
10632 : op0);
10633 266978 : expand_float (target, op0,
10634 133489 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10635 133489 : return target;
10636 :
10637 59546 : case NEGATE_EXPR:
10638 59546 : op0 = expand_expr (treeop0, subtarget,
10639 : VOIDmode, EXPAND_NORMAL);
10640 59546 : if (modifier == EXPAND_STACK_PARM)
10641 241 : target = 0;
10642 59546 : temp = expand_unop (mode,
10643 : optab_for_tree_code (NEGATE_EXPR, type,
10644 : optab_default),
10645 : op0, target, 0);
10646 59546 : gcc_assert (temp);
10647 59546 : return REDUCE_BIT_FIELD (temp);
10648 :
10649 27252 : case ABS_EXPR:
10650 27252 : case ABSU_EXPR:
10651 27252 : op0 = expand_expr (treeop0, subtarget,
10652 : VOIDmode, EXPAND_NORMAL);
10653 27252 : if (modifier == EXPAND_STACK_PARM)
10654 63 : target = 0;
10655 :
10656 : /* ABS_EXPR is not valid for complex arguments. */
10657 27252 : gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
10658 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
10659 :
10660 : /* Unsigned abs is simply the operand. Testing here means we don't
10661 : risk generating incorrect code below. */
10662 27252 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10663 : return op0;
10664 :
10665 27252 : return expand_abs (mode, op0, target, unsignedp,
10666 54504 : safe_from_p (target, treeop0, 1));
10667 :
10668 134552 : case MAX_EXPR:
10669 134552 : case MIN_EXPR:
10670 134552 : target = original_target;
10671 134552 : if (target == 0
10672 134552 : || modifier == EXPAND_STACK_PARM
10673 69985 : || (MEM_P (target) && MEM_VOLATILE_P (target))
10674 69985 : || GET_MODE (target) != mode
10675 204537 : || (REG_P (target)
10676 63376 : && REGNO (target) < FIRST_PSEUDO_REGISTER))
10677 64567 : target = gen_reg_rtx (mode);
10678 134552 : expand_operands (treeop0, treeop1,
10679 : target, &op0, &op1, EXPAND_NORMAL);
10680 :
10681 : /* First try to do it with a special MIN or MAX instruction.
10682 : If that does not win, use a conditional jump to select the proper
10683 : value. */
10684 134552 : this_optab = optab_for_tree_code (code, type, optab_default);
10685 134552 : temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
10686 : OPTAB_WIDEN);
10687 134552 : if (temp != 0)
10688 : return temp;
10689 :
10690 122 : if (VECTOR_TYPE_P (type))
10691 0 : gcc_unreachable ();
10692 :
10693 : /* At this point, a MEM target is no longer useful; we will get better
10694 : code without it. */
10695 :
10696 122 : if (! REG_P (target))
10697 1 : target = gen_reg_rtx (mode);
10698 :
10699 : /* If op1 was placed in target, swap op0 and op1. */
10700 122 : if (target != op0 && target == op1)
10701 0 : std::swap (op0, op1);
10702 :
10703 : /* We generate better code and avoid problems with op1 mentioning
10704 : target by forcing op1 into a pseudo if it isn't a constant. */
10705 122 : if (! CONSTANT_P (op1))
10706 42 : op1 = force_reg (mode, op1);
10707 :
10708 122 : {
10709 122 : enum rtx_code comparison_code;
10710 122 : rtx cmpop1 = op1;
10711 :
10712 122 : if (code == MAX_EXPR)
10713 62 : comparison_code = unsignedp ? GEU : GE;
10714 : else
10715 60 : comparison_code = unsignedp ? LEU : LE;
10716 :
10717 : /* Canonicalize to comparisons against 0. */
10718 122 : if (op1 == const1_rtx)
10719 : {
10720 : /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
10721 : or (a != 0 ? a : 1) for unsigned.
10722 : For MIN we are safe converting (a <= 1 ? a : 1)
10723 : into (a <= 0 ? a : 1) */
10724 0 : cmpop1 = const0_rtx;
10725 0 : if (code == MAX_EXPR)
10726 0 : comparison_code = unsignedp ? NE : GT;
10727 : }
10728 122 : if (op1 == constm1_rtx && !unsignedp)
10729 : {
10730 : /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
10731 : and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
10732 0 : cmpop1 = const0_rtx;
10733 0 : if (code == MIN_EXPR)
10734 0 : comparison_code = LT;
10735 : }
10736 :
10737 : /* Use a conditional move if possible. */
10738 122 : if (can_conditionally_move_p (mode))
10739 : {
10740 75 : rtx insn;
10741 :
10742 75 : start_sequence ();
10743 :
10744 : /* Try to emit the conditional move. */
10745 75 : insn = emit_conditional_move (target,
10746 : { comparison_code,
10747 : op0, cmpop1, mode },
10748 : op0, op1, mode,
10749 : unsignedp);
10750 :
10751 : /* If we could do the conditional move, emit the sequence,
10752 : and return. */
10753 75 : if (insn)
10754 : {
10755 41 : rtx_insn *seq = end_sequence ();
10756 41 : emit_insn (seq);
10757 41 : return target;
10758 : }
10759 :
10760 : /* Otherwise discard the sequence and fall back to code with
10761 : branches. */
10762 34 : end_sequence ();
10763 : }
10764 :
10765 81 : if (target != op0)
10766 52 : emit_move_insn (target, op0);
10767 :
10768 81 : lab = gen_label_rtx ();
10769 81 : do_compare_rtx_and_jump (target, cmpop1, comparison_code,
10770 : unsignedp, mode, NULL_RTX, NULL, lab,
10771 : profile_probability::uninitialized ());
10772 : }
10773 81 : emit_move_insn (target, op1);
10774 81 : emit_label (lab);
10775 81 : return target;
10776 :
10777 62395 : case BIT_NOT_EXPR:
10778 62395 : op0 = expand_expr (treeop0, subtarget,
10779 : VOIDmode, EXPAND_NORMAL);
10780 62395 : if (modifier == EXPAND_STACK_PARM)
10781 88 : target = 0;
10782 : /* In case we have to reduce the result to bitfield precision
10783 : for unsigned bitfield expand this as XOR with a proper constant
10784 : instead. */
10785 62395 : if (reduce_bit_field && TYPE_UNSIGNED (type))
10786 : {
10787 22989 : int_mode = SCALAR_INT_TYPE_MODE (type);
10788 22989 : wide_int mask = wi::mask (TYPE_PRECISION (type),
10789 45978 : false, GET_MODE_PRECISION (int_mode));
10790 :
10791 45978 : temp = expand_binop (int_mode, xor_optab, op0,
10792 45978 : immed_wide_int_const (mask, int_mode),
10793 : target, 1, OPTAB_LIB_WIDEN);
10794 22989 : }
10795 : else
10796 39406 : temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
10797 62395 : gcc_assert (temp);
10798 : return temp;
10799 :
10800 : /* ??? Can optimize bitwise operations with one arg constant.
10801 : Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
10802 : and (a bitwise1 b) bitwise2 b (etc)
10803 : but that is probably not worth while. */
10804 :
10805 615510 : case BIT_AND_EXPR:
10806 615510 : case BIT_IOR_EXPR:
10807 615510 : case BIT_XOR_EXPR:
10808 615510 : goto binop;
10809 :
10810 8423 : case LROTATE_EXPR:
10811 8423 : case RROTATE_EXPR:
10812 8423 : gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
10813 : || type_has_mode_precision_p (type));
10814 : /* fall through */
10815 :
10816 293034 : case LSHIFT_EXPR:
10817 293034 : case RSHIFT_EXPR:
10818 293034 : {
10819 : /* If this is a fixed-point operation, then we cannot use the code
10820 : below because "expand_shift" doesn't support sat/no-sat fixed-point
10821 : shifts. */
10822 293034 : if (ALL_FIXED_POINT_MODE_P (mode))
10823 0 : goto binop;
10824 :
10825 293034 : if (! safe_from_p (subtarget, treeop1, 1))
10826 4972 : subtarget = 0;
10827 293034 : if (modifier == EXPAND_STACK_PARM)
10828 2580 : target = 0;
10829 293034 : op0 = expand_expr (treeop0, subtarget,
10830 : VOIDmode, EXPAND_NORMAL);
10831 :
10832 : /* Left shift optimization when shifting across word_size boundary.
10833 :
10834 : If mode == GET_MODE_WIDER_MODE (word_mode), then normally
10835 : there isn't native instruction to support this wide mode
10836 : left shift. Given below scenario:
10837 :
10838 : Type A = (Type) B << C
10839 :
10840 : |< T >|
10841 : | dest_high | dest_low |
10842 :
10843 : | word_size |
10844 :
10845 : If the shift amount C caused we shift B to across the word
10846 : size boundary, i.e part of B shifted into high half of
10847 : destination register, and part of B remains in the low
10848 : half, then GCC will use the following left shift expand
10849 : logic:
10850 :
10851 : 1. Initialize dest_low to B.
10852 : 2. Initialize every bit of dest_high to the sign bit of B.
10853 : 3. Logic left shift dest_low by C bit to finalize dest_low.
10854 : The value of dest_low before this shift is kept in a temp D.
10855 : 4. Logic left shift dest_high by C.
10856 : 5. Logic right shift D by (word_size - C).
10857 : 6. Or the result of 4 and 5 to finalize dest_high.
10858 :
10859 : While, by checking gimple statements, if operand B is
10860 : coming from signed extension, then we can simplify above
10861 : expand logic into:
10862 :
10863 : 1. dest_high = src_low >> (word_size - C).
10864 : 2. dest_low = src_low << C.
10865 :
10866 : We can use one arithmetic right shift to finish all the
10867 : purpose of steps 2, 4, 5, 6, thus we reduce the steps
10868 : needed from 6 into 2.
10869 :
10870 : The case is similar for zero extension, except that we
10871 : initialize dest_high to zero rather than copies of the sign
10872 : bit from B. Furthermore, we need to use a logical right shift
10873 : in this case.
10874 :
10875 : The choice of sign-extension versus zero-extension is
10876 : determined entirely by whether or not B is signed and is
10877 : independent of the current setting of unsignedp. */
10878 :
10879 293034 : temp = NULL_RTX;
10880 293034 : if (code == LSHIFT_EXPR
10881 293034 : && target
10882 33144 : && REG_P (target)
10883 323153 : && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
10884 30186 : && mode == int_mode
10885 1491 : && TREE_CONSTANT (treeop1)
10886 293865 : && TREE_CODE (treeop0) == SSA_NAME)
10887 : {
10888 831 : gimple *def = SSA_NAME_DEF_STMT (treeop0);
10889 831 : if (is_gimple_assign (def)
10890 831 : && gimple_assign_rhs_code (def) == NOP_EXPR)
10891 : {
10892 327 : scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
10893 : (TREE_TYPE (gimple_assign_rhs1 (def)));
10894 :
10895 654 : if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
10896 608 : && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
10897 469 : && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
10898 71 : >= GET_MODE_BITSIZE (word_mode)))
10899 : {
10900 67 : rtx_insn *seq, *seq_old;
10901 67 : poly_uint64 high_off = subreg_highpart_offset (word_mode,
10902 : int_mode);
10903 67 : bool extend_unsigned
10904 67 : = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
10905 67 : rtx low = lowpart_subreg (word_mode, op0, int_mode);
10906 67 : rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
10907 67 : rtx dest_high = simplify_gen_subreg (word_mode, target,
10908 : int_mode, high_off);
10909 67 : HOST_WIDE_INT ramount = (BITS_PER_WORD
10910 67 : - TREE_INT_CST_LOW (treeop1));
10911 67 : tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
10912 :
10913 67 : start_sequence ();
10914 : /* dest_high = src_low >> (word_size - C). */
10915 67 : temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
10916 : rshift, dest_high,
10917 : extend_unsigned);
10918 67 : if (temp != dest_high)
10919 0 : emit_move_insn (dest_high, temp);
10920 :
10921 : /* dest_low = src_low << C. */
10922 67 : temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
10923 : treeop1, dest_low, unsignedp);
10924 67 : if (temp != dest_low)
10925 2 : emit_move_insn (dest_low, temp);
10926 :
10927 67 : seq = end_sequence ();
10928 67 : temp = target ;
10929 :
10930 67 : if (have_insn_for (ASHIFT, int_mode))
10931 : {
10932 67 : bool speed_p = optimize_insn_for_speed_p ();
10933 67 : start_sequence ();
10934 67 : rtx ret_old = expand_variable_shift (code, int_mode,
10935 : op0, treeop1,
10936 : target,
10937 : unsignedp);
10938 :
10939 67 : seq_old = end_sequence ();
10940 134 : if (seq_cost (seq, speed_p)
10941 67 : >= seq_cost (seq_old, speed_p))
10942 : {
10943 67 : seq = seq_old;
10944 67 : temp = ret_old;
10945 : }
10946 : }
10947 67 : emit_insn (seq);
10948 : }
10949 : }
10950 : }
10951 :
10952 67 : if (temp == NULL_RTX)
10953 292967 : temp = expand_variable_shift (code, mode, op0, treeop1, target,
10954 : unsignedp);
10955 293034 : if (code == LSHIFT_EXPR)
10956 77991 : temp = REDUCE_BIT_FIELD (temp);
10957 : return temp;
10958 : }
10959 :
10960 : /* Could determine the answer when only additive constants differ. Also,
10961 : the addition of one can be handled by changing the condition. */
10962 637470 : case LT_EXPR:
10963 637470 : case LE_EXPR:
10964 637470 : case GT_EXPR:
10965 637470 : case GE_EXPR:
10966 637470 : case EQ_EXPR:
10967 637470 : case NE_EXPR:
10968 637470 : case UNORDERED_EXPR:
10969 637470 : case ORDERED_EXPR:
10970 637470 : case UNLT_EXPR:
10971 637470 : case UNLE_EXPR:
10972 637470 : case UNGT_EXPR:
10973 637470 : case UNGE_EXPR:
10974 637470 : case UNEQ_EXPR:
10975 637470 : case LTGT_EXPR:
10976 637470 : {
10977 1048189 : temp = do_store_flag (ops,
10978 : modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
10979 : tmode != VOIDmode ? tmode : mode);
10980 637470 : if (temp)
10981 : return temp;
10982 :
10983 : /* Use a compare and a jump for BLKmode comparisons, or for function
10984 : type comparisons is have_canonicalize_funcptr_for_compare. */
10985 :
10986 0 : if ((target == 0
10987 0 : || modifier == EXPAND_STACK_PARM
10988 0 : || ! safe_from_p (target, treeop0, 1)
10989 0 : || ! safe_from_p (target, treeop1, 1)
10990 : /* Make sure we don't have a hard reg (such as function's return
10991 : value) live across basic blocks, if not optimizing. */
10992 0 : || (!optimize && REG_P (target)
10993 0 : && REGNO (target) < FIRST_PSEUDO_REGISTER)))
10994 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
10995 :
10996 0 : emit_move_insn (target, const0_rtx);
10997 :
10998 0 : rtx_code_label *lab1 = gen_label_rtx ();
10999 0 : jumpifnot_1 (code, treeop0, treeop1, lab1,
11000 : profile_probability::uninitialized ());
11001 :
11002 0 : if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
11003 0 : emit_move_insn (target, constm1_rtx);
11004 : else
11005 0 : emit_move_insn (target, const1_rtx);
11006 :
11007 0 : emit_label (lab1);
11008 0 : return target;
11009 : }
11010 54928 : case COMPLEX_EXPR:
11011 : /* Get the rtx code of the operands. */
11012 54928 : op0 = expand_normal (treeop0);
11013 54928 : op1 = expand_normal (treeop1);
11014 :
11015 54928 : if (!target)
11016 3097 : target = gen_reg_rtx (TYPE_MODE (type));
11017 : else
11018 : /* If target overlaps with op1, then either we need to force
11019 : op1 into a pseudo (if target also overlaps with op0),
11020 : or write the complex parts in reverse order. */
11021 51831 : switch (GET_CODE (target))
11022 : {
11023 49077 : case CONCAT:
11024 49077 : if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
11025 : {
11026 0 : if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
11027 : {
11028 0 : complex_expr_force_op1:
11029 1724 : temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
11030 862 : emit_move_insn (temp, op1);
11031 862 : op1 = temp;
11032 862 : break;
11033 : }
11034 0 : complex_expr_swap_order:
11035 : /* Move the imaginary (op1) and real (op0) parts to their
11036 : location. */
11037 1 : write_complex_part (target, op1, true, true);
11038 1 : write_complex_part (target, op0, false, false);
11039 :
11040 1 : return target;
11041 : }
11042 : break;
11043 2754 : case MEM:
11044 5508 : temp = adjust_address_nv (target,
11045 : GET_MODE_INNER (GET_MODE (target)), 0);
11046 2754 : if (reg_overlap_mentioned_p (temp, op1))
11047 : {
11048 863 : scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
11049 1726 : temp = adjust_address_nv (target, imode,
11050 : GET_MODE_SIZE (imode));
11051 863 : if (reg_overlap_mentioned_p (temp, op0))
11052 862 : goto complex_expr_force_op1;
11053 1 : goto complex_expr_swap_order;
11054 : }
11055 : break;
11056 0 : default:
11057 0 : if (reg_overlap_mentioned_p (target, op1))
11058 : {
11059 0 : if (reg_overlap_mentioned_p (target, op0))
11060 0 : goto complex_expr_force_op1;
11061 0 : goto complex_expr_swap_order;
11062 : }
11063 : break;
11064 : }
11065 :
11066 : /* Move the real (op0) and imaginary (op1) parts to their location. */
11067 54927 : write_complex_part (target, op0, false, true);
11068 54927 : write_complex_part (target, op1, true, false);
11069 :
11070 54927 : return target;
11071 :
11072 0 : case WIDEN_SUM_EXPR:
11073 0 : {
11074 0 : tree oprnd0 = treeop0;
11075 0 : tree oprnd1 = treeop1;
11076 :
11077 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11078 0 : target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
11079 : target, unsignedp);
11080 0 : return target;
11081 : }
11082 :
11083 18166 : case VEC_UNPACK_HI_EXPR:
11084 18166 : case VEC_UNPACK_LO_EXPR:
11085 18166 : case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
11086 18166 : case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
11087 18166 : {
11088 18166 : op0 = expand_normal (treeop0);
11089 18166 : temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
11090 : target, unsignedp);
11091 18166 : gcc_assert (temp);
11092 : return temp;
11093 : }
11094 :
11095 1754 : case VEC_UNPACK_FLOAT_HI_EXPR:
11096 1754 : case VEC_UNPACK_FLOAT_LO_EXPR:
11097 1754 : {
11098 1754 : op0 = expand_normal (treeop0);
11099 : /* The signedness is determined from input operand. */
11100 1754 : temp = expand_widen_pattern_expr
11101 3508 : (ops, op0, NULL_RTX, NULL_RTX,
11102 1754 : target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
11103 :
11104 1754 : gcc_assert (temp);
11105 : return temp;
11106 : }
11107 :
11108 993 : case VEC_WIDEN_MULT_HI_EXPR:
11109 993 : case VEC_WIDEN_MULT_LO_EXPR:
11110 993 : case VEC_WIDEN_MULT_EVEN_EXPR:
11111 993 : case VEC_WIDEN_MULT_ODD_EXPR:
11112 993 : case VEC_WIDEN_LSHIFT_HI_EXPR:
11113 993 : case VEC_WIDEN_LSHIFT_LO_EXPR:
11114 993 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11115 993 : target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
11116 : target, unsignedp);
11117 993 : gcc_assert (target);
11118 : return target;
11119 :
11120 362 : case VEC_PACK_SAT_EXPR:
11121 362 : case VEC_PACK_FIX_TRUNC_EXPR:
11122 362 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11123 362 : subtarget = NULL_RTX;
11124 362 : goto binop;
11125 :
11126 11035 : case VEC_PACK_TRUNC_EXPR:
11127 11035 : if (VECTOR_BOOLEAN_TYPE_P (type)
11128 2481 : && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
11129 2481 : && mode == TYPE_MODE (TREE_TYPE (treeop0))
11130 11739 : && SCALAR_INT_MODE_P (mode))
11131 : {
11132 704 : class expand_operand eops[4];
11133 704 : machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
11134 704 : expand_operands (treeop0, treeop1,
11135 : subtarget, &op0, &op1, EXPAND_NORMAL);
11136 704 : this_optab = vec_pack_sbool_trunc_optab;
11137 704 : enum insn_code icode = optab_handler (this_optab, imode);
11138 704 : create_output_operand (&eops[0], target, mode);
11139 704 : create_convert_operand_from (&eops[1], op0, imode, false);
11140 704 : create_convert_operand_from (&eops[2], op1, imode, false);
11141 704 : temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
11142 704 : create_input_operand (&eops[3], temp, imode);
11143 704 : expand_insn (icode, 4, eops);
11144 704 : return eops[0].value;
11145 : }
11146 10331 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11147 10331 : subtarget = NULL_RTX;
11148 10331 : goto binop;
11149 :
11150 27 : case VEC_PACK_FLOAT_EXPR:
11151 27 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11152 27 : expand_operands (treeop0, treeop1,
11153 : subtarget, &op0, &op1, EXPAND_NORMAL);
11154 27 : this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
11155 : optab_default);
11156 81 : target = expand_binop (mode, this_optab, op0, op1, target,
11157 27 : TYPE_UNSIGNED (TREE_TYPE (treeop0)),
11158 : OPTAB_LIB_WIDEN);
11159 27 : gcc_assert (target);
11160 : return target;
11161 :
11162 75233 : case VEC_PERM_EXPR:
11163 75233 : {
11164 75233 : expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL);
11165 75233 : vec_perm_builder sel;
11166 75233 : if (TREE_CODE (treeop2) == VECTOR_CST
11167 75233 : && tree_to_vec_perm_builder (&sel, treeop2))
11168 : {
11169 75215 : machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
11170 75215 : temp = expand_vec_perm_const (mode, op0, op1, sel,
11171 : sel_mode, target);
11172 : }
11173 : else
11174 : {
11175 18 : op2 = expand_normal (treeop2);
11176 18 : temp = expand_vec_perm_var (mode, op0, op1, op2, target);
11177 : }
11178 75233 : gcc_assert (temp);
11179 75233 : return temp;
11180 75233 : }
11181 :
11182 429 : case DOT_PROD_EXPR:
11183 429 : {
11184 429 : tree oprnd0 = treeop0;
11185 429 : tree oprnd1 = treeop1;
11186 429 : tree oprnd2 = treeop2;
11187 :
11188 429 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11189 429 : op2 = expand_normal (oprnd2);
11190 429 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11191 : target, unsignedp);
11192 429 : return target;
11193 : }
11194 :
11195 113 : case SAD_EXPR:
11196 113 : {
11197 113 : tree oprnd0 = treeop0;
11198 113 : tree oprnd1 = treeop1;
11199 113 : tree oprnd2 = treeop2;
11200 :
11201 113 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11202 113 : op2 = expand_normal (oprnd2);
11203 113 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11204 : target, unsignedp);
11205 113 : return target;
11206 : }
11207 :
11208 0 : case REALIGN_LOAD_EXPR:
11209 0 : {
11210 0 : tree oprnd0 = treeop0;
11211 0 : tree oprnd1 = treeop1;
11212 0 : tree oprnd2 = treeop2;
11213 :
11214 0 : this_optab = optab_for_tree_code (code, type, optab_default);
11215 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11216 0 : op2 = expand_normal (oprnd2);
11217 0 : temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
11218 : target, unsignedp);
11219 0 : gcc_assert (temp);
11220 : return temp;
11221 : }
11222 :
11223 18080 : case COND_EXPR:
11224 18080 : {
11225 : /* A COND_EXPR with its type being VOID_TYPE represents a
11226 : conditional jump and is handled in
11227 : expand_gimple_cond_expr. */
11228 18080 : gcc_assert (!VOID_TYPE_P (type));
11229 :
11230 : /* Note that COND_EXPRs whose type is a structure or union
11231 : are required to be constructed to contain assignments of
11232 : a temporary variable, so that we can evaluate them here
11233 : for side effect only. If type is void, we must do likewise. */
11234 :
11235 18080 : gcc_assert (!TREE_ADDRESSABLE (type)
11236 : && !ignore
11237 : && TREE_TYPE (treeop1) != void_type_node
11238 : && TREE_TYPE (treeop2) != void_type_node);
11239 :
11240 18080 : temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
11241 18080 : if (temp)
11242 : return temp;
11243 :
11244 : /* If we are not to produce a result, we have no target. Otherwise,
11245 : if a target was specified use it; it will not be used as an
11246 : intermediate target unless it is safe. If no target, use a
11247 : temporary. */
11248 :
11249 3860 : if (modifier != EXPAND_STACK_PARM
11250 3860 : && original_target
11251 2285 : && safe_from_p (original_target, treeop0, 1)
11252 0 : && GET_MODE (original_target) == mode
11253 3860 : && !MEM_P (original_target))
11254 : temp = original_target;
11255 : else
11256 3860 : temp = assign_temp (type, 0, 1);
11257 :
11258 3860 : do_pending_stack_adjust ();
11259 3860 : NO_DEFER_POP;
11260 3860 : rtx_code_label *lab0 = gen_label_rtx ();
11261 3860 : rtx_code_label *lab1 = gen_label_rtx ();
11262 3860 : jumpifnot (treeop0, lab0,
11263 : profile_probability::uninitialized ());
11264 3860 : store_expr (treeop1, temp,
11265 : modifier == EXPAND_STACK_PARM,
11266 : false, false);
11267 :
11268 3860 : emit_jump_insn (targetm.gen_jump (lab1));
11269 3860 : emit_barrier ();
11270 3860 : emit_label (lab0);
11271 3860 : store_expr (treeop2, temp,
11272 : modifier == EXPAND_STACK_PARM,
11273 : false, false);
11274 :
11275 3860 : emit_label (lab1);
11276 3860 : OK_DEFER_POP;
11277 3860 : return temp;
11278 : }
11279 :
11280 0 : case VEC_DUPLICATE_EXPR:
11281 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
11282 0 : target = expand_vector_broadcast (mode, op0);
11283 0 : gcc_assert (target);
11284 : return target;
11285 :
11286 0 : case VEC_SERIES_EXPR:
11287 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
11288 0 : return expand_vec_series_expr (mode, op0, op1, target);
11289 :
11290 977 : case BIT_INSERT_EXPR:
11291 977 : {
11292 977 : unsigned bitpos = tree_to_uhwi (treeop2);
11293 977 : unsigned bitsize;
11294 977 : if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
11295 658 : bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
11296 : else
11297 319 : bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
11298 977 : op0 = expand_normal (treeop0);
11299 977 : op1 = expand_normal (treeop1);
11300 977 : rtx dst = gen_reg_rtx (mode);
11301 977 : emit_move_insn (dst, op0);
11302 977 : store_bit_field (dst, bitsize, bitpos, 0, 0,
11303 977 : TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
11304 977 : return dst;
11305 : }
11306 :
11307 0 : default:
11308 0 : gcc_unreachable ();
11309 : }
11310 :
11311 : /* Here to do an ordinary binary operator. */
11312 1194750 : binop:
11313 1194750 : expand_operands (treeop0, treeop1,
11314 : subtarget, &op0, &op1, EXPAND_NORMAL);
11315 5694575 : binop2:
11316 5694575 : this_optab = optab_for_tree_code (code, type, optab_default);
11317 5694575 : binop3:
11318 5694575 : if (modifier == EXPAND_STACK_PARM)
11319 27201 : target = 0;
11320 5694575 : temp = expand_binop (mode, this_optab, op0, op1, target,
11321 : unsignedp, OPTAB_LIB_WIDEN);
11322 5694575 : gcc_assert (temp);
11323 : /* Bitwise operations do not need bitfield reduction as we expect their
11324 : operands being properly truncated. */
11325 5694575 : if (code == BIT_XOR_EXPR
11326 : || code == BIT_AND_EXPR
11327 5694575 : || code == BIT_IOR_EXPR)
11328 : return temp;
11329 5079065 : return REDUCE_BIT_FIELD (temp);
11330 : }
11331 : #undef REDUCE_BIT_FIELD
11332 :
11333 :
11334 : /* Return TRUE if expression STMT is suitable for replacement.
11335 : Never consider memory loads as replaceable, because those don't ever lead
11336 : into constant expressions. */
11337 :
11338 : static bool
11339 8 : stmt_is_replaceable_p (gimple *stmt)
11340 : {
11341 8 : if (ssa_is_replaceable_p (stmt))
11342 : {
11343 : /* Don't move around loads. */
11344 7 : if (!gimple_assign_single_p (stmt)
11345 7 : || is_gimple_val (gimple_assign_rhs1 (stmt)))
11346 6 : return true;
11347 : }
11348 : return false;
11349 : }
11350 :
11351 : /* A subroutine of expand_expr_real_1. Expand gimple assignment G,
11352 : which is known to set an SSA_NAME result. The other arguments are
11353 : as for expand_expr_real_1. */
11354 :
11355 : rtx
11356 15111854 : expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
11357 : enum expand_modifier modifier, rtx *alt_rtl,
11358 : bool inner_reference_p)
11359 : {
11360 15111854 : separate_ops ops;
11361 15111854 : rtx r;
11362 15111854 : location_t saved_loc = curr_insn_location ();
11363 15111854 : auto loc = gimple_location (g);
11364 15111854 : if (loc != UNKNOWN_LOCATION)
11365 12092607 : set_curr_insn_location (loc);
11366 15111854 : tree lhs = gimple_assign_lhs (g);
11367 15111854 : ops.code = gimple_assign_rhs_code (g);
11368 15111854 : ops.type = TREE_TYPE (lhs);
11369 15111854 : switch (get_gimple_rhs_class (ops.code))
11370 : {
11371 94681 : case GIMPLE_TERNARY_RHS:
11372 189362 : ops.op2 = gimple_assign_rhs3 (g);
11373 : /* Fallthru */
11374 8113015 : case GIMPLE_BINARY_RHS:
11375 8113015 : ops.op1 = gimple_assign_rhs2 (g);
11376 :
11377 : /* Try to expand conditional compare. */
11378 8113015 : if (targetm.have_ccmp ())
11379 : {
11380 164948 : gcc_checking_assert (targetm.gen_ccmp_next != NULL);
11381 164948 : r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
11382 164948 : if (r)
11383 : break;
11384 : }
11385 : /* Fallthru */
11386 11662061 : case GIMPLE_UNARY_RHS:
11387 11662061 : ops.op0 = gimple_assign_rhs1 (g);
11388 11662061 : ops.location = loc;
11389 11662061 : r = expand_expr_real_2 (&ops, target, tmode, modifier);
11390 11662061 : break;
11391 3449775 : case GIMPLE_SINGLE_RHS:
11392 3449775 : {
11393 3449775 : r = expand_expr_real (gimple_assign_rhs1 (g), target,
11394 : tmode, modifier, alt_rtl,
11395 : inner_reference_p);
11396 3449775 : break;
11397 : }
11398 0 : default:
11399 0 : gcc_unreachable ();
11400 : }
11401 15111854 : set_curr_insn_location (saved_loc);
11402 15111854 : if (REG_P (r) && !REG_EXPR (r))
11403 3960683 : set_reg_attrs_for_decl_rtl (lhs, r);
11404 15111854 : return r;
11405 : }
11406 :
11407 : /* A subroutine of expand_expr_real_1. Attempt to VIEW_CONVERT_EXPR
11408 : the complex expression OP0 to the vector mode MODE. Store the
11409 : result at TARGET if possible (if TARGET is nonzero). Returns
11410 : NULL_RTX on failure. */
11411 : static rtx
11412 6660 : try_expand_complex_as_vector (machine_mode mode, rtx op0, rtx target)
11413 : {
11414 6660 : if (COMPLEX_MODE_P (GET_MODE (op0))
11415 1404 : && VECTOR_MODE_P (mode)
11416 58 : && known_eq (GET_MODE_NUNITS (mode), 2)
11417 6718 : && GET_MODE_INNER (mode) == GET_MODE_INNER (GET_MODE (op0)))
11418 : {
11419 29 : enum insn_code icode = convert_optab_handler (vec_init_optab, mode,
11420 29 : GET_MODE_INNER (mode));
11421 29 : if (icode != CODE_FOR_nothing)
11422 : {
11423 29 : if (!target || !REG_P (target))
11424 16 : target = gen_reg_rtx (mode);
11425 29 : rtx rpart = read_complex_part (op0, false);
11426 29 : rtx ipart = read_complex_part (op0, true);
11427 29 : if (!REG_P (rpart) && !CONSTANT_P (rpart))
11428 0 : rpart = force_reg (GET_MODE_INNER (mode), rpart);
11429 29 : if (!REG_P (ipart) && !CONSTANT_P (ipart))
11430 0 : ipart = force_reg (GET_MODE_INNER (mode), ipart);
11431 29 : rtvec vec = rtvec_alloc (2);
11432 29 : RTVEC_ELT (vec, 0) = rpart;
11433 29 : RTVEC_ELT (vec, 1) = ipart;
11434 29 : rtx par = gen_rtx_PARALLEL (mode, vec);
11435 29 : rtx_insn *insn = GEN_FCN (icode) (target, par);
11436 29 : if (insn)
11437 : {
11438 29 : emit_insn (insn);
11439 29 : return target;
11440 : }
11441 : }
11442 : }
11443 : return NULL_RTX;
11444 : }
11445 :
11446 : rtx
11447 158141343 : expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
11448 : enum expand_modifier modifier, rtx *alt_rtl,
11449 : bool inner_reference_p)
11450 : {
11451 158141343 : rtx op0, op1, temp, decl_rtl;
11452 158141343 : tree type;
11453 158141343 : int unsignedp;
11454 158141343 : machine_mode mode, dmode;
11455 158141343 : enum tree_code code = TREE_CODE (exp);
11456 158141343 : rtx subtarget, original_target;
11457 158141343 : int ignore;
11458 158141343 : bool reduce_bit_field;
11459 158141343 : location_t loc = EXPR_LOCATION (exp);
11460 158141343 : struct separate_ops ops;
11461 158141343 : tree treeop0, treeop1, treeop2;
11462 158141343 : tree ssa_name = NULL_TREE;
11463 158141343 : gimple *g;
11464 :
11465 : /* Some ABIs define padding bits in _BitInt uninitialized. Normally, RTL
11466 : expansion sign/zero extends integral types with less than mode precision
11467 : when reading from bit-fields and after arithmetic operations (see
11468 : REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
11469 : on those extensions to have been already performed, but because of the
11470 : above for _BitInt they need to be sign/zero extended when reading from
11471 : locations that could be exposed to ABI boundaries (when loading from
11472 : objects in memory, or function arguments, return value). Because we
11473 : internally extend after arithmetic operations, we can avoid doing that
11474 : when reading from SSA_NAMEs of vars. */
11475 : #define EXTEND_BITINT(expr) \
11476 : ((BITINT_TYPE_P (type) \
11477 : && !bitint_extended \
11478 : && reduce_bit_field \
11479 : && mode != BLKmode \
11480 : && modifier != EXPAND_MEMORY \
11481 : && modifier != EXPAND_WRITE \
11482 : && modifier != EXPAND_INITIALIZER \
11483 : && modifier != EXPAND_CONST_ADDRESS) \
11484 : ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
11485 :
11486 158141343 : type = TREE_TYPE (exp);
11487 158141343 : mode = TYPE_MODE (type);
11488 158141343 : unsignedp = TYPE_UNSIGNED (type);
11489 158141343 : if (BITINT_TYPE_P (type) && bitint_extended == -1)
11490 : {
11491 8798 : struct bitint_info info;
11492 8798 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
11493 8798 : gcc_assert (ok);
11494 8798 : bitint_extended = info.extended;
11495 : }
11496 :
11497 158141343 : treeop0 = treeop1 = treeop2 = NULL_TREE;
11498 158141343 : if (!VL_EXP_CLASS_P (exp))
11499 151369580 : switch (TREE_CODE_LENGTH (code))
11500 : {
11501 5545846 : default:
11502 5545846 : case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
11503 13601928 : case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
11504 28120335 : case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
11505 : case 0: break;
11506 : }
11507 158141343 : ops.code = code;
11508 158141343 : ops.type = type;
11509 158141343 : ops.op0 = treeop0;
11510 158141343 : ops.op1 = treeop1;
11511 158141343 : ops.op2 = treeop2;
11512 158141343 : ops.location = loc;
11513 :
11514 316282686 : ignore = (target == const0_rtx
11515 158141343 : || ((CONVERT_EXPR_CODE_P (code)
11516 153058261 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
11517 956789 : && TREE_CODE (type) == VOID_TYPE));
11518 :
11519 : /* An operation in what may be a bit-field type needs the
11520 : result to be reduced to the precision of the bit-field type,
11521 : which is narrower than that of the type's mode. */
11522 316282450 : reduce_bit_field = (!ignore
11523 153667068 : && INTEGRAL_TYPE_P (type)
11524 80797869 : && !type_has_mode_precision_p (type));
11525 :
11526 : /* If we are going to ignore this result, we need only do something
11527 : if there is a side-effect somewhere in the expression. If there
11528 : is, short-circuit the most common cases here. Note that we must
11529 : not call expand_expr with anything but const0_rtx in case this
11530 : is an initial expansion of a size that contains a PLACEHOLDER_EXPR. */
11531 :
11532 4474275 : if (ignore)
11533 : {
11534 4474275 : if (! TREE_SIDE_EFFECTS (exp))
11535 : return const0_rtx;
11536 :
11537 : /* Ensure we reference a volatile object even if value is ignored, but
11538 : don't do this if all we are doing is taking its address. */
11539 4474039 : if (TREE_THIS_VOLATILE (exp)
11540 0 : && TREE_CODE (exp) != FUNCTION_DECL
11541 0 : && mode != VOIDmode && mode != BLKmode
11542 0 : && modifier != EXPAND_CONST_ADDRESS)
11543 : {
11544 0 : temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
11545 0 : if (MEM_P (temp))
11546 0 : copy_to_reg (temp);
11547 0 : return const0_rtx;
11548 : }
11549 :
11550 4474039 : if (TREE_CODE_CLASS (code) == tcc_unary
11551 : || code == BIT_FIELD_REF
11552 4474039 : || code == COMPONENT_REF
11553 4474039 : || code == INDIRECT_REF)
11554 0 : return expand_expr (treeop0, const0_rtx, VOIDmode,
11555 0 : modifier);
11556 :
11557 4474039 : else if (TREE_CODE_CLASS (code) == tcc_binary
11558 4474039 : || TREE_CODE_CLASS (code) == tcc_comparison
11559 4474039 : || code == ARRAY_REF || code == ARRAY_RANGE_REF)
11560 : {
11561 0 : expand_expr (treeop0, const0_rtx, VOIDmode, modifier);
11562 0 : expand_expr (treeop1, const0_rtx, VOIDmode, modifier);
11563 0 : return const0_rtx;
11564 : }
11565 :
11566 : target = 0;
11567 : }
11568 :
11569 158141107 : if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
11570 39464 : target = 0;
11571 :
11572 : /* Use subtarget as the target for operand 0 of a binary operation. */
11573 158141107 : subtarget = get_subtarget (target);
11574 158141107 : original_target = target;
11575 :
11576 158141107 : switch (code)
11577 : {
11578 10841 : case LABEL_DECL:
11579 10841 : {
11580 10841 : tree function = decl_function_context (exp);
11581 :
11582 10841 : temp = label_rtx (exp);
11583 14785 : temp = gen_rtx_LABEL_REF (Pmode, temp);
11584 :
11585 10841 : if (function != current_function_decl
11586 1270 : && function != 0)
11587 1270 : LABEL_REF_NONLOCAL_P (temp) = 1;
11588 :
11589 10841 : temp = gen_rtx_MEM (FUNCTION_MODE, temp);
11590 10841 : return temp;
11591 : }
11592 :
11593 57207075 : case SSA_NAME:
11594 : /* ??? ivopts calls expander, without any preparation from
11595 : out-of-ssa. So fake instructions as if this was an access to the
11596 : base variable. This unnecessarily allocates a pseudo, see how we can
11597 : reuse it, if partition base vars have it set already. */
11598 57207075 : if (!currently_expanding_to_rtl)
11599 : {
11600 0 : tree var = SSA_NAME_VAR (exp);
11601 0 : if (var && DECL_RTL_SET_P (var))
11602 0 : return DECL_RTL (var);
11603 0 : return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
11604 0 : LAST_VIRTUAL_REGISTER + 1);
11605 : }
11606 :
11607 57207075 : g = get_gimple_for_ssa_name (exp);
11608 : /* For EXPAND_INITIALIZER try harder to get something simpler. */
11609 57207075 : if (g == NULL
11610 57207075 : && modifier == EXPAND_INITIALIZER
11611 26 : && !SSA_NAME_IS_DEFAULT_DEF (exp)
11612 11 : && (optimize || !SSA_NAME_VAR (exp)
11613 1 : || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
11614 10 : && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
11615 57207083 : && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
11616 6 : g = SSA_NAME_DEF_STMT (exp);
11617 57207075 : if (safe_is_a <gassign *> (g))
11618 9126221 : return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
11619 9126221 : modifier, alt_rtl, inner_reference_p);
11620 48080854 : else if (safe_is_a <gcall *> (g))
11621 : {
11622 : /* ??? internal call expansion doesn't follow the usual API
11623 : of returning the destination RTX and being passed a desired
11624 : target. */
11625 72886 : if (modifier == EXPAND_WRITE)
11626 36447 : return DECL_RTL (SSA_NAME_VAR (exp));
11627 36439 : rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11628 36439 : tree tmplhs = make_tree (TREE_TYPE (exp), dest);
11629 36439 : tree var_or_id = SSA_NAME_VAR (exp);
11630 : if (!var_or_id)
11631 26452 : var_or_id = SSA_NAME_IDENTIFIER (exp);
11632 36439 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, tmplhs);
11633 36439 : expand_internal_call (as_a <gcall *> (g));
11634 36439 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, var_or_id);
11635 36439 : return dest;
11636 : }
11637 :
11638 48007968 : ssa_name = exp;
11639 48007968 : decl_rtl = get_rtx_for_ssa_name (ssa_name);
11640 48007968 : exp = SSA_NAME_VAR (ssa_name);
11641 : /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
11642 : SSA_NAME computed within the current function. In such case the
11643 : value have been already extended before. While if it is a function
11644 : parameter, result or some memory location, we need to be prepared
11645 : for some other compiler leaving the bits uninitialized. */
11646 18812383 : if (!exp || VAR_P (exp))
11647 : reduce_bit_field = false;
11648 48007968 : goto expand_decl_rtl;
11649 :
11650 19780629 : case VAR_DECL:
11651 : /* Allow accel compiler to handle variables that require special
11652 : treatment, e.g. if they have been modified in some way earlier in
11653 : compilation by the adjust_private_decl OpenACC hook. */
11654 19780629 : if (flag_openacc && targetm.goacc.expand_var_decl)
11655 : {
11656 0 : temp = targetm.goacc.expand_var_decl (exp);
11657 0 : if (temp)
11658 : return temp;
11659 : }
11660 : /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
11661 : have scalar integer modes to a reg via store_constructor. */
11662 19780629 : if (TREE_READONLY (exp)
11663 3376022 : && !TREE_SIDE_EFFECTS (exp)
11664 3353614 : && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
11665 18489 : && immediate_const_ctor_p (DECL_INITIAL (exp))
11666 163 : && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
11667 127 : && crtl->emit.regno_pointer_align_length
11668 19780756 : && !target)
11669 : {
11670 88 : target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11671 88 : store_constructor (DECL_INITIAL (exp), target, 0,
11672 88 : int_expr_size (DECL_INITIAL (exp)), false);
11673 88 : return target;
11674 : }
11675 : /* ... fall through ... */
11676 :
11677 20325377 : case PARM_DECL:
11678 : /* If a static var's type was incomplete when the decl was written,
11679 : but the type is complete now, lay out the decl now. */
11680 20325377 : if (DECL_SIZE (exp) == 0
11681 44930 : && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
11682 20370195 : && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
11683 44818 : layout_decl (exp, 0);
11684 :
11685 : /* fall through */
11686 :
11687 21791013 : case FUNCTION_DECL:
11688 21791013 : case RESULT_DECL:
11689 21791013 : decl_rtl = DECL_RTL (exp);
11690 69798981 : expand_decl_rtl:
11691 69798981 : gcc_assert (decl_rtl);
11692 :
11693 : /* DECL_MODE might change when TYPE_MODE depends on attribute target
11694 : settings for VECTOR_TYPE_P that might switch for the function. */
11695 69798981 : if (currently_expanding_to_rtl
11696 66121570 : && code == VAR_DECL && MEM_P (decl_rtl)
11697 84558896 : && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
11698 57 : decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
11699 : else
11700 69798924 : decl_rtl = copy_rtx (decl_rtl);
11701 :
11702 : /* Record writes to register variables. */
11703 69798981 : if (modifier == EXPAND_WRITE
11704 21922982 : && REG_P (decl_rtl)
11705 85824782 : && HARD_REGISTER_P (decl_rtl))
11706 2027 : add_to_hard_reg_set (&crtl->asm_clobbers,
11707 2027 : GET_MODE (decl_rtl), REGNO (decl_rtl));
11708 :
11709 : /* Ensure variable marked as used even if it doesn't go through
11710 : a parser. If it hasn't be used yet, write out an external
11711 : definition. */
11712 69798981 : if (exp)
11713 40603396 : TREE_USED (exp) = 1;
11714 :
11715 : /* Show we haven't gotten RTL for this yet. */
11716 110402377 : temp = 0;
11717 :
11718 : /* Variables inherited from containing functions should have
11719 : been lowered by this point. */
11720 40603396 : if (exp)
11721 : {
11722 40603396 : tree context = decl_function_context (exp);
11723 40603396 : gcc_assert (SCOPE_FILE_SCOPE_P (context)
11724 : || context == current_function_decl
11725 : || TREE_STATIC (exp)
11726 : || DECL_EXTERNAL (exp)
11727 : /* ??? C++ creates functions that are not
11728 : TREE_STATIC. */
11729 : || TREE_CODE (exp) == FUNCTION_DECL);
11730 : }
11731 :
11732 : /* This is the case of an array whose size is to be determined
11733 : from its initializer, while the initializer is still being parsed.
11734 : ??? We aren't parsing while expanding anymore. */
11735 :
11736 69798981 : if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
11737 393551 : temp = validize_mem (decl_rtl);
11738 :
11739 : /* If DECL_RTL is memory, we are in the normal case and the
11740 : address is not valid, get the address into a register. */
11741 :
11742 69405430 : else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
11743 : {
11744 18833446 : if (alt_rtl)
11745 2027702 : *alt_rtl = decl_rtl;
11746 18833446 : decl_rtl = use_anchored_address (decl_rtl);
11747 18833446 : if (modifier != EXPAND_CONST_ADDRESS
11748 18833446 : && modifier != EXPAND_SUM
11749 31183378 : && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
11750 17391 : : GET_MODE (decl_rtl),
11751 : XEXP (decl_rtl, 0),
11752 12349932 : MEM_ADDR_SPACE (decl_rtl)))
11753 137192 : temp = replace_equiv_address (decl_rtl,
11754 : copy_rtx (XEXP (decl_rtl, 0)));
11755 : }
11756 :
11757 : /* If we got something, return it. But first, set the alignment
11758 : if the address is a register. */
11759 19226997 : if (temp != 0)
11760 : {
11761 530743 : if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
11762 498763 : mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
11763 : }
11764 69268238 : else if (MEM_P (decl_rtl))
11765 : temp = decl_rtl;
11766 :
11767 47559695 : if (temp != 0)
11768 : {
11769 22738059 : if (MEM_P (temp)
11770 : && modifier != EXPAND_WRITE
11771 22738059 : && modifier != EXPAND_MEMORY
11772 : && modifier != EXPAND_INITIALIZER
11773 16778754 : && modifier != EXPAND_CONST_ADDRESS
11774 6948570 : && modifier != EXPAND_SUM
11775 6948570 : && !inner_reference_p
11776 4569627 : && mode != BLKmode
11777 26940596 : && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
11778 19902 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11779 19902 : MEM_ALIGN (temp), NULL_RTX, NULL);
11780 :
11781 22738059 : return EXTEND_BITINT (temp);
11782 : }
11783 :
11784 47060922 : if (exp)
11785 17882738 : dmode = DECL_MODE (exp);
11786 : else
11787 29178184 : dmode = TYPE_MODE (TREE_TYPE (ssa_name));
11788 :
11789 : /* If the mode of DECL_RTL does not match that of the decl,
11790 : there are two cases: we are dealing with a BLKmode value
11791 : that is returned in a register, or we are dealing with
11792 : a promoted value. In the latter case, return a SUBREG
11793 : of the wanted mode, but mark it so that we know that it
11794 : was already extended. */
11795 47060922 : if (REG_P (decl_rtl)
11796 46527498 : && dmode != BLKmode
11797 46527498 : && GET_MODE (decl_rtl) != dmode)
11798 : {
11799 82 : machine_mode pmode;
11800 :
11801 : /* Get the signedness to be used for this variable. Ensure we get
11802 : the same mode we got when the variable was declared. */
11803 82 : if (code != SSA_NAME)
11804 0 : pmode = promote_decl_mode (exp, &unsignedp);
11805 82 : else if ((g = SSA_NAME_DEF_STMT (ssa_name))
11806 82 : && gimple_code (g) == GIMPLE_CALL
11807 84 : && !gimple_call_internal_p (g))
11808 2 : pmode = promote_function_mode (type, mode, &unsignedp,
11809 2 : gimple_call_fntype (g),
11810 : 2);
11811 : else
11812 80 : pmode = promote_ssa_mode (ssa_name, &unsignedp);
11813 82 : gcc_assert (GET_MODE (decl_rtl) == pmode);
11814 :
11815 : /* Some ABIs require scalar floating point modes to be passed
11816 : in a wider scalar integer mode. We need to explicitly
11817 : truncate to an integer mode of the correct precision before
11818 : using a SUBREG to reinterpret as a floating point value. */
11819 82 : if (SCALAR_FLOAT_MODE_P (mode)
11820 0 : && SCALAR_INT_MODE_P (pmode)
11821 82 : && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
11822 0 : return convert_wider_int_to_float (mode, pmode, decl_rtl);
11823 :
11824 82 : temp = gen_lowpart_SUBREG (mode, decl_rtl);
11825 82 : SUBREG_PROMOTED_VAR_P (temp) = 1;
11826 82 : SUBREG_PROMOTED_SET (temp, unsignedp);
11827 82 : return EXTEND_BITINT (temp);
11828 : }
11829 :
11830 47060840 : return EXTEND_BITINT (decl_rtl);
11831 :
11832 42429593 : case INTEGER_CST:
11833 42429593 : {
11834 42429593 : if (BITINT_TYPE_P (type))
11835 : {
11836 11582 : unsigned int prec = TYPE_PRECISION (type);
11837 11582 : struct bitint_info info;
11838 11582 : bool ok = targetm.c.bitint_type_info (prec, &info);
11839 11582 : gcc_assert (ok);
11840 11582 : scalar_int_mode limb_mode
11841 11582 : = as_a <scalar_int_mode> (info.limb_mode);
11842 11582 : unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
11843 19154 : if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
11844 : {
11845 : /* Emit large/huge _BitInt INTEGER_CSTs into memory. */
11846 5113 : exp = tree_output_constant_def (exp);
11847 5113 : return expand_expr (exp, target, VOIDmode, modifier);
11848 : }
11849 : }
11850 :
11851 : /* Given that TYPE_PRECISION (type) is not always equal to
11852 : GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
11853 : the former to the latter according to the signedness of the
11854 : type. */
11855 42424480 : scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
11856 42424480 : temp = immed_wide_int_const
11857 42424480 : (wi::to_wide (exp, GET_MODE_PRECISION (int_mode)), int_mode);
11858 42424480 : return temp;
11859 : }
11860 :
11861 569403 : case VECTOR_CST:
11862 569403 : {
11863 569403 : tree tmp = NULL_TREE;
11864 569403 : if (VECTOR_MODE_P (mode))
11865 566604 : return const_vector_from_tree (exp);
11866 2799 : scalar_int_mode int_mode;
11867 2799 : if (is_int_mode (mode, &int_mode))
11868 : {
11869 911 : tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
11870 911 : if (type_for_mode)
11871 911 : tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
11872 : type_for_mode, exp);
11873 : }
11874 911 : if (!tmp)
11875 : {
11876 1888 : vec<constructor_elt, va_gc> *v;
11877 : /* Constructors need to be fixed-length. FIXME. */
11878 1888 : unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
11879 1888 : vec_alloc (v, nunits);
11880 28739 : for (unsigned int i = 0; i < nunits; ++i)
11881 26851 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
11882 1888 : tmp = build_constructor (type, v);
11883 : }
11884 2799 : return expand_expr (tmp, ignore ? const0_rtx : target,
11885 2799 : tmode, modifier);
11886 : }
11887 :
11888 141 : case CONST_DECL:
11889 141 : if (modifier == EXPAND_WRITE)
11890 : {
11891 : /* Writing into CONST_DECL is always invalid, but handle it
11892 : gracefully. */
11893 2 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
11894 2 : scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
11895 2 : op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
11896 : EXPAND_NORMAL, as);
11897 2 : op0 = memory_address_addr_space (mode, op0, as);
11898 2 : temp = gen_rtx_MEM (mode, op0);
11899 2 : set_mem_addr_space (temp, as);
11900 2 : return temp;
11901 : }
11902 139 : return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
11903 :
11904 862901 : case REAL_CST:
11905 : /* If optimized, generate immediate CONST_DOUBLE
11906 : which will be turned into memory by reload if necessary.
11907 :
11908 : We used to force a register so that loop.c could see it. But
11909 : this does not allow gen_* patterns to perform optimizations with
11910 : the constants. It also produces two insns in cases like "x = 1.0;".
11911 : On most machines, floating-point constants are not permitted in
11912 : many insns, so we'd end up copying it to a register in any case.
11913 :
11914 : Now, we do the copying in expand_binop, if appropriate. */
11915 862901 : return const_double_from_real_value (TREE_REAL_CST (exp),
11916 1725802 : TYPE_MODE (TREE_TYPE (exp)));
11917 :
11918 0 : case FIXED_CST:
11919 0 : return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
11920 : TYPE_MODE (TREE_TYPE (exp)));
11921 :
11922 18396 : case COMPLEX_CST:
11923 : /* Handle evaluating a complex constant in a CONCAT target. */
11924 18396 : if (original_target && GET_CODE (original_target) == CONCAT)
11925 : {
11926 219 : rtx rtarg, itarg;
11927 :
11928 219 : mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
11929 219 : rtarg = XEXP (original_target, 0);
11930 219 : itarg = XEXP (original_target, 1);
11931 :
11932 : /* Move the real and imaginary parts separately. */
11933 219 : op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, EXPAND_NORMAL);
11934 219 : op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, EXPAND_NORMAL);
11935 :
11936 219 : if (op0 != rtarg)
11937 219 : emit_move_insn (rtarg, op0);
11938 219 : if (op1 != itarg)
11939 219 : emit_move_insn (itarg, op1);
11940 :
11941 219 : return original_target;
11942 : }
11943 :
11944 : /* fall through */
11945 :
11946 200682 : case STRING_CST:
11947 200682 : temp = expand_expr_constant (exp, 1, modifier);
11948 :
11949 : /* temp contains a constant address.
11950 : On RISC machines where a constant address isn't valid,
11951 : make some insns to get that address into a register. */
11952 200682 : if (modifier != EXPAND_CONST_ADDRESS
11953 : && modifier != EXPAND_INITIALIZER
11954 200682 : && modifier != EXPAND_SUM
11955 219239 : && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
11956 18557 : MEM_ADDR_SPACE (temp)))
11957 12 : return replace_equiv_address (temp,
11958 12 : copy_rtx (XEXP (temp, 0)));
11959 : return temp;
11960 :
11961 0 : case POLY_INT_CST:
11962 0 : return immed_wide_int_const (poly_int_cst_value (exp), mode);
11963 :
11964 1624 : case SAVE_EXPR:
11965 1624 : {
11966 1624 : tree val = treeop0;
11967 1624 : rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
11968 : inner_reference_p);
11969 :
11970 1624 : if (!SAVE_EXPR_RESOLVED_P (exp))
11971 : {
11972 : /* We can indeed still hit this case, typically via builtin
11973 : expanders calling save_expr immediately before expanding
11974 : something. Assume this means that we only have to deal
11975 : with non-BLKmode values. */
11976 1577 : gcc_assert (GET_MODE (ret) != BLKmode);
11977 :
11978 1577 : val = build_decl (curr_insn_location (),
11979 1577 : VAR_DECL, NULL, TREE_TYPE (exp));
11980 1577 : DECL_ARTIFICIAL (val) = 1;
11981 1577 : DECL_IGNORED_P (val) = 1;
11982 1577 : treeop0 = val;
11983 1577 : TREE_OPERAND (exp, 0) = treeop0;
11984 1577 : SAVE_EXPR_RESOLVED_P (exp) = 1;
11985 :
11986 1577 : if (!CONSTANT_P (ret))
11987 1577 : ret = copy_to_reg (ret);
11988 1577 : SET_DECL_RTL (val, ret);
11989 : }
11990 :
11991 : return ret;
11992 : }
11993 :
11994 :
11995 177281 : case CONSTRUCTOR:
11996 : /* If we don't need the result, just ensure we evaluate any
11997 : subexpressions. */
11998 177281 : if (ignore)
11999 : {
12000 : unsigned HOST_WIDE_INT idx;
12001 : tree value;
12002 :
12003 0 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
12004 0 : expand_expr (value, const0_rtx, VOIDmode, EXPAND_NORMAL);
12005 :
12006 0 : return const0_rtx;
12007 : }
12008 :
12009 177281 : return expand_constructor (exp, target, modifier, false);
12010 :
12011 855609 : case TARGET_MEM_REF:
12012 855609 : {
12013 855609 : addr_space_t as
12014 855609 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
12015 855609 : unsigned int align;
12016 :
12017 855609 : op0 = addr_for_mem_ref (exp, as, true);
12018 855609 : op0 = memory_address_addr_space (mode, op0, as);
12019 855609 : temp = gen_rtx_MEM (mode, op0);
12020 855609 : set_mem_attributes (temp, exp, 0);
12021 855609 : set_mem_addr_space (temp, as);
12022 855609 : align = get_object_alignment (exp);
12023 855609 : if (modifier != EXPAND_WRITE
12024 855609 : && modifier != EXPAND_MEMORY
12025 589042 : && mode != BLKmode
12026 1438739 : && align < GET_MODE_ALIGNMENT (mode))
12027 52989 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
12028 : align, NULL_RTX, NULL);
12029 855609 : return EXTEND_BITINT (temp);
12030 : }
12031 :
12032 6754131 : case MEM_REF:
12033 6754131 : {
12034 6754131 : const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
12035 6754131 : addr_space_t as
12036 6754131 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
12037 6754131 : machine_mode address_mode;
12038 6754131 : tree base = TREE_OPERAND (exp, 0);
12039 6754131 : gimple *def_stmt;
12040 6754131 : unsigned align;
12041 : /* Handle expansion of non-aliased memory with non-BLKmode. That
12042 : might end up in a register. */
12043 6754131 : if (mem_ref_refers_to_non_mem_p (exp))
12044 : {
12045 79391 : poly_int64 offset = mem_ref_offset (exp).force_shwi ();
12046 79391 : base = TREE_OPERAND (base, 0);
12047 79391 : poly_uint64 type_size;
12048 79391 : if (known_eq (offset, 0)
12049 45758 : && !reverse
12050 45758 : && poly_int_tree_p (TYPE_SIZE (type), &type_size)
12051 170907 : && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
12052 19291 : return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
12053 19291 : target, tmode, modifier);
12054 60100 : unsigned align;
12055 60100 : if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
12056 : {
12057 218 : temp = assign_stack_temp (DECL_MODE (base),
12058 436 : GET_MODE_SIZE (DECL_MODE (base)));
12059 218 : store_expr (base, temp, 0, false, false);
12060 218 : temp = adjust_address (temp, TYPE_MODE (type), offset);
12061 218 : if (TYPE_MODE (type) == BLKmode)
12062 197 : set_mem_size (temp, int_size_in_bytes (type));
12063 : /* When the original ref was misaligned so will be the
12064 : access to the stack temporary. Not all targets handle
12065 : this correctly, some will ICE in sanity checking.
12066 : Handle this by doing bitfield extraction when necessary. */
12067 42 : else if ((align = get_object_alignment (exp))
12068 21 : < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
12069 3 : temp
12070 3 : = expand_misaligned_mem_ref (temp, TYPE_MODE (type),
12071 : unsignedp, align,
12072 : modifier == EXPAND_STACK_PARM
12073 : ? NULL_RTX : target, NULL);
12074 218 : return temp;
12075 : }
12076 : /* When the access is fully outside of the underlying object
12077 : expand the offset as zero. This avoids out-of-bound
12078 : BIT_FIELD_REFs and generates smaller code for these cases
12079 : with UB. */
12080 59882 : type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
12081 119764 : if (!ranges_maybe_overlap_p (offset, type_size, 0,
12082 119764 : GET_MODE_SIZE (DECL_MODE (base))))
12083 37 : offset = 0;
12084 59882 : exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
12085 59882 : bitsize_int (offset * BITS_PER_UNIT));
12086 59882 : REF_REVERSE_STORAGE_ORDER (exp) = reverse;
12087 59882 : return expand_expr (exp, target, tmode, modifier);
12088 : }
12089 6674740 : address_mode = targetm.addr_space.address_mode (as);
12090 6674740 : if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
12091 : {
12092 44 : tree mask = gimple_assign_rhs2 (def_stmt);
12093 44 : base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
12094 : gimple_assign_rhs1 (def_stmt), mask);
12095 44 : TREE_OPERAND (exp, 0) = base;
12096 : }
12097 6674740 : align = get_object_alignment (exp);
12098 6674740 : op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
12099 6674740 : op0 = memory_address_addr_space (mode, op0, as);
12100 6674740 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
12101 : {
12102 2028906 : rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
12103 2028906 : op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
12104 2028906 : op0 = memory_address_addr_space (mode, op0, as);
12105 : }
12106 6674740 : temp = gen_rtx_MEM (mode, op0);
12107 6674740 : set_mem_attributes (temp, exp, 0);
12108 6674740 : set_mem_addr_space (temp, as);
12109 6674740 : if (TREE_THIS_VOLATILE (exp))
12110 12405 : MEM_VOLATILE_P (temp) = 1;
12111 6674740 : if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
12112 : return temp;
12113 3963419 : if (!inner_reference_p
12114 2053507 : && mode != BLKmode
12115 5955588 : && align < GET_MODE_ALIGNMENT (mode))
12116 141804 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
12117 : modifier == EXPAND_STACK_PARM
12118 : ? NULL_RTX : target, alt_rtl);
12119 3963419 : if (reverse)
12120 7 : temp = flip_storage_order (mode, temp);
12121 3963419 : return EXTEND_BITINT (temp);
12122 : }
12123 :
12124 625372 : case ARRAY_REF:
12125 :
12126 625372 : {
12127 625372 : tree array = treeop0;
12128 625372 : tree index = treeop1;
12129 625372 : tree init;
12130 :
12131 : /* Fold an expression like: "foo"[2].
12132 : This is not done in fold so it won't happen inside &.
12133 : Don't fold if this is for wide characters since it's too
12134 : difficult to do correctly and this is a very rare case. */
12135 :
12136 625372 : if (modifier != EXPAND_CONST_ADDRESS
12137 625372 : && modifier != EXPAND_INITIALIZER
12138 625372 : && modifier != EXPAND_MEMORY)
12139 : {
12140 625267 : tree t = fold_read_from_constant_string (exp);
12141 :
12142 625267 : if (t)
12143 0 : return expand_expr (t, target, tmode, modifier);
12144 : }
12145 :
12146 : /* If this is a constant index into a constant array,
12147 : just get the value from the array. Handle both the cases when
12148 : we have an explicit constructor and when our operand is a variable
12149 : that was declared const. */
12150 :
12151 625372 : if (modifier != EXPAND_CONST_ADDRESS
12152 : && modifier != EXPAND_INITIALIZER
12153 : && modifier != EXPAND_MEMORY
12154 625267 : && TREE_CODE (array) == CONSTRUCTOR
12155 0 : && ! TREE_SIDE_EFFECTS (array)
12156 625372 : && TREE_CODE (index) == INTEGER_CST)
12157 : {
12158 : unsigned HOST_WIDE_INT ix;
12159 : tree field, value;
12160 :
12161 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
12162 : field, value)
12163 0 : if (tree_int_cst_equal (field, index))
12164 : {
12165 0 : if (!TREE_SIDE_EFFECTS (value)
12166 0 : && TREE_CODE (value) != RAW_DATA_CST)
12167 0 : return expand_expr (fold (value), target, tmode, modifier);
12168 : break;
12169 : }
12170 : }
12171 :
12172 625372 : else if (optimize >= 1
12173 : && modifier != EXPAND_CONST_ADDRESS
12174 357119 : && modifier != EXPAND_INITIALIZER
12175 357119 : && modifier != EXPAND_MEMORY
12176 357018 : && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
12177 9061 : && TREE_CODE (index) == INTEGER_CST
12178 2051 : && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
12179 625521 : && (init = ctor_for_folding (array)) != error_mark_node)
12180 : {
12181 108 : if (init == NULL_TREE)
12182 : {
12183 5 : tree value = build_zero_cst (type);
12184 5 : if (TREE_CODE (value) == CONSTRUCTOR)
12185 : {
12186 : /* If VALUE is a CONSTRUCTOR, this optimization is only
12187 : useful if this doesn't store the CONSTRUCTOR into
12188 : memory. If it does, it is more efficient to just
12189 : load the data from the array directly. */
12190 5 : rtx ret = expand_constructor (value, target,
12191 : modifier, true);
12192 5 : if (ret == NULL_RTX)
12193 : value = NULL_TREE;
12194 : }
12195 :
12196 : if (value)
12197 0 : return expand_expr (value, target, tmode, modifier);
12198 : }
12199 103 : else if (TREE_CODE (init) == CONSTRUCTOR)
12200 : {
12201 : unsigned HOST_WIDE_INT ix;
12202 : tree field, value;
12203 :
12204 168 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
12205 : field, value)
12206 166 : if (tree_int_cst_equal (field, index))
12207 : {
12208 100 : if (TREE_SIDE_EFFECTS (value)
12209 100 : || TREE_CODE (value) == RAW_DATA_CST)
12210 : break;
12211 :
12212 100 : if (TREE_CODE (value) == CONSTRUCTOR)
12213 : {
12214 : /* If VALUE is a CONSTRUCTOR, this
12215 : optimization is only useful if
12216 : this doesn't store the CONSTRUCTOR
12217 : into memory. If it does, it is more
12218 : efficient to just load the data from
12219 : the array directly. */
12220 95 : rtx ret = expand_constructor (value, target,
12221 : modifier, true);
12222 95 : if (ret == NULL_RTX)
12223 : break;
12224 : }
12225 :
12226 62 : return expand_expr (fold (value), target, tmode,
12227 62 : modifier);
12228 : }
12229 : }
12230 1 : else if (TREE_CODE (init) == STRING_CST)
12231 : {
12232 1 : tree low_bound = array_ref_low_bound (exp);
12233 1 : tree index1 = fold_convert_loc (loc, sizetype, treeop1);
12234 :
12235 : /* Optimize the special case of a zero lower bound.
12236 :
12237 : We convert the lower bound to sizetype to avoid problems
12238 : with constant folding. E.g. suppose the lower bound is
12239 : 1 and its mode is QI. Without the conversion
12240 : (ARRAY + (INDEX - (unsigned char)1))
12241 : becomes
12242 : (ARRAY + (-(unsigned char)1) + INDEX)
12243 : which becomes
12244 : (ARRAY + 255 + INDEX). Oops! */
12245 1 : if (!integer_zerop (low_bound))
12246 0 : index1 = size_diffop_loc (loc, index1,
12247 : fold_convert_loc (loc, sizetype,
12248 : low_bound));
12249 :
12250 1 : if (tree_fits_uhwi_p (index1)
12251 2 : && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
12252 : {
12253 0 : tree char_type = TREE_TYPE (TREE_TYPE (init));
12254 0 : scalar_int_mode char_mode;
12255 :
12256 625310 : if (is_int_mode (TYPE_MODE (char_type), &char_mode)
12257 0 : && GET_MODE_SIZE (char_mode) == 1)
12258 0 : return gen_int_mode (TREE_STRING_POINTER (init)
12259 0 : [TREE_INT_CST_LOW (index1)],
12260 : char_mode);
12261 : }
12262 : }
12263 : }
12264 : }
12265 625310 : goto normal_inner_ref;
12266 :
12267 3723700 : case COMPONENT_REF:
12268 3723700 : gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
12269 : /* Fall through. */
12270 4605537 : case BIT_FIELD_REF:
12271 4605537 : case ARRAY_RANGE_REF:
12272 3723700 : normal_inner_ref:
12273 4605537 : {
12274 4605537 : machine_mode mode1, mode2;
12275 4605537 : poly_int64 bitsize, bitpos, bytepos;
12276 4605537 : tree offset;
12277 4605537 : int reversep, volatilep = 0;
12278 4605537 : tree tem
12279 4605537 : = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
12280 : &unsignedp, &reversep, &volatilep);
12281 4605537 : rtx orig_op0, memloc;
12282 4605537 : bool clear_mem_expr = false;
12283 4605537 : bool must_force_mem;
12284 :
12285 : /* If we got back the original object, something is wrong. Perhaps
12286 : we are evaluating an expression too early. In any event, don't
12287 : infinitely recurse. */
12288 4605537 : gcc_assert (tem != exp);
12289 :
12290 : /* Make sure bitpos is not negative, this can wreak havoc later. */
12291 4605537 : if (maybe_lt (bitpos, 0))
12292 : {
12293 249 : gcc_checking_assert (offset == NULL_TREE);
12294 249 : offset = size_int (bits_to_bytes_round_down (bitpos));
12295 249 : bitpos = num_trailing_bits (bitpos);
12296 : }
12297 :
12298 : /* If we have either an offset, a BLKmode result, or a reference
12299 : outside the underlying object, we must force it to memory.
12300 : Such a case can occur in Ada if we have unchecked conversion
12301 : of an expression from a scalar type to an aggregate type or
12302 : for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
12303 : passed a partially uninitialized object or a view-conversion
12304 : to a larger size. */
12305 9211074 : must_force_mem = offset != NULL_TREE
12306 4326923 : || mode1 == BLKmode
12307 8860424 : || (mode == BLKmode
12308 0 : && !int_mode_for_size (bitsize, 1).exists ());
12309 :
12310 524433 : const enum expand_modifier tem_modifier
12311 : = must_force_mem
12312 : ? EXPAND_MEMORY
12313 4254887 : : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
12314 :
12315 : /* If TEM's type is a union of variable size, pass TARGET to the inner
12316 : computation, since it will need a temporary and TARGET is known
12317 : to have to do. This occurs in unchecked conversion in Ada. */
12318 4605537 : const rtx tem_target
12319 4605537 : = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12320 36700 : && COMPLETE_TYPE_P (TREE_TYPE (tem))
12321 36695 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
12322 0 : && modifier != EXPAND_STACK_PARM
12323 4605537 : ? target
12324 : : NULL_RTX;
12325 :
12326 9211074 : orig_op0 = op0
12327 4605537 : = expand_expr_real (tem, tem_target, VOIDmode, tem_modifier, NULL,
12328 : true);
12329 :
12330 : /* If the field has a mode, we want to access it in the
12331 : field's mode, not the computed mode.
12332 : If a MEM has VOIDmode (external with incomplete type),
12333 : use BLKmode for it instead. */
12334 4605537 : if (MEM_P (op0))
12335 : {
12336 4266241 : if (mode1 != VOIDmode)
12337 4111014 : op0 = adjust_address (op0, mode1, 0);
12338 155227 : else if (GET_MODE (op0) == VOIDmode)
12339 0 : op0 = adjust_address (op0, BLKmode, 0);
12340 : }
12341 :
12342 4605537 : mode2
12343 4605537 : = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
12344 :
12345 : /* See above for the rationale. */
12346 9211074 : if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
12347 2907841 : must_force_mem = true;
12348 :
12349 : /* Handle CONCAT first. */
12350 4605537 : if (GET_CODE (op0) == CONCAT && !must_force_mem)
12351 : {
12352 114 : if (known_eq (bitpos, 0)
12353 206 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
12354 98 : && COMPLEX_MODE_P (mode1)
12355 93 : && COMPLEX_MODE_P (GET_MODE (op0))
12356 393 : && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
12357 186 : == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
12358 : {
12359 93 : if (reversep)
12360 0 : op0 = flip_storage_order (GET_MODE (op0), op0);
12361 93 : if (mode1 != GET_MODE (op0))
12362 : {
12363 : rtx parts[2];
12364 0 : for (int i = 0; i < 2; i++)
12365 : {
12366 0 : rtx op = read_complex_part (op0, i != 0);
12367 0 : if (GET_CODE (op) == SUBREG)
12368 0 : op = force_reg (GET_MODE (op), op);
12369 0 : temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
12370 0 : if (temp)
12371 : op = temp;
12372 : else
12373 : {
12374 0 : if (!REG_P (op) && !MEM_P (op))
12375 0 : op = force_reg (GET_MODE (op), op);
12376 0 : op = gen_lowpart (GET_MODE_INNER (mode1), op);
12377 : }
12378 0 : parts[i] = op;
12379 : }
12380 0 : op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
12381 : }
12382 93 : return op0;
12383 : }
12384 21 : if (known_eq (bitpos, 0)
12385 20 : && known_eq (bitsize,
12386 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12387 23 : && maybe_ne (bitsize, 0))
12388 : {
12389 : op0 = XEXP (op0, 0);
12390 : mode2 = GET_MODE (op0);
12391 : }
12392 19 : else if (known_eq (bitpos,
12393 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12394 4 : && known_eq (bitsize,
12395 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
12396 0 : && maybe_ne (bitpos, 0)
12397 19 : && maybe_ne (bitsize, 0))
12398 : {
12399 0 : op0 = XEXP (op0, 1);
12400 0 : bitpos = 0;
12401 0 : mode2 = GET_MODE (op0);
12402 : }
12403 : else
12404 : /* Otherwise force into memory. */
12405 : must_force_mem = true;
12406 : }
12407 :
12408 : /* If this is a constant, put it in a register if it is a legitimate
12409 : constant and we don't need a memory reference. */
12410 4605444 : if (CONSTANT_P (op0)
12411 33 : && mode2 != BLKmode
12412 33 : && targetm.legitimate_constant_p (mode2, op0)
12413 4605465 : && !must_force_mem)
12414 21 : op0 = force_reg (mode2, op0);
12415 :
12416 : /* Otherwise, if this is a constant, try to force it to the constant
12417 : pool. Note that back-ends, e.g. MIPS, may refuse to do so if it
12418 : is a legitimate constant. */
12419 4605423 : else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
12420 12 : op0 = validize_mem (memloc);
12421 :
12422 : /* Otherwise, if this is a constant or the object is not in memory
12423 : and need be, put it there. */
12424 4605411 : else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
12425 : {
12426 1095 : machine_mode tem_mode = TYPE_MODE (TREE_TYPE (tem));
12427 1095 : poly_int64 size;
12428 1095 : if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
12429 0 : size = max_int_size_in_bytes (TREE_TYPE (tem));
12430 1095 : unsigned int align = TREE_CODE (tem) == SSA_NAME
12431 1095 : ? TYPE_ALIGN (TREE_TYPE (tem))
12432 1095 : : get_object_alignment (tem);
12433 1095 : if (STRICT_ALIGNMENT)
12434 : {
12435 : /* For STRICT_ALIGNMENT targets, when we force the operand to
12436 : memory, we may need to increase the alignment to meet the
12437 : expectation in later RTL lowering passes. The increased
12438 : alignment is capped by MAX_SUPPORTED_STACK_ALIGNMENT. */
12439 : if (tem_mode != BLKmode)
12440 : align = MAX (align, GET_MODE_ALIGNMENT (tem_mode));
12441 : else
12442 : align = MAX (align, TYPE_ALIGN (TREE_TYPE (tem)));
12443 : align = MIN (align, (unsigned) MAX_SUPPORTED_STACK_ALIGNMENT);
12444 : }
12445 1095 : memloc = assign_stack_local (tem_mode, size, align);
12446 1095 : emit_move_insn (memloc, op0);
12447 1095 : op0 = memloc;
12448 1095 : clear_mem_expr = true;
12449 : }
12450 :
12451 4605444 : if (offset)
12452 : {
12453 278614 : machine_mode address_mode;
12454 278614 : rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
12455 : EXPAND_SUM);
12456 :
12457 278614 : gcc_assert (MEM_P (op0));
12458 :
12459 278614 : address_mode = get_address_mode (op0);
12460 278614 : if (GET_MODE (offset_rtx) != address_mode)
12461 : {
12462 : /* We cannot be sure that the RTL in offset_rtx is valid outside
12463 : of a memory address context, so force it into a register
12464 : before attempting to convert it to the desired mode. */
12465 422 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
12466 422 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
12467 : }
12468 :
12469 : /* See the comment in expand_assignment for the rationale. */
12470 278614 : if (mode1 != VOIDmode
12471 278398 : && maybe_ne (bitpos, 0)
12472 74431 : && maybe_gt (bitsize, 0)
12473 353045 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12474 352506 : && multiple_p (bitpos, bitsize)
12475 147784 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
12476 352506 : && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
12477 : {
12478 73537 : op0 = adjust_address (op0, mode1, bytepos);
12479 73537 : bitpos = 0;
12480 : }
12481 :
12482 278614 : op0 = offset_address (op0, offset_rtx,
12483 : highest_pow2_factor (offset));
12484 : }
12485 :
12486 : /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
12487 : record its alignment as BIGGEST_ALIGNMENT. */
12488 4605444 : if (MEM_P (op0)
12489 4267348 : && known_eq (bitpos, 0)
12490 1444371 : && offset != 0
12491 4883014 : && is_aligning_offset (offset, tem))
12492 0 : set_mem_align (op0, BIGGEST_ALIGNMENT);
12493 :
12494 : /* Don't forget about volatility even if this is a bitfield. */
12495 4605444 : if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
12496 : {
12497 528 : if (op0 == orig_op0)
12498 158 : op0 = copy_rtx (op0);
12499 :
12500 528 : MEM_VOLATILE_P (op0) = 1;
12501 : }
12502 :
12503 4605444 : if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
12504 : {
12505 6 : if (op0 == orig_op0)
12506 0 : op0 = copy_rtx (op0);
12507 :
12508 6 : set_mem_align (op0, BITS_PER_UNIT);
12509 : }
12510 :
12511 : /* In cases where an aligned union has an unaligned object
12512 : as a field, we might be extracting a BLKmode value from
12513 : an integer-mode (e.g., SImode) object. Handle this case
12514 : by doing the extract into an object as wide as the field
12515 : (which we know to be the width of a basic mode), then
12516 : storing into memory, and changing the mode to BLKmode. */
12517 4605444 : if (mode1 == VOIDmode
12518 4378452 : || REG_P (op0) || GET_CODE (op0) == SUBREG
12519 4112087 : || (mode1 != BLKmode && ! direct_load[(int) mode1]
12520 27257 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
12521 23098 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
12522 : && modifier != EXPAND_CONST_ADDRESS
12523 15389 : && modifier != EXPAND_INITIALIZER
12524 15389 : && modifier != EXPAND_MEMORY)
12525 : /* If the bitfield is volatile and the bitsize
12526 : is narrower than the access size of the bitfield,
12527 : we need to extract bitfields from the access. */
12528 4096698 : || (volatilep && TREE_CODE (exp) == COMPONENT_REF
12529 1462 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
12530 10 : && mode1 != BLKmode
12531 20 : && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
12532 : /* If the field isn't aligned enough to fetch as a memref,
12533 : fetch it as a bit field. */
12534 4096689 : || (mode1 != BLKmode
12535 4023791 : && (((MEM_P (op0)
12536 4023791 : ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
12537 7903623 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
12538 0 : : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
12539 0 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
12540 75299 : && modifier != EXPAND_MEMORY
12541 75299 : && ((modifier == EXPAND_CONST_ADDRESS
12542 75299 : || modifier == EXPAND_INITIALIZER)
12543 75299 : ? STRICT_ALIGNMENT
12544 75299 : : targetm.slow_unaligned_access (mode1,
12545 75299 : MEM_ALIGN (op0))))
12546 4023791 : || !multiple_p (bitpos, BITS_PER_UNIT)))
12547 : /* If the type and the field are a constant size and the
12548 : size of the type isn't the same size as the bitfield,
12549 : we must use bitfield operations. */
12550 12725924 : || (known_size_p (bitsize)
12551 4096689 : && TYPE_SIZE (TREE_TYPE (exp))
12552 4096689 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
12553 4096689 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
12554 : bitsize)))
12555 : {
12556 508784 : machine_mode ext_mode = mode;
12557 :
12558 508784 : if (ext_mode == BLKmode
12559 508784 : && ! (target != 0 && MEM_P (op0)
12560 22 : && MEM_P (target)
12561 22 : && multiple_p (bitpos, BITS_PER_UNIT)))
12562 3 : ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
12563 :
12564 508784 : if (ext_mode == BLKmode)
12565 : {
12566 25 : if (target == 0)
12567 3 : target = assign_temp (type, 1, 1);
12568 :
12569 : /* ??? Unlike the similar test a few lines below, this one is
12570 : very likely obsolete. */
12571 25 : if (known_eq (bitsize, 0))
12572 : return target;
12573 :
12574 : /* In this case, BITPOS must start at a byte boundary and
12575 : TARGET, if specified, must be a MEM. */
12576 25 : gcc_assert (MEM_P (op0)
12577 : && (!target || MEM_P (target)));
12578 :
12579 25 : bytepos = exact_div (bitpos, BITS_PER_UNIT);
12580 25 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
12581 50 : emit_block_move (target,
12582 : adjust_address (op0, VOIDmode, bytepos),
12583 25 : gen_int_mode (bytesize, Pmode),
12584 : (modifier == EXPAND_STACK_PARM
12585 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
12586 :
12587 25 : return target;
12588 : }
12589 :
12590 : /* If we have nothing to extract, the result will be 0 for targets
12591 : with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise. Always
12592 : return 0 for the sake of consistency, as reading a zero-sized
12593 : bitfield is valid in Ada and the value is fully specified. */
12594 508759 : if (known_eq (bitsize, 0))
12595 0 : return const0_rtx;
12596 :
12597 508759 : op0 = validize_mem (op0);
12598 :
12599 508759 : if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
12600 47437 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12601 :
12602 : /* If the result has aggregate type and the extraction is done in
12603 : an integral mode, then the field may be not aligned on a byte
12604 : boundary; in this case, if it has reverse storage order, it
12605 : needs to be extracted as a scalar field with reverse storage
12606 : order and put back into memory order afterwards. */
12607 508759 : if (AGGREGATE_TYPE_P (type)
12608 4834 : && GET_MODE_CLASS (ext_mode) == MODE_INT)
12609 4752 : reversep = TYPE_REVERSE_STORAGE_ORDER (type);
12610 :
12611 508759 : gcc_checking_assert (known_ge (bitpos, 0));
12612 521391 : op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
12613 : (modifier == EXPAND_STACK_PARM
12614 : ? NULL_RTX : target),
12615 : ext_mode, ext_mode, reversep, alt_rtl);
12616 :
12617 : /* If the result has aggregate type and the mode of OP0 is an
12618 : integral mode then, if BITSIZE is narrower than this mode
12619 : and this is for big-endian data, we must put the field
12620 : into the high-order bits. And we must also put it back
12621 : into memory order if it has been previously reversed. */
12622 508759 : scalar_int_mode op0_mode;
12623 508759 : if (AGGREGATE_TYPE_P (type)
12624 508759 : && is_int_mode (GET_MODE (op0), &op0_mode))
12625 : {
12626 4752 : HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
12627 :
12628 4752 : gcc_checking_assert (known_le (bitsize, size));
12629 4752 : if (maybe_lt (bitsize, size)
12630 4752 : && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
12631 0 : op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
12632 : size - bitsize, op0, 1);
12633 :
12634 4752 : if (reversep)
12635 0 : op0 = flip_storage_order (op0_mode, op0);
12636 : }
12637 :
12638 : /* If the result type is BLKmode, store the data into a temporary
12639 : of the appropriate type, but with the mode corresponding to the
12640 : mode for the data we have (op0's mode). */
12641 508759 : if (mode == BLKmode)
12642 : {
12643 0 : rtx new_rtx
12644 0 : = assign_stack_temp_for_type (ext_mode,
12645 0 : GET_MODE_BITSIZE (ext_mode),
12646 : type);
12647 0 : emit_move_insn (new_rtx, op0);
12648 0 : op0 = copy_rtx (new_rtx);
12649 0 : PUT_MODE (op0, BLKmode);
12650 : }
12651 :
12652 508759 : return op0;
12653 : }
12654 :
12655 : /* If the result is BLKmode, use that to access the object
12656 : now as well. */
12657 4096660 : if (mode == BLKmode)
12658 72873 : mode1 = BLKmode;
12659 :
12660 : /* Get a reference to just this component. */
12661 4096660 : bytepos = bits_to_bytes_round_down (bitpos);
12662 4096660 : if (modifier == EXPAND_CONST_ADDRESS
12663 4096660 : || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
12664 164352 : op0 = adjust_address_nv (op0, mode1, bytepos);
12665 : else
12666 3932308 : op0 = adjust_address (op0, mode1, bytepos);
12667 :
12668 4096660 : if (op0 == orig_op0)
12669 126748 : op0 = copy_rtx (op0);
12670 :
12671 : /* Don't set memory attributes if the base expression is
12672 : SSA_NAME that got expanded as a MEM or a CONSTANT. In that case,
12673 : we should just honor its original memory attributes. */
12674 4096660 : if (!(TREE_CODE (tem) == SSA_NAME
12675 8884 : && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
12676 4087776 : set_mem_attributes (op0, exp, 0);
12677 :
12678 4096660 : if (REG_P (XEXP (op0, 0)))
12679 662722 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12680 :
12681 : /* If op0 is a temporary because the original expressions was forced
12682 : to memory, clear MEM_EXPR so that the original expression cannot
12683 : be marked as addressable through MEM_EXPR of the temporary. */
12684 4096660 : if (clear_mem_expr)
12685 1061 : set_mem_expr (op0, NULL_TREE);
12686 :
12687 4096660 : MEM_VOLATILE_P (op0) |= volatilep;
12688 :
12689 4096660 : if (reversep
12690 : && modifier != EXPAND_MEMORY
12691 491 : && modifier != EXPAND_WRITE)
12692 491 : op0 = flip_storage_order (mode1, op0);
12693 :
12694 4096660 : op0 = EXTEND_BITINT (op0);
12695 :
12696 4096660 : if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
12697 : || modifier == EXPAND_CONST_ADDRESS
12698 0 : || modifier == EXPAND_INITIALIZER)
12699 : return op0;
12700 :
12701 0 : if (target == 0)
12702 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
12703 :
12704 0 : convert_move (target, op0, unsignedp);
12705 0 : return target;
12706 : }
12707 :
12708 84487 : case OBJ_TYPE_REF:
12709 84487 : return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
12710 :
12711 6771535 : case CALL_EXPR:
12712 : /* All valid uses of __builtin_va_arg_pack () are removed during
12713 : inlining. */
12714 6771535 : if (CALL_EXPR_VA_ARG_PACK (exp))
12715 6 : error ("invalid use of %<__builtin_va_arg_pack ()%>");
12716 6771535 : {
12717 6771535 : tree fndecl = get_callee_fndecl (exp), attr;
12718 :
12719 6771535 : if (fndecl
12720 : /* Don't diagnose the error attribute in thunks, those are
12721 : artificially created. */
12722 6585464 : && !CALL_FROM_THUNK_P (exp)
12723 13353430 : && (attr = lookup_attribute ("error",
12724 6581895 : DECL_ATTRIBUTES (fndecl))) != NULL)
12725 : {
12726 5 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12727 10 : error ("call to %qs declared with attribute error: %s",
12728 : identifier_to_locale (ident),
12729 5 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12730 : }
12731 6771535 : if (fndecl
12732 : /* Don't diagnose the warning attribute in thunks, those are
12733 : artificially created. */
12734 6585464 : && !CALL_FROM_THUNK_P (exp)
12735 13353430 : && (attr = lookup_attribute ("warning",
12736 6581895 : DECL_ATTRIBUTES (fndecl))) != NULL)
12737 : {
12738 17 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12739 34 : warning_at (EXPR_LOCATION (exp),
12740 17 : OPT_Wattribute_warning,
12741 : "call to %qs declared with attribute warning: %s",
12742 : identifier_to_locale (ident),
12743 17 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12744 : }
12745 :
12746 : /* Check for a built-in function. */
12747 6771535 : if (fndecl && fndecl_built_in_p (fndecl))
12748 : {
12749 2003033 : gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
12750 2003033 : return expand_builtin (exp, target, subtarget, tmode, ignore);
12751 : }
12752 : }
12753 4768502 : temp = expand_call (exp, target, ignore);
12754 4768500 : return EXTEND_BITINT (temp);
12755 :
12756 347831 : case VIEW_CONVERT_EXPR:
12757 347831 : op0 = NULL_RTX;
12758 :
12759 : /* If we are converting to BLKmode, try to avoid an intermediate
12760 : temporary by fetching an inner memory reference. */
12761 347831 : if (mode == BLKmode
12762 74203 : && poly_int_tree_p (TYPE_SIZE (type))
12763 74203 : && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
12764 347831 : && handled_component_p (treeop0))
12765 : {
12766 0 : machine_mode mode1;
12767 0 : poly_int64 bitsize, bitpos, bytepos;
12768 0 : tree offset;
12769 0 : int reversep, volatilep = 0;
12770 0 : tree tem
12771 0 : = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
12772 : &unsignedp, &reversep, &volatilep);
12773 :
12774 : /* ??? We should work harder and deal with non-zero offsets. */
12775 0 : if (!offset
12776 0 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12777 0 : && !reversep
12778 0 : && known_size_p (bitsize)
12779 0 : && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
12780 : {
12781 : /* See the normal_inner_ref case for the rationale. */
12782 0 : rtx orig_op0
12783 0 : = expand_expr_real (tem,
12784 0 : (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12785 0 : && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
12786 : != INTEGER_CST)
12787 0 : && modifier != EXPAND_STACK_PARM
12788 : ? target : NULL_RTX),
12789 : VOIDmode,
12790 : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
12791 : NULL, true);
12792 :
12793 0 : if (MEM_P (orig_op0))
12794 : {
12795 0 : op0 = orig_op0;
12796 :
12797 : /* Get a reference to just this component. */
12798 0 : if (modifier == EXPAND_CONST_ADDRESS
12799 : || modifier == EXPAND_SUM
12800 0 : || modifier == EXPAND_INITIALIZER)
12801 0 : op0 = adjust_address_nv (op0, mode, bytepos);
12802 : else
12803 0 : op0 = adjust_address (op0, mode, bytepos);
12804 :
12805 0 : if (op0 == orig_op0)
12806 0 : op0 = copy_rtx (op0);
12807 :
12808 0 : set_mem_attributes (op0, treeop0, 0);
12809 0 : if (REG_P (XEXP (op0, 0)))
12810 0 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12811 :
12812 0 : MEM_VOLATILE_P (op0) |= volatilep;
12813 : }
12814 : }
12815 : }
12816 :
12817 0 : if (!op0)
12818 347831 : op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
12819 347831 : NULL, inner_reference_p || mode == BLKmode);
12820 :
12821 : /* If the input and output modes are both the same, we are done. */
12822 347831 : if (mode == GET_MODE (op0))
12823 : ;
12824 : /* Similarly if the output mode is BLKmode and input is a MEM,
12825 : adjust_address done below is all we need. */
12826 148805 : else if (mode == BLKmode && MEM_P (op0))
12827 : ;
12828 : /* If neither mode is BLKmode, and both modes are the same size
12829 : then we can use gen_lowpart. */
12830 : else if (mode != BLKmode
12831 148771 : && GET_MODE (op0) != BLKmode
12832 147444 : && known_eq (GET_MODE_PRECISION (mode),
12833 : GET_MODE_PRECISION (GET_MODE (op0)))
12834 143547 : && !COMPLEX_MODE_P (GET_MODE (op0)))
12835 : {
12836 142143 : if (GET_CODE (op0) == SUBREG)
12837 108 : op0 = force_reg (GET_MODE (op0), op0);
12838 142143 : temp = gen_lowpart_common (mode, op0);
12839 142143 : if (temp)
12840 : op0 = temp;
12841 : else
12842 : {
12843 27368 : if (!REG_P (op0) && !MEM_P (op0))
12844 18 : op0 = force_reg (GET_MODE (op0), op0);
12845 27368 : op0 = gen_lowpart (mode, op0);
12846 : }
12847 : }
12848 : /* If both types are integral, convert from one mode to the other. */
12849 6660 : else if (INTEGRAL_TYPE_P (type)
12850 3129 : && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
12851 0 : && mode != BLKmode
12852 6660 : && GET_MODE (op0) != BLKmode)
12853 0 : op0 = convert_modes (mode, GET_MODE (op0), op0,
12854 0 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
12855 : /* If the output type is a bit-field type, do an extraction. */
12856 6660 : else if (reduce_bit_field
12857 2 : && mode != BLKmode
12858 2 : && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
12859 0 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12860 0 : TYPE_UNSIGNED (type), NULL_RTX,
12861 : mode, mode, false, NULL);
12862 : /* If source is a complex number and destination is a
12863 : two-component vector with same inner type, try to use
12864 : vector initialization. */
12865 6660 : else if ((temp = try_expand_complex_as_vector (mode, op0, target))
12866 : != NULL_RTX)
12867 : return temp;
12868 : /* As a last resort, spill op0 to memory, and reload it in a
12869 : different mode. */
12870 6631 : else if (!MEM_P (op0))
12871 : {
12872 : /* If the operand is not a MEM, force it into memory. Since we
12873 : are going to be changing the mode of the MEM, don't call
12874 : force_const_mem for constants because we don't allow pool
12875 : constants to change mode. */
12876 5294 : tree inner_type = TREE_TYPE (treeop0);
12877 :
12878 5294 : gcc_assert (!TREE_ADDRESSABLE (exp));
12879 :
12880 5294 : if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
12881 5290 : target
12882 : = assign_stack_temp_for_type
12883 5290 : (TYPE_MODE (inner_type),
12884 10580 : GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
12885 :
12886 5294 : emit_move_insn (target, op0);
12887 5294 : op0 = target;
12888 :
12889 5294 : if (reduce_bit_field && mode != BLKmode)
12890 2 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12891 2 : TYPE_UNSIGNED (type), NULL_RTX,
12892 : mode, mode, false, NULL);
12893 : }
12894 :
12895 : /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the
12896 : output type is such that the operand is known to be aligned, indicate
12897 : that it is. Otherwise, we need only be concerned about alignment for
12898 : non-BLKmode results. */
12899 347800 : if (MEM_P (op0))
12900 : {
12901 127580 : enum insn_code icode;
12902 :
12903 127580 : if (modifier != EXPAND_WRITE
12904 127580 : && modifier != EXPAND_MEMORY
12905 127580 : && !inner_reference_p
12906 127579 : && mode != BLKmode
12907 180956 : && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
12908 : {
12909 : /* If the target does have special handling for unaligned
12910 : loads of mode then use them. */
12911 15648 : if ((icode = optab_handler (movmisalign_optab, mode))
12912 : != CODE_FOR_nothing)
12913 : {
12914 1774 : rtx reg;
12915 :
12916 1774 : op0 = adjust_address (op0, mode, 0);
12917 : /* We've already validated the memory, and we're creating a
12918 : new pseudo destination. The predicates really can't
12919 : fail. */
12920 1774 : reg = gen_reg_rtx (mode);
12921 :
12922 : /* Nor can the insn generator. */
12923 1774 : rtx_insn *insn = GEN_FCN (icode) (reg, op0);
12924 1774 : emit_insn (insn);
12925 1774 : return reg;
12926 : }
12927 : else if (STRICT_ALIGNMENT)
12928 : {
12929 : poly_uint64 mode_size = GET_MODE_SIZE (mode);
12930 : poly_uint64 temp_size = mode_size;
12931 : if (GET_MODE (op0) != BLKmode)
12932 : temp_size = upper_bound (temp_size,
12933 : GET_MODE_SIZE (GET_MODE (op0)));
12934 : rtx new_rtx
12935 : = assign_stack_temp_for_type (mode, temp_size, type);
12936 : rtx new_with_op0_mode
12937 : = adjust_address (new_rtx, GET_MODE (op0), 0);
12938 :
12939 : gcc_assert (!TREE_ADDRESSABLE (exp));
12940 :
12941 : if (GET_MODE (op0) == BLKmode)
12942 : {
12943 : rtx size_rtx = gen_int_mode (mode_size, Pmode);
12944 : emit_block_move (new_with_op0_mode, op0, size_rtx,
12945 : (modifier == EXPAND_STACK_PARM
12946 : ? BLOCK_OP_CALL_PARM
12947 : : BLOCK_OP_NORMAL));
12948 : }
12949 : else
12950 : emit_move_insn (new_with_op0_mode, op0);
12951 :
12952 : op0 = new_rtx;
12953 : }
12954 : }
12955 :
12956 125806 : op0 = adjust_address (op0, mode, 0);
12957 : }
12958 :
12959 : return op0;
12960 :
12961 63582 : case MODIFY_EXPR:
12962 63582 : {
12963 63582 : tree lhs = treeop0;
12964 63582 : tree rhs = treeop1;
12965 63582 : gcc_assert (ignore);
12966 :
12967 : /* Check for |= or &= of a bitfield of size one into another bitfield
12968 : of size 1. In this case, (unless we need the result of the
12969 : assignment) we can do this more efficiently with a
12970 : test followed by an assignment, if necessary.
12971 :
12972 : ??? At this point, we can't get a BIT_FIELD_REF here. But if
12973 : things change so we do, this code should be enhanced to
12974 : support it. */
12975 63582 : if (TREE_CODE (lhs) == COMPONENT_REF
12976 60510 : && (TREE_CODE (rhs) == BIT_IOR_EXPR
12977 60510 : || TREE_CODE (rhs) == BIT_AND_EXPR)
12978 0 : && TREE_OPERAND (rhs, 0) == lhs
12979 0 : && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
12980 0 : && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
12981 63582 : && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
12982 : {
12983 0 : rtx_code_label *label = gen_label_rtx ();
12984 0 : int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
12985 0 : profile_probability prob = profile_probability::uninitialized ();
12986 0 : if (value)
12987 0 : jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
12988 : else
12989 0 : jumpif (TREE_OPERAND (rhs, 1), label, prob);
12990 0 : expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value),
12991 : false);
12992 0 : do_pending_stack_adjust ();
12993 0 : emit_label (label);
12994 0 : return const0_rtx;
12995 : }
12996 :
12997 63582 : expand_assignment (lhs, rhs, false);
12998 63582 : return const0_rtx;
12999 : }
13000 :
13001 13191271 : case ADDR_EXPR:
13002 13191271 : return expand_expr_addr_expr (exp, target, tmode, modifier);
13003 :
13004 172083 : case REALPART_EXPR:
13005 172083 : op0 = expand_normal (treeop0);
13006 172083 : return read_complex_part (op0, false);
13007 :
13008 195908 : case IMAGPART_EXPR:
13009 195908 : op0 = expand_normal (treeop0);
13010 195908 : return read_complex_part (op0, true);
13011 :
13012 0 : case RETURN_EXPR:
13013 0 : case LABEL_EXPR:
13014 0 : case GOTO_EXPR:
13015 0 : case SWITCH_EXPR:
13016 0 : case ASM_EXPR:
13017 : /* Expanded in cfgexpand.cc. */
13018 0 : gcc_unreachable ();
13019 :
13020 0 : case TRY_CATCH_EXPR:
13021 0 : case CATCH_EXPR:
13022 0 : case EH_FILTER_EXPR:
13023 0 : case TRY_FINALLY_EXPR:
13024 0 : case EH_ELSE_EXPR:
13025 : /* Lowered by tree-eh.cc. */
13026 0 : gcc_unreachable ();
13027 :
13028 0 : case WITH_CLEANUP_EXPR:
13029 0 : case CLEANUP_POINT_EXPR:
13030 0 : case TARGET_EXPR:
13031 0 : case CASE_LABEL_EXPR:
13032 0 : case VA_ARG_EXPR:
13033 0 : case BIND_EXPR:
13034 0 : case INIT_EXPR:
13035 0 : case CONJ_EXPR:
13036 0 : case COMPOUND_EXPR:
13037 0 : case PREINCREMENT_EXPR:
13038 0 : case PREDECREMENT_EXPR:
13039 0 : case POSTINCREMENT_EXPR:
13040 0 : case POSTDECREMENT_EXPR:
13041 0 : case LOOP_EXPR:
13042 0 : case EXIT_EXPR:
13043 0 : case COMPOUND_LITERAL_EXPR:
13044 : /* Lowered by gimplify.cc. */
13045 0 : gcc_unreachable ();
13046 :
13047 0 : case FDESC_EXPR:
13048 : /* Function descriptors are not valid except for as
13049 : initialization constants, and should not be expanded. */
13050 0 : gcc_unreachable ();
13051 :
13052 258 : case WITH_SIZE_EXPR:
13053 : /* WITH_SIZE_EXPR expands to its first argument. The caller should
13054 : have pulled out the size to use in whatever context it needed. */
13055 258 : return expand_expr_real (treeop0, original_target, tmode,
13056 258 : modifier, alt_rtl, inner_reference_p);
13057 :
13058 1847952 : default:
13059 1847952 : return expand_expr_real_2 (&ops, target, tmode, modifier);
13060 : }
13061 : }
13062 : #undef EXTEND_BITINT
13063 :
13064 : /* Subroutine of above: reduce EXP to the precision of TYPE (in the
13065 : signedness of TYPE), possibly returning the result in TARGET.
13066 : TYPE is known to be a partial integer type. */
13067 : static rtx
13068 88720 : reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
13069 : {
13070 88720 : scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
13071 88720 : HOST_WIDE_INT prec = TYPE_PRECISION (type);
13072 88720 : gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
13073 : && (!target || GET_MODE (target) == mode));
13074 :
13075 : /* For constant values, reduce using wide_int_to_tree. */
13076 88720 : if (poly_int_rtx_p (exp))
13077 : {
13078 0 : auto value = wi::to_poly_wide (exp, mode);
13079 0 : tree t = wide_int_to_tree (type, value);
13080 0 : return expand_expr (t, target, VOIDmode, EXPAND_NORMAL);
13081 : }
13082 88720 : else if (TYPE_UNSIGNED (type))
13083 : {
13084 69784 : rtx mask = immed_wide_int_const
13085 69784 : (wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
13086 69784 : return expand_and (mode, exp, mask, target);
13087 : }
13088 : else
13089 : {
13090 18936 : int count = GET_MODE_PRECISION (mode) - prec;
13091 18936 : exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
13092 18936 : return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
13093 : }
13094 : }
13095 :
13096 : /* Subroutine of above: returns true if OFFSET corresponds to an offset that
13097 : when applied to the address of EXP produces an address known to be
13098 : aligned more than BIGGEST_ALIGNMENT. */
13099 :
13100 : static bool
13101 277570 : is_aligning_offset (const_tree offset, const_tree exp)
13102 : {
13103 : /* Strip off any conversions. */
13104 295002 : while (CONVERT_EXPR_P (offset))
13105 17432 : offset = TREE_OPERAND (offset, 0);
13106 :
13107 : /* We must now have a BIT_AND_EXPR with a constant that is one less than
13108 : power of 2 and which is larger than BIGGEST_ALIGNMENT. */
13109 277570 : if (TREE_CODE (offset) != BIT_AND_EXPR
13110 0 : || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
13111 0 : || compare_tree_int (TREE_OPERAND (offset, 1),
13112 0 : BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
13113 277570 : || !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
13114 277570 : return false;
13115 :
13116 : /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
13117 : It must be NEGATE_EXPR. Then strip any more conversions. */
13118 0 : offset = TREE_OPERAND (offset, 0);
13119 0 : while (CONVERT_EXPR_P (offset))
13120 0 : offset = TREE_OPERAND (offset, 0);
13121 :
13122 0 : if (TREE_CODE (offset) != NEGATE_EXPR)
13123 : return false;
13124 :
13125 0 : offset = TREE_OPERAND (offset, 0);
13126 0 : while (CONVERT_EXPR_P (offset))
13127 0 : offset = TREE_OPERAND (offset, 0);
13128 :
13129 : /* This must now be the address of EXP. */
13130 0 : return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
13131 : }
13132 :
13133 : /* Return a STRING_CST corresponding to ARG's constant initializer either
13134 : if it's a string constant, or, when VALREP is set, any other constant,
13135 : or null otherwise.
13136 : On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
13137 : within the byte string that ARG is references. If nonnull set *MEM_SIZE
13138 : to the size of the byte string. If nonnull, set *DECL to the constant
13139 : declaration ARG refers to. */
13140 :
13141 : static tree
13142 15615482 : constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
13143 : bool valrep = false)
13144 : {
13145 15615482 : tree dummy = NULL_TREE;
13146 15615482 : if (!mem_size)
13147 11013 : mem_size = &dummy;
13148 :
13149 : /* Store the type of the original expression before conversions
13150 : via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
13151 : removed. */
13152 15615482 : tree argtype = TREE_TYPE (arg);
13153 :
13154 15615482 : tree array;
13155 15615482 : STRIP_NOPS (arg);
13156 :
13157 : /* Non-constant index into the character array in an ARRAY_REF
13158 : expression or null. */
13159 15615482 : tree varidx = NULL_TREE;
13160 :
13161 15615482 : poly_int64 base_off = 0;
13162 :
13163 15615482 : if (TREE_CODE (arg) == ADDR_EXPR)
13164 : {
13165 6427910 : arg = TREE_OPERAND (arg, 0);
13166 6427910 : tree ref = arg;
13167 6427910 : if (TREE_CODE (arg) == ARRAY_REF)
13168 : {
13169 565231 : tree idx = TREE_OPERAND (arg, 1);
13170 565231 : if (TREE_CODE (idx) != INTEGER_CST)
13171 : {
13172 : /* From a pointer (but not array) argument extract the variable
13173 : index to prevent get_addr_base_and_unit_offset() from failing
13174 : due to it. Use it later to compute the non-constant offset
13175 : into the string and return it to the caller. */
13176 166989 : varidx = idx;
13177 166989 : ref = TREE_OPERAND (arg, 0);
13178 :
13179 166989 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
13180 : return NULL_TREE;
13181 :
13182 28115 : if (!integer_zerop (array_ref_low_bound (arg)))
13183 : return NULL_TREE;
13184 :
13185 27355 : if (!integer_onep (array_ref_element_size (arg)))
13186 : return NULL_TREE;
13187 : }
13188 : }
13189 6287173 : array = get_addr_base_and_unit_offset (ref, &base_off);
13190 6287173 : if (!array
13191 6239739 : || (TREE_CODE (array) != VAR_DECL
13192 6239739 : && TREE_CODE (array) != CONST_DECL
13193 3917092 : && TREE_CODE (array) != STRING_CST))
13194 : return NULL_TREE;
13195 : }
13196 9187572 : else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
13197 : {
13198 26634 : tree arg0 = TREE_OPERAND (arg, 0);
13199 26634 : tree arg1 = TREE_OPERAND (arg, 1);
13200 :
13201 26634 : tree offset;
13202 26634 : tree str = string_constant (arg0, &offset, mem_size, decl);
13203 26634 : if (!str)
13204 : {
13205 17329 : str = string_constant (arg1, &offset, mem_size, decl);
13206 17329 : arg1 = arg0;
13207 : }
13208 :
13209 17329 : if (str)
13210 : {
13211 : /* Avoid pointers to arrays (see bug 86622). */
13212 9305 : if (POINTER_TYPE_P (TREE_TYPE (arg))
13213 9305 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
13214 1890 : && !(decl && !*decl)
13215 11825 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
13216 1260 : && tree_fits_uhwi_p (*mem_size)
13217 1260 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
13218 1890 : return NULL_TREE;
13219 :
13220 7415 : tree type = TREE_TYPE (offset);
13221 7415 : arg1 = fold_convert (type, arg1);
13222 7415 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
13223 7415 : return str;
13224 : }
13225 : return NULL_TREE;
13226 : }
13227 9160938 : else if (TREE_CODE (arg) == SSA_NAME)
13228 : {
13229 3906174 : gimple *stmt = SSA_NAME_DEF_STMT (arg);
13230 3906174 : if (!is_gimple_assign (stmt))
13231 : return NULL_TREE;
13232 :
13233 1043944 : tree rhs1 = gimple_assign_rhs1 (stmt);
13234 1043944 : tree_code code = gimple_assign_rhs_code (stmt);
13235 1043944 : if (code == ADDR_EXPR)
13236 234010 : return string_constant (rhs1, ptr_offset, mem_size, decl);
13237 809934 : else if (code != POINTER_PLUS_EXPR)
13238 : return NULL_TREE;
13239 :
13240 190303 : tree offset;
13241 190303 : if (tree str = string_constant (rhs1, &offset, mem_size, decl))
13242 : {
13243 : /* Avoid pointers to arrays (see bug 86622). */
13244 21604 : if (POINTER_TYPE_P (TREE_TYPE (rhs1))
13245 21604 : && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
13246 18907 : && !(decl && !*decl)
13247 37852 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
13248 8124 : && tree_fits_uhwi_p (*mem_size)
13249 8124 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
13250 15949 : return NULL_TREE;
13251 :
13252 5655 : tree rhs2 = gimple_assign_rhs2 (stmt);
13253 5655 : tree type = TREE_TYPE (offset);
13254 5655 : rhs2 = fold_convert (type, rhs2);
13255 5655 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
13256 5655 : return str;
13257 : }
13258 : return NULL_TREE;
13259 : }
13260 5254764 : else if (DECL_P (arg))
13261 : array = arg;
13262 : else
13263 : return NULL_TREE;
13264 :
13265 8645443 : tree offset = wide_int_to_tree (sizetype, base_off);
13266 8645443 : if (varidx)
13267 : {
13268 2258 : if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
13269 : return NULL_TREE;
13270 :
13271 1747 : gcc_assert (TREE_CODE (arg) == ARRAY_REF);
13272 1747 : tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
13273 1747 : if (TREE_CODE (chartype) != INTEGER_TYPE)
13274 : return NULL;
13275 :
13276 1591 : offset = fold_convert (sizetype, varidx);
13277 : }
13278 :
13279 8644776 : if (TREE_CODE (array) == STRING_CST)
13280 : {
13281 3526205 : *ptr_offset = fold_convert (sizetype, offset);
13282 3526205 : *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
13283 3526205 : if (decl)
13284 758852 : *decl = NULL_TREE;
13285 3526205 : gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
13286 : >= TREE_STRING_LENGTH (array));
13287 : return array;
13288 : }
13289 :
13290 5118571 : tree init = ctor_for_folding (array);
13291 5118571 : if (!init || init == error_mark_node)
13292 : return NULL_TREE;
13293 :
13294 158920 : if (valrep)
13295 : {
13296 58360 : HOST_WIDE_INT cstoff;
13297 58360 : if (!base_off.is_constant (&cstoff))
13298 : return NULL_TREE;
13299 :
13300 : /* Check that the host and target are sane. */
13301 58360 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13302 : return NULL_TREE;
13303 :
13304 58360 : HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
13305 58360 : if (typesz <= 0 || (int) typesz != typesz)
13306 : return NULL_TREE;
13307 :
13308 58207 : HOST_WIDE_INT size = typesz;
13309 58207 : if (VAR_P (array)
13310 58195 : && DECL_SIZE_UNIT (array)
13311 116402 : && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
13312 : {
13313 58195 : size = tree_to_shwi (DECL_SIZE_UNIT (array));
13314 58195 : gcc_checking_assert (size >= typesz);
13315 : }
13316 :
13317 : /* If value representation was requested convert the initializer
13318 : for the whole array or object into a string of bytes forming
13319 : its value representation and return it. */
13320 58207 : unsigned char *bytes = XNEWVEC (unsigned char, size);
13321 58207 : int r = native_encode_initializer (init, bytes, size);
13322 58207 : if (r < typesz)
13323 : {
13324 60 : XDELETEVEC (bytes);
13325 60 : return NULL_TREE;
13326 : }
13327 :
13328 58147 : if (r < size)
13329 0 : memset (bytes + r, '\0', size - r);
13330 :
13331 58147 : const char *p = reinterpret_cast<const char *>(bytes);
13332 58147 : init = build_string_literal (size, p, char_type_node);
13333 58147 : init = TREE_OPERAND (init, 0);
13334 58147 : init = TREE_OPERAND (init, 0);
13335 58147 : XDELETE (bytes);
13336 :
13337 58147 : *mem_size = size_int (TREE_STRING_LENGTH (init));
13338 58147 : *ptr_offset = wide_int_to_tree (ssizetype, base_off);
13339 :
13340 58147 : if (decl)
13341 0 : *decl = array;
13342 :
13343 58147 : return init;
13344 : }
13345 :
13346 100560 : if (TREE_CODE (init) == CONSTRUCTOR)
13347 : {
13348 : /* Convert the 64-bit constant offset to a wider type to avoid
13349 : overflow and use it to obtain the initializer for the subobject
13350 : it points into. */
13351 80926 : offset_int wioff;
13352 80926 : if (!base_off.is_constant (&wioff))
13353 155 : return NULL_TREE;
13354 :
13355 80926 : wioff *= BITS_PER_UNIT;
13356 80926 : if (!wi::fits_uhwi_p (wioff))
13357 : return NULL_TREE;
13358 :
13359 80818 : base_off = wioff.to_uhwi ();
13360 80818 : unsigned HOST_WIDE_INT fieldoff = 0;
13361 80818 : init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
13362 : &fieldoff);
13363 80818 : if (!init || init == error_mark_node)
13364 : return NULL_TREE;
13365 :
13366 80771 : HOST_WIDE_INT cstoff;
13367 80771 : if (!base_off.is_constant (&cstoff))
13368 : return NULL_TREE;
13369 :
13370 80771 : cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
13371 80771 : tree off = build_int_cst (sizetype, cstoff);
13372 80771 : if (varidx)
13373 944 : offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
13374 : else
13375 : offset = off;
13376 : }
13377 :
13378 100405 : *ptr_offset = offset;
13379 :
13380 100405 : tree inittype = TREE_TYPE (init);
13381 :
13382 100405 : if (TREE_CODE (init) == INTEGER_CST
13383 100405 : && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
13384 1108 : || TYPE_MAIN_VARIANT (inittype) == char_type_node))
13385 : {
13386 : /* Check that the host and target are sane. */
13387 901 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13388 : return NULL_TREE;
13389 :
13390 : /* For a reference to (address of) a single constant character,
13391 : store the native representation of the character in CHARBUF.
13392 : If the reference is to an element of an array or a member
13393 : of a struct, only consider narrow characters until ctors
13394 : for wide character arrays are transformed to STRING_CSTs
13395 : like those for narrow arrays. */
13396 901 : unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
13397 901 : int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
13398 901 : if (len > 0)
13399 : {
13400 : /* Construct a string literal with elements of INITTYPE and
13401 : the representation above. Then strip
13402 : the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
13403 901 : init = build_string_literal (len, (char *)charbuf, inittype);
13404 901 : init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
13405 : }
13406 : }
13407 :
13408 100405 : tree initsize = TYPE_SIZE_UNIT (inittype);
13409 :
13410 100405 : if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
13411 : {
13412 : /* Fold an empty/zero constructor for an implicitly initialized
13413 : object or subobject into the empty string. */
13414 :
13415 : /* Determine the character type from that of the original
13416 : expression. */
13417 9337 : tree chartype = argtype;
13418 9337 : if (POINTER_TYPE_P (chartype))
13419 9330 : chartype = TREE_TYPE (chartype);
13420 14958 : while (TREE_CODE (chartype) == ARRAY_TYPE)
13421 5621 : chartype = TREE_TYPE (chartype);
13422 :
13423 9337 : if (INTEGRAL_TYPE_P (chartype)
13424 9337 : && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
13425 : {
13426 : /* Convert a char array to an empty STRING_CST having an array
13427 : of the expected type and size. */
13428 9133 : if (!initsize)
13429 3090 : initsize = integer_zero_node;
13430 6043 : else if (!tree_fits_uhwi_p (initsize))
13431 : return NULL_TREE;
13432 :
13433 9127 : unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
13434 9127 : if (size > (unsigned HOST_WIDE_INT) INT_MAX)
13435 : return NULL_TREE;
13436 :
13437 9127 : init = build_string_literal (size, NULL, chartype, size);
13438 9127 : init = TREE_OPERAND (init, 0);
13439 9127 : init = TREE_OPERAND (init, 0);
13440 :
13441 9127 : *ptr_offset = integer_zero_node;
13442 : }
13443 : }
13444 :
13445 100399 : if (decl)
13446 54390 : *decl = array;
13447 :
13448 100399 : if (TREE_CODE (init) != STRING_CST)
13449 : return NULL_TREE;
13450 :
13451 68386 : *mem_size = initsize;
13452 :
13453 68386 : gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
13454 :
13455 : return init;
13456 : }
13457 :
13458 : /* Return STRING_CST if an ARG corresponds to a string constant or zero
13459 : if it doesn't. If we return nonzero, set *PTR_OFFSET to the (possibly
13460 : non-constant) offset in bytes within the string that ARG is accessing.
13461 : If MEM_SIZE is non-zero the storage size of the memory is returned.
13462 : If DECL is non-zero the constant declaration is returned if available. */
13463 :
13464 : tree
13465 10938913 : string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13466 : {
13467 10938913 : return constant_byte_string (arg, ptr_offset, mem_size, decl, false);
13468 : }
13469 :
13470 : /* Similar to string_constant, return a STRING_CST corresponding
13471 : to the value representation of the first argument if it's
13472 : a constant. */
13473 :
13474 : tree
13475 4676569 : byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13476 : {
13477 4676569 : return constant_byte_string (arg, ptr_offset, mem_size, decl, true);
13478 : }
13479 :
13480 : /* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
13481 : is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
13482 : for C2 > 0 to x & C3 == C2
13483 : for C2 < 0 to x & C3 == (C2 & C3). */
13484 : enum tree_code
13485 35 : maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13486 : {
13487 35 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13488 35 : tree treeop0 = gimple_assign_rhs1 (stmt);
13489 35 : tree treeop1 = gimple_assign_rhs2 (stmt);
13490 35 : tree type = TREE_TYPE (*arg0);
13491 35 : scalar_int_mode mode;
13492 35 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13493 : return code;
13494 70 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13495 35 : || TYPE_PRECISION (type) <= 1
13496 35 : || TYPE_UNSIGNED (type)
13497 : /* Signed x % c == 0 should have been optimized into unsigned modulo
13498 : earlier. */
13499 35 : || integer_zerop (*arg1)
13500 : /* If c is known to be non-negative, modulo will be expanded as unsigned
13501 : modulo. */
13502 70 : || get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1)
13503 0 : return code;
13504 :
13505 : /* x % c == d where d < 0 && d <= -c should be always false. */
13506 35 : if (tree_int_cst_sgn (*arg1) == -1
13507 51 : && -wi::to_widest (treeop1) >= wi::to_widest (*arg1))
13508 : return code;
13509 :
13510 35 : int prec = TYPE_PRECISION (type);
13511 35 : wide_int w = wi::to_wide (treeop1) - 1;
13512 35 : w |= wi::shifted_mask (0, prec - 1, true, prec);
13513 35 : tree c3 = wide_int_to_tree (type, w);
13514 35 : tree c4 = *arg1;
13515 35 : if (tree_int_cst_sgn (*arg1) == -1)
13516 16 : c4 = wide_int_to_tree (type, w & wi::to_wide (*arg1));
13517 :
13518 35 : rtx op0 = expand_normal (treeop0);
13519 35 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13520 :
13521 35 : bool speed_p = optimize_insn_for_speed_p ();
13522 :
13523 35 : do_pending_stack_adjust ();
13524 :
13525 35 : location_t loc = gimple_location (stmt);
13526 35 : struct separate_ops ops;
13527 35 : ops.code = TRUNC_MOD_EXPR;
13528 35 : ops.location = loc;
13529 35 : ops.type = TREE_TYPE (treeop0);
13530 35 : ops.op0 = treeop0;
13531 35 : ops.op1 = treeop1;
13532 35 : ops.op2 = NULL_TREE;
13533 35 : start_sequence ();
13534 35 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13535 : EXPAND_NORMAL);
13536 35 : rtx_insn *moinsns = end_sequence ();
13537 :
13538 35 : unsigned mocost = seq_cost (moinsns, speed_p);
13539 35 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13540 35 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13541 :
13542 35 : ops.code = BIT_AND_EXPR;
13543 35 : ops.location = loc;
13544 35 : ops.type = TREE_TYPE (treeop0);
13545 35 : ops.op0 = treeop0;
13546 35 : ops.op1 = c3;
13547 35 : ops.op2 = NULL_TREE;
13548 35 : start_sequence ();
13549 35 : rtx mur = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13550 : EXPAND_NORMAL);
13551 35 : rtx_insn *muinsns = end_sequence ();
13552 :
13553 35 : unsigned mucost = seq_cost (muinsns, speed_p);
13554 35 : mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
13555 35 : mucost += rtx_cost (expand_normal (c4), mode, EQ, 1, speed_p);
13556 :
13557 35 : if (mocost <= mucost)
13558 : {
13559 0 : emit_insn (moinsns);
13560 0 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13561 0 : return code;
13562 : }
13563 :
13564 35 : emit_insn (muinsns);
13565 35 : *arg0 = make_tree (TREE_TYPE (*arg0), mur);
13566 35 : *arg1 = c4;
13567 35 : return code;
13568 35 : }
13569 :
13570 : /* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
13571 : If C1 is odd to:
13572 : (X - C2) * C3 <= C4 (or >), where
13573 : C3 is modular multiplicative inverse of C1 and 1<<prec and
13574 : C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
13575 : if C2 > ((1<<prec) - 1) % C1).
13576 : If C1 is even, S = ctz (C1) and C2 is 0, use
13577 : ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
13578 : inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
13579 :
13580 : For signed (X % C1) == 0 if C1 is odd to (all operations in it
13581 : unsigned):
13582 : (X * C3) + C4 <= 2 * C4, where
13583 : C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
13584 : C4 is ((1<<(prec - 1) - 1) / C1).
13585 : If C1 is even, S = ctz(C1), use
13586 : ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
13587 : where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
13588 : and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
13589 :
13590 : See the Hacker's Delight book, section 10-17. */
13591 : enum tree_code
13592 3348964 : maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13593 : {
13594 3348964 : gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
13595 3348964 : gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
13596 :
13597 3348964 : if (optimize < 2)
13598 : return code;
13599 :
13600 2534489 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13601 2534489 : if (stmt == NULL)
13602 : return code;
13603 :
13604 2429 : tree treeop0 = gimple_assign_rhs1 (stmt);
13605 2429 : tree treeop1 = gimple_assign_rhs2 (stmt);
13606 2429 : if (TREE_CODE (treeop0) != SSA_NAME
13607 2321 : || TREE_CODE (treeop1) != INTEGER_CST
13608 : /* Don't optimize the undefined behavior case x % 0;
13609 : x % 1 should have been optimized into zero, punt if
13610 : it makes it here for whatever reason;
13611 : x % -c should have been optimized into x % c. */
13612 1966 : || compare_tree_int (treeop1, 2) <= 0
13613 : /* Likewise x % c == d where d >= c should be always false. */
13614 4319 : || tree_int_cst_le (treeop1, *arg1))
13615 539 : return code;
13616 :
13617 : /* Unsigned x % pow2 is handled right already, for signed
13618 : modulo handle it in maybe_optimize_pow2p_mod_cmp. */
13619 1890 : if (integer_pow2p (treeop1))
13620 35 : return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
13621 :
13622 1855 : tree type = TREE_TYPE (*arg0);
13623 1855 : scalar_int_mode mode;
13624 3348936 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13625 : return code;
13626 3710 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13627 1855 : || TYPE_PRECISION (type) <= 1)
13628 : return code;
13629 :
13630 1855 : signop sgn = UNSIGNED;
13631 : /* If both operands are known to have the sign bit clear, handle
13632 : even the signed modulo case as unsigned. treeop1 is always
13633 : positive >= 2, checked above. */
13634 1855 : if (!TYPE_UNSIGNED (type)
13635 1855 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) != 1)
13636 : sgn = SIGNED;
13637 :
13638 1855 : if (!TYPE_UNSIGNED (type))
13639 : {
13640 1627 : if (tree_int_cst_sgn (*arg1) == -1)
13641 : return code;
13642 1620 : type = unsigned_type_for (type);
13643 1620 : if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
13644 0 : return code;
13645 : }
13646 :
13647 1848 : int prec = TYPE_PRECISION (type);
13648 1848 : wide_int w = wi::to_wide (treeop1);
13649 1848 : int shift = wi::ctz (w);
13650 : /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
13651 : C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
13652 : If C1 is odd, we can handle all cases by subtracting
13653 : C4 below. We could handle even the even C1 and C2 > -1U % C1 cases
13654 : e.g. by testing for overflow on the subtraction, punt on that for now
13655 : though. */
13656 1848 : if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
13657 : {
13658 189 : if (sgn == SIGNED)
13659 174 : return code;
13660 26 : wide_int x = wi::umod_trunc (wi::mask (prec, false, prec), w);
13661 26 : if (wi::gtu_p (wi::to_wide (*arg1), x))
13662 11 : return code;
13663 26 : }
13664 :
13665 1674 : imm_use_iterator imm_iter;
13666 1674 : use_operand_p use_p;
13667 12406 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
13668 : {
13669 9068 : gimple *use_stmt = USE_STMT (use_p);
13670 : /* Punt if treeop0 is used in the same bb in a division
13671 : or another modulo with the same divisor. We should expect
13672 : the division and modulo combined together. */
13673 17700 : if (use_stmt == stmt
13674 9068 : || gimple_bb (use_stmt) != gimple_bb (stmt))
13675 8632 : continue;
13676 436 : if (!is_gimple_assign (use_stmt)
13677 436 : || (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR
13678 420 : && gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR))
13679 411 : continue;
13680 25 : if (gimple_assign_rhs1 (use_stmt) != treeop0
13681 25 : || !operand_equal_p (gimple_assign_rhs2 (use_stmt), treeop1, 0))
13682 15 : continue;
13683 10 : return code;
13684 10 : }
13685 :
13686 1664 : w = wi::lrshift (w, shift);
13687 1664 : wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
13688 1664 : wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
13689 1664 : wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
13690 1664 : tree c3 = wide_int_to_tree (type, m);
13691 1664 : tree c5 = NULL_TREE;
13692 1664 : wide_int d, e;
13693 1664 : if (sgn == UNSIGNED)
13694 : {
13695 1059 : d = wi::divmod_trunc (wi::mask (prec, false, prec), w, UNSIGNED, &e);
13696 : /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
13697 : otherwise use < or subtract one from C4. E.g. for
13698 : x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
13699 : x % 3U == 1 already needs to be
13700 : (x - 1) * 0xaaaaaaabU <= 0x55555554. */
13701 1059 : if (!shift && wi::gtu_p (wi::to_wide (*arg1), e))
13702 15 : d -= 1;
13703 1059 : if (shift)
13704 442 : d = wi::lrshift (d, shift);
13705 : }
13706 : else
13707 : {
13708 605 : e = wi::udiv_trunc (wi::mask (prec - 1, false, prec), w);
13709 605 : if (!shift)
13710 406 : d = wi::lshift (e, 1);
13711 : else
13712 : {
13713 199 : e = wi::bit_and (e, wi::mask (shift, true, prec));
13714 199 : d = wi::lrshift (e, shift - 1);
13715 : }
13716 605 : c5 = wide_int_to_tree (type, e);
13717 : }
13718 1664 : tree c4 = wide_int_to_tree (type, d);
13719 :
13720 1664 : rtx op0 = expand_normal (treeop0);
13721 1664 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13722 :
13723 1664 : bool speed_p = optimize_insn_for_speed_p ();
13724 :
13725 1664 : do_pending_stack_adjust ();
13726 :
13727 1664 : location_t loc = gimple_location (stmt);
13728 1664 : struct separate_ops ops;
13729 1664 : ops.code = TRUNC_MOD_EXPR;
13730 1664 : ops.location = loc;
13731 1664 : ops.type = TREE_TYPE (treeop0);
13732 1664 : ops.op0 = treeop0;
13733 1664 : ops.op1 = treeop1;
13734 1664 : ops.op2 = NULL_TREE;
13735 1664 : start_sequence ();
13736 1664 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13737 : EXPAND_NORMAL);
13738 1664 : rtx_insn *moinsns = end_sequence ();
13739 :
13740 1664 : unsigned mocost = seq_cost (moinsns, speed_p);
13741 1664 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13742 1664 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13743 :
13744 1664 : tree t = fold_convert_loc (loc, type, treeop0);
13745 1664 : if (!integer_zerop (*arg1))
13746 36 : t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
13747 1664 : t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
13748 1664 : if (sgn == SIGNED)
13749 605 : t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
13750 1664 : if (shift)
13751 : {
13752 641 : tree s = build_int_cst (NULL_TREE, shift);
13753 641 : t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
13754 : }
13755 :
13756 1664 : start_sequence ();
13757 1664 : rtx mur = expand_normal (t);
13758 1664 : rtx_insn *muinsns = end_sequence ();
13759 :
13760 1664 : unsigned mucost = seq_cost (muinsns, speed_p);
13761 1664 : mucost += rtx_cost (mur, mode, LE, 0, speed_p);
13762 1664 : mucost += rtx_cost (expand_normal (c4), mode, LE, 1, speed_p);
13763 :
13764 1664 : if (mocost <= mucost)
13765 : {
13766 266 : emit_insn (moinsns);
13767 266 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13768 266 : return code;
13769 : }
13770 :
13771 1398 : emit_insn (muinsns);
13772 1398 : *arg0 = make_tree (type, mur);
13773 1398 : *arg1 = c4;
13774 1398 : return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
13775 3512 : }
13776 :
13777 : /* Optimize x - y < 0 into x < 0 if x - y has undefined overflow. */
13778 :
13779 : void
13780 240705 : maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
13781 : {
13782 240705 : gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
13783 : || code == LT_EXPR || code == LE_EXPR);
13784 240705 : gcc_checking_assert (integer_zerop (*arg1));
13785 :
13786 240705 : if (!optimize)
13787 : return;
13788 :
13789 207085 : gimple *stmt = get_def_for_expr (*arg0, MINUS_EXPR);
13790 207085 : if (stmt == NULL)
13791 : return;
13792 :
13793 1351 : tree treeop0 = gimple_assign_rhs1 (stmt);
13794 1351 : tree treeop1 = gimple_assign_rhs2 (stmt);
13795 1351 : if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
13796 : return;
13797 :
13798 1254 : *arg0 = treeop0;
13799 1254 : *arg1 = treeop1;
13800 : }
13801 :
13802 :
13803 : /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
13804 : a single bit equality/inequality test, returns where the result is located. */
13805 :
13806 : static rtx
13807 9792 : expand_single_bit_test (location_t loc, enum tree_code code,
13808 : tree inner, int bitnum,
13809 : tree result_type, rtx target,
13810 : machine_mode mode)
13811 : {
13812 9792 : gcc_assert (code == NE_EXPR || code == EQ_EXPR);
13813 :
13814 9792 : tree type = TREE_TYPE (inner);
13815 9792 : scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
13816 9792 : int ops_unsigned;
13817 9792 : tree signed_type, unsigned_type, intermediate_type;
13818 9792 : gimple *inner_def;
13819 :
13820 : /* First, see if we can fold the single bit test into a sign-bit
13821 : test. */
13822 9792 : if (bitnum == TYPE_PRECISION (type) - 1
13823 9792 : && type_has_mode_precision_p (type))
13824 : {
13825 241 : tree stype = signed_type_for (type);
13826 444 : tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
13827 : result_type,
13828 : fold_convert_loc (loc, stype, inner),
13829 : build_int_cst (stype, 0));
13830 241 : return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
13831 : }
13832 :
13833 : /* Otherwise we have (A & C) != 0 where C is a single bit,
13834 : convert that into ((A >> C2) & 1). Where C2 = log2(C).
13835 : Similarly for (A & C) == 0. */
13836 :
13837 : /* If INNER is a right shift of a constant and it plus BITNUM does
13838 : not overflow, adjust BITNUM and INNER. */
13839 9551 : if ((inner_def = get_def_for_expr (inner, RSHIFT_EXPR))
13840 93 : && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
13841 16 : && bitnum < TYPE_PRECISION (type)
13842 9567 : && wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (inner_def)),
13843 9551 : TYPE_PRECISION (type) - bitnum))
13844 : {
13845 16 : bitnum += tree_to_uhwi (gimple_assign_rhs2 (inner_def));
13846 16 : inner = gimple_assign_rhs1 (inner_def);
13847 : }
13848 :
13849 : /* If we are going to be able to omit the AND below, we must do our
13850 : operations as unsigned. If we must use the AND, we have a choice.
13851 : Normally unsigned is faster, but for some machines signed is. */
13852 9551 : ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
13853 : && !flag_syntax_only) ? 0 : 1;
13854 :
13855 9551 : signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
13856 9551 : unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
13857 9551 : intermediate_type = ops_unsigned ? unsigned_type : signed_type;
13858 9551 : inner = fold_convert_loc (loc, intermediate_type, inner);
13859 :
13860 9551 : rtx inner0 = expand_expr (inner, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13861 :
13862 9551 : if (CONST_SCALAR_INT_P (inner0))
13863 : {
13864 0 : wide_int t = rtx_mode_t (inner0, operand_mode);
13865 0 : bool setp = (wi::lrshift (t, bitnum) & 1) != 0;
13866 0 : return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
13867 0 : }
13868 9551 : int bitpos = bitnum;
13869 :
13870 9551 : if (BYTES_BIG_ENDIAN)
13871 : bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
13872 :
13873 9551 : inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
13874 : operand_mode, mode, 0, NULL);
13875 :
13876 9551 : if (code == EQ_EXPR)
13877 2672 : inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
13878 : NULL_RTX, 1, OPTAB_LIB_WIDEN);
13879 9551 : if (GET_MODE (inner0) != mode)
13880 : {
13881 0 : rtx t = gen_reg_rtx (mode);
13882 0 : convert_move (t, inner0, 0);
13883 0 : return t;
13884 : }
13885 : return inner0;
13886 : }
13887 :
13888 : /* Generate code to calculate OPS, and exploded expression
13889 : using a store-flag instruction and return an rtx for the result.
13890 : OPS reflects a comparison.
13891 :
13892 : If TARGET is nonzero, store the result there if convenient.
13893 :
13894 : Return zero if there is no suitable set-flag instruction
13895 : available on this machine.
13896 :
13897 : Once expand_expr has been called on the arguments of the comparison,
13898 : we are committed to doing the store flag, since it is not safe to
13899 : re-evaluate the expression. We emit the store-flag insn by calling
13900 : emit_store_flag, but only expand the arguments if we have a reason
13901 : to believe that emit_store_flag will be successful. If we think that
13902 : it will, but it isn't, we have to simulate the store-flag with a
13903 : set/jump/set sequence. */
13904 :
13905 : static rtx
13906 637576 : do_store_flag (const_sepops ops, rtx target, machine_mode mode)
13907 : {
13908 637576 : enum rtx_code code;
13909 637576 : tree arg0, arg1, type;
13910 637576 : machine_mode operand_mode;
13911 637576 : int unsignedp;
13912 637576 : rtx op0, op1;
13913 637576 : rtx subtarget = target;
13914 637576 : location_t loc = ops->location;
13915 637576 : unsigned HOST_WIDE_INT nunits;
13916 :
13917 637576 : arg0 = ops->op0;
13918 637576 : arg1 = ops->op1;
13919 :
13920 : /* Don't crash if the comparison was erroneous. */
13921 637576 : if (arg0 == error_mark_node || arg1 == error_mark_node)
13922 0 : return const0_rtx;
13923 :
13924 637576 : type = TREE_TYPE (arg0);
13925 637576 : operand_mode = TYPE_MODE (type);
13926 637576 : unsignedp = TYPE_UNSIGNED (type);
13927 :
13928 : /* We won't bother with BLKmode store-flag operations because it would mean
13929 : passing a lot of information to emit_store_flag. */
13930 637576 : if (operand_mode == BLKmode)
13931 : return 0;
13932 :
13933 : /* We won't bother with store-flag operations involving function pointers
13934 : when function pointers must be canonicalized before comparisons. */
13935 637576 : if (targetm.have_canonicalize_funcptr_for_compare ()
13936 637576 : && ((POINTER_TYPE_P (TREE_TYPE (arg0))
13937 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
13938 0 : || (POINTER_TYPE_P (TREE_TYPE (arg1))
13939 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
13940 : return 0;
13941 :
13942 637576 : STRIP_NOPS (arg0);
13943 637576 : STRIP_NOPS (arg1);
13944 :
13945 : /* For vector typed comparisons emit code to generate the desired
13946 : all-ones or all-zeros mask. */
13947 637576 : if (VECTOR_TYPE_P (ops->type))
13948 : {
13949 26159 : tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
13950 26159 : if (VECTOR_BOOLEAN_TYPE_P (ops->type)
13951 52318 : && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
13952 26159 : return expand_vec_cmp_expr (ops->type, ifexp, target);
13953 : else
13954 0 : gcc_unreachable ();
13955 : }
13956 :
13957 : /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
13958 : into (x - C2) * C3 < C4. */
13959 611417 : if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
13960 412695 : && TREE_CODE (arg0) == SSA_NAME
13961 412120 : && TREE_CODE (arg1) == INTEGER_CST)
13962 : {
13963 246410 : enum tree_code new_code = maybe_optimize_mod_cmp (ops->code,
13964 : &arg0, &arg1);
13965 246410 : if (new_code != ops->code)
13966 : {
13967 106 : struct separate_ops nops = *ops;
13968 106 : nops.code = new_code;
13969 106 : nops.op0 = arg0;
13970 106 : nops.op1 = arg1;
13971 106 : nops.type = TREE_TYPE (arg0);
13972 106 : return do_store_flag (&nops, target, mode);
13973 : }
13974 : }
13975 :
13976 : /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow. */
13977 611311 : if (!unsignedp
13978 439340 : && (ops->code == LT_EXPR || ops->code == LE_EXPR
13979 439340 : || ops->code == GT_EXPR || ops->code == GE_EXPR)
13980 126678 : && integer_zerop (arg1)
13981 649811 : && TREE_CODE (arg0) == SSA_NAME)
13982 38496 : maybe_optimize_sub_cmp_0 (ops->code, &arg0, &arg1);
13983 :
13984 : /* Get the rtx comparison code to use. We know that EXP is a comparison
13985 : operation of some type. Some comparisons against 1 and -1 can be
13986 : converted to comparisons with zero. Do so here so that the tests
13987 : below will be aware that we have a comparison with zero. These
13988 : tests will not catch constants in the first operand, but constants
13989 : are rarely passed as the first operand. */
13990 :
13991 611311 : switch (ops->code)
13992 : {
13993 : case EQ_EXPR:
13994 : code = EQ;
13995 : break;
13996 234678 : case NE_EXPR:
13997 234678 : code = NE;
13998 234678 : break;
13999 40006 : case LT_EXPR:
14000 40006 : if (integer_onep (arg1))
14001 0 : arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
14002 : else
14003 40006 : code = unsignedp ? LTU : LT;
14004 : break;
14005 33485 : case LE_EXPR:
14006 33485 : if (! unsignedp && integer_all_onesp (arg1))
14007 0 : arg1 = integer_zero_node, code = LT;
14008 : else
14009 33485 : code = unsignedp ? LEU : LE;
14010 : break;
14011 53847 : case GT_EXPR:
14012 53847 : if (! unsignedp && integer_all_onesp (arg1))
14013 0 : arg1 = integer_zero_node, code = GE;
14014 : else
14015 53847 : code = unsignedp ? GTU : GT;
14016 : break;
14017 46945 : case GE_EXPR:
14018 46945 : if (integer_onep (arg1))
14019 29246 : arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
14020 : else
14021 46945 : code = unsignedp ? GEU : GE;
14022 : break;
14023 :
14024 1016 : case UNORDERED_EXPR:
14025 1016 : code = UNORDERED;
14026 1016 : break;
14027 712 : case ORDERED_EXPR:
14028 712 : code = ORDERED;
14029 712 : break;
14030 523 : case UNLT_EXPR:
14031 523 : code = UNLT;
14032 523 : break;
14033 11121 : case UNLE_EXPR:
14034 11121 : code = UNLE;
14035 11121 : break;
14036 942 : case UNGT_EXPR:
14037 942 : code = UNGT;
14038 942 : break;
14039 9916 : case UNGE_EXPR:
14040 9916 : code = UNGE;
14041 9916 : break;
14042 135 : case UNEQ_EXPR:
14043 135 : code = UNEQ;
14044 135 : break;
14045 74 : case LTGT_EXPR:
14046 74 : code = LTGT;
14047 74 : break;
14048 :
14049 0 : default:
14050 0 : gcc_unreachable ();
14051 : }
14052 :
14053 : /* Put a constant second. */
14054 611311 : if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
14055 609511 : || TREE_CODE (arg0) == FIXED_CST)
14056 : {
14057 1800 : std::swap (arg0, arg1);
14058 1800 : code = swap_condition (code);
14059 : }
14060 :
14061 : /* If this is an equality or inequality test of a single bit, we can
14062 : do this by shifting the bit being tested to the low-order bit and
14063 : masking the result with the constant 1. If the condition was EQ,
14064 : we xor it with 1. This does not require an scc insn and is faster
14065 : than an scc insn even if we have it. */
14066 :
14067 611311 : if ((code == NE || code == EQ)
14068 412589 : && (integer_zerop (arg1)
14069 258497 : || integer_pow2p (arg1))
14070 : /* vector types are not handled here. */
14071 187050 : && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE
14072 798321 : && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
14073 : {
14074 187010 : tree narg0 = arg0;
14075 187010 : wide_int nz = tree_nonzero_bits (narg0);
14076 187010 : gimple *srcstmt = get_def_for_expr (narg0, BIT_AND_EXPR);
14077 : /* If the defining statement was (x & POW2), then use that instead of
14078 : the non-zero bits. */
14079 187010 : if (srcstmt && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
14080 : {
14081 5470 : nz = wi::to_wide (gimple_assign_rhs2 (srcstmt));
14082 5470 : narg0 = gimple_assign_rhs1 (srcstmt);
14083 : }
14084 :
14085 187010 : if (wi::popcount (nz) == 1
14086 187010 : && (integer_zerop (arg1)
14087 177250 : || wi::to_wide (arg1) == nz))
14088 : {
14089 9792 : int bitnum = wi::exact_log2 (nz);
14090 9792 : enum tree_code tcode = EQ_EXPR;
14091 9792 : if ((code == NE) ^ !integer_zerop (arg1))
14092 7082 : tcode = NE_EXPR;
14093 :
14094 9792 : type = lang_hooks.types.type_for_mode (mode, unsignedp);
14095 9792 : return expand_single_bit_test (loc, tcode,
14096 : narg0,
14097 : bitnum, type, target, mode);
14098 : }
14099 187010 : }
14100 :
14101 :
14102 601519 : if (! get_subtarget (target)
14103 601519 : || GET_MODE (subtarget) != operand_mode)
14104 : subtarget = 0;
14105 :
14106 601519 : expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
14107 :
14108 : /* For boolean vectors with less than mode precision
14109 : make sure to fill padding with consistent values. */
14110 40 : if (VECTOR_BOOLEAN_TYPE_P (type)
14111 27 : && SCALAR_INT_MODE_P (operand_mode)
14112 601519 : && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
14113 601519 : && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
14114 : {
14115 0 : gcc_assert (code == EQ || code == NE);
14116 0 : op0 = expand_binop (mode, and_optab, op0,
14117 0 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
14118 : NULL_RTX, true, OPTAB_WIDEN);
14119 0 : op1 = expand_binop (mode, and_optab, op1,
14120 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
14121 : NULL_RTX, true, OPTAB_WIDEN);
14122 : }
14123 :
14124 601519 : if (target == 0)
14125 410733 : target = gen_reg_rtx (mode);
14126 :
14127 : /* Try a cstore if possible. */
14128 601519 : return emit_store_flag_force (target, code, op0, op1,
14129 : operand_mode, unsignedp,
14130 601519 : (TYPE_PRECISION (ops->type) == 1
14131 1202367 : && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
14132 : }
14133 :
14134 : /* Attempt to generate a casesi instruction. Returns true if successful,
14135 : false otherwise (i.e. if there is no casesi instruction).
14136 :
14137 : DEFAULT_PROBABILITY is the probability of jumping to the default
14138 : label. */
14139 : bool
14140 6594 : try_casesi (tree index_type, tree index_expr, tree minval, tree range,
14141 : rtx table_label, rtx default_label, rtx fallback_label,
14142 : profile_probability default_probability)
14143 : {
14144 6594 : class expand_operand ops[5];
14145 6594 : scalar_int_mode index_mode = SImode;
14146 6594 : rtx op1, op2, index;
14147 :
14148 6594 : if (! targetm.have_casesi ())
14149 : return false;
14150 :
14151 : /* The index must be some form of integer. Convert it to SImode. */
14152 0 : scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
14153 0 : if (GET_MODE_BITSIZE (omode) > GET_MODE_BITSIZE (index_mode))
14154 : {
14155 0 : rtx rangertx = expand_normal (range);
14156 :
14157 : /* We must handle the endpoints in the original mode. */
14158 0 : index_expr = build2 (MINUS_EXPR, index_type,
14159 : index_expr, minval);
14160 0 : minval = integer_zero_node;
14161 0 : index = expand_normal (index_expr);
14162 0 : if (default_label)
14163 0 : emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
14164 : omode, 1, default_label,
14165 : default_probability);
14166 : /* Now we can safely truncate. */
14167 0 : index = convert_to_mode (index_mode, index, 0);
14168 : }
14169 : else
14170 : {
14171 0 : if (omode != index_mode)
14172 : {
14173 0 : index_type = lang_hooks.types.type_for_mode (index_mode, 0);
14174 0 : index_expr = fold_convert (index_type, index_expr);
14175 : }
14176 :
14177 0 : index = expand_normal (index_expr);
14178 : }
14179 :
14180 0 : do_pending_stack_adjust ();
14181 :
14182 0 : op1 = expand_normal (minval);
14183 0 : op2 = expand_normal (range);
14184 :
14185 0 : create_input_operand (&ops[0], index, index_mode);
14186 0 : create_convert_operand_from_type (&ops[1], op1, TREE_TYPE (minval));
14187 0 : create_convert_operand_from_type (&ops[2], op2, TREE_TYPE (range));
14188 0 : create_fixed_operand (&ops[3], table_label);
14189 0 : create_fixed_operand (&ops[4], (default_label
14190 : ? default_label
14191 : : fallback_label));
14192 0 : expand_jump_insn (targetm.code_for_casesi, 5, ops);
14193 0 : return true;
14194 : }
14195 :
14196 : /* Attempt to generate a tablejump instruction; same concept. */
14197 : /* Subroutine of the next function.
14198 :
14199 : INDEX is the value being switched on, with the lowest value
14200 : in the table already subtracted.
14201 : MODE is its expected mode (needed if INDEX is constant).
14202 : RANGE is the length of the jump table.
14203 : TABLE_LABEL is a CODE_LABEL rtx for the table itself.
14204 :
14205 : DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
14206 : index value is out of range.
14207 : DEFAULT_PROBABILITY is the probability of jumping to
14208 : the default label. */
14209 :
14210 : static void
14211 6594 : do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
14212 : rtx default_label, profile_probability default_probability)
14213 : {
14214 6594 : rtx temp, vector;
14215 :
14216 6594 : if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
14217 5713 : cfun->cfg->max_jumptable_ents = INTVAL (range);
14218 :
14219 : /* Do an unsigned comparison (in the proper mode) between the index
14220 : expression and the value which represents the length of the range.
14221 : Since we just finished subtracting the lower bound of the range
14222 : from the index expression, this comparison allows us to simultaneously
14223 : check that the original index expression value is both greater than
14224 : or equal to the minimum value of the range and less than or equal to
14225 : the maximum value of the range. */
14226 :
14227 6594 : if (default_label)
14228 6548 : emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
14229 : default_label, default_probability);
14230 :
14231 : /* If index is in range, it must fit in Pmode.
14232 : Convert to Pmode so we can index with it. */
14233 7649 : if (mode != Pmode)
14234 : {
14235 5597 : unsigned int width;
14236 :
14237 : /* We know the value of INDEX is between 0 and RANGE. If we have a
14238 : sign-extended subreg, and RANGE does not have the sign bit set, then
14239 : we have a value that is valid for both sign and zero extension. In
14240 : this case, we get better code if we sign extend. */
14241 5597 : if (GET_CODE (index) == SUBREG
14242 9 : && SUBREG_PROMOTED_VAR_P (index)
14243 0 : && SUBREG_PROMOTED_SIGNED_P (index)
14244 0 : && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode)))
14245 : <= HOST_BITS_PER_WIDE_INT)
14246 5597 : && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
14247 0 : index = convert_to_mode (Pmode, index, 0);
14248 : else
14249 5597 : index = convert_to_mode (Pmode, index, 1);
14250 : }
14251 :
14252 : /* Don't let a MEM slip through, because then INDEX that comes
14253 : out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
14254 : and break_out_memory_refs will go to work on it and mess it up. */
14255 : #ifdef PIC_CASE_VECTOR_ADDRESS
14256 : if (flag_pic && !REG_P (index))
14257 : index = copy_to_mode_reg (Pmode, index);
14258 : #endif
14259 :
14260 : /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
14261 : GET_MODE_SIZE, because this indicates how large insns are. The other
14262 : uses should all be Pmode, because they are addresses. This code
14263 : could fail if addresses and insns are not the same size. */
14264 7649 : index = simplify_gen_binary (MULT, Pmode, index,
14265 13188 : gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
14266 6594 : Pmode));
14267 7649 : index = simplify_gen_binary (PLUS, Pmode, index,
14268 6594 : gen_rtx_LABEL_REF (Pmode, table_label));
14269 :
14270 : #ifdef PIC_CASE_VECTOR_ADDRESS
14271 : if (flag_pic)
14272 : index = PIC_CASE_VECTOR_ADDRESS (index);
14273 : else
14274 : #endif
14275 8252 : index = memory_address (CASE_VECTOR_MODE, index);
14276 8252 : temp = gen_reg_rtx (CASE_VECTOR_MODE);
14277 8252 : vector = gen_const_mem (CASE_VECTOR_MODE, index);
14278 6594 : convert_move (temp, vector, 0);
14279 :
14280 6594 : emit_jump_insn (targetm.gen_tablejump (temp, table_label));
14281 :
14282 : /* If we are generating PIC code or if the table is PC-relative, the
14283 : table and JUMP_INSN must be adjacent, so don't output a BARRIER. */
14284 6594 : if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
14285 5435 : emit_barrier ();
14286 6594 : }
14287 :
14288 : bool
14289 6594 : try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
14290 : rtx table_label, rtx default_label,
14291 : profile_probability default_probability)
14292 : {
14293 6594 : rtx index;
14294 :
14295 6594 : if (! targetm.have_tablejump ())
14296 : return false;
14297 :
14298 6594 : index_expr = fold_build2 (MINUS_EXPR, index_type,
14299 : fold_convert (index_type, index_expr),
14300 : fold_convert (index_type, minval));
14301 6594 : index = expand_normal (index_expr);
14302 6594 : do_pending_stack_adjust ();
14303 :
14304 6594 : do_tablejump (index, TYPE_MODE (index_type),
14305 6594 : convert_modes (TYPE_MODE (index_type),
14306 6594 : TYPE_MODE (TREE_TYPE (range)),
14307 : expand_normal (range),
14308 6594 : TYPE_UNSIGNED (TREE_TYPE (range))),
14309 : table_label, default_label, default_probability);
14310 6594 : return true;
14311 : }
14312 :
14313 : /* Return a CONST_VECTOR rtx representing vector mask for
14314 : a VECTOR_CST of booleans. */
14315 : static rtx
14316 684 : const_vector_mask_from_tree (tree exp)
14317 : {
14318 684 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14319 684 : machine_mode inner = GET_MODE_INNER (mode);
14320 :
14321 684 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14322 684 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14323 684 : unsigned int count = builder.encoded_nelts ();
14324 3680 : for (unsigned int i = 0; i < count; ++i)
14325 : {
14326 2996 : tree elt = VECTOR_CST_ELT (exp, i);
14327 2996 : gcc_assert (TREE_CODE (elt) == INTEGER_CST);
14328 2996 : if (integer_zerop (elt))
14329 1177 : builder.quick_push (CONST0_RTX (inner));
14330 1819 : else if (integer_onep (elt)
14331 1819 : || integer_minus_onep (elt))
14332 1819 : builder.quick_push (CONSTM1_RTX (inner));
14333 : else
14334 0 : gcc_unreachable ();
14335 : }
14336 684 : return builder.build ();
14337 684 : }
14338 :
14339 : /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
14340 : static rtx
14341 566604 : const_vector_from_tree (tree exp)
14342 : {
14343 566604 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14344 :
14345 566604 : if (initializer_zerop (exp))
14346 168215 : return CONST0_RTX (mode);
14347 :
14348 398389 : if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
14349 684 : return const_vector_mask_from_tree (exp);
14350 :
14351 397705 : machine_mode inner = GET_MODE_INNER (mode);
14352 :
14353 397705 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14354 397705 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14355 397705 : unsigned int count = builder.encoded_nelts ();
14356 1283067 : for (unsigned int i = 0; i < count; ++i)
14357 : {
14358 885362 : tree elt = VECTOR_CST_ELT (exp, i);
14359 885362 : if (TREE_CODE (elt) == REAL_CST)
14360 134896 : builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt),
14361 : inner));
14362 750466 : else if (TREE_CODE (elt) == FIXED_CST)
14363 0 : builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
14364 : inner));
14365 : else
14366 750466 : builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt),
14367 : inner));
14368 : }
14369 397705 : return builder.build ();
14370 397705 : }
14371 :
14372 : /* Build a decl for a personality function given a language prefix. */
14373 :
14374 : tree
14375 32928 : build_personality_function (const char *lang)
14376 : {
14377 32928 : const char *unwind_and_version;
14378 32928 : tree decl, type;
14379 32928 : char *name;
14380 :
14381 32928 : switch (targetm_common.except_unwind_info (&global_options))
14382 : {
14383 : case UI_NONE:
14384 : return NULL;
14385 : case UI_SJLJ:
14386 : unwind_and_version = "_sj0";
14387 : break;
14388 32928 : case UI_DWARF2:
14389 32928 : case UI_TARGET:
14390 32928 : unwind_and_version = "_v0";
14391 32928 : break;
14392 0 : case UI_SEH:
14393 0 : unwind_and_version = "_seh0";
14394 0 : break;
14395 0 : default:
14396 0 : gcc_unreachable ();
14397 : }
14398 :
14399 32928 : name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
14400 :
14401 32928 : type = build_function_type_list (unsigned_type_node,
14402 : integer_type_node, integer_type_node,
14403 : long_long_unsigned_type_node,
14404 : ptr_type_node, ptr_type_node, NULL_TREE);
14405 32928 : decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
14406 : get_identifier (name), type);
14407 32928 : DECL_ARTIFICIAL (decl) = 1;
14408 32928 : DECL_EXTERNAL (decl) = 1;
14409 32928 : TREE_PUBLIC (decl) = 1;
14410 :
14411 : /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
14412 : are the flags assigned by targetm.encode_section_info. */
14413 32928 : SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
14414 :
14415 32928 : return decl;
14416 : }
14417 :
14418 : /* Extracts the personality function of DECL and returns the corresponding
14419 : libfunc. */
14420 :
14421 : rtx
14422 1654337 : get_personality_function (tree decl)
14423 : {
14424 1654337 : tree personality = DECL_FUNCTION_PERSONALITY (decl);
14425 1654337 : enum eh_personality_kind pk;
14426 :
14427 1654337 : pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
14428 1654337 : if (pk == eh_personality_none)
14429 : return NULL;
14430 :
14431 157204 : if (!personality
14432 157204 : && pk == eh_personality_any)
14433 71838 : personality = lang_hooks.eh_personality ();
14434 :
14435 157204 : if (pk == eh_personality_lang)
14436 85366 : gcc_assert (personality != NULL_TREE);
14437 :
14438 157204 : return XEXP (DECL_RTL (personality), 0);
14439 : }
14440 :
14441 : /* Returns a tree for the size of EXP in bytes. */
14442 :
14443 : static tree
14444 14853213 : tree_expr_size (const_tree exp)
14445 : {
14446 14853213 : if (DECL_P (exp)
14447 14853213 : && DECL_SIZE_UNIT (exp) != 0)
14448 1949341 : return DECL_SIZE_UNIT (exp);
14449 : else
14450 12903872 : return size_in_bytes (TREE_TYPE (exp));
14451 : }
14452 :
14453 : /* Return an rtx for the size in bytes of the value of EXP. */
14454 :
14455 : rtx
14456 14663415 : expr_size (tree exp)
14457 : {
14458 14663415 : tree size;
14459 :
14460 14663415 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14461 773 : size = TREE_OPERAND (exp, 1);
14462 : else
14463 : {
14464 14662642 : size = tree_expr_size (exp);
14465 14662642 : gcc_assert (size);
14466 14662642 : gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
14467 : }
14468 :
14469 14663415 : return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
14470 : }
14471 :
14472 : /* Return a wide integer for the size in bytes of the value of EXP, or -1
14473 : if the size can vary or is larger than an integer. */
14474 :
14475 : HOST_WIDE_INT
14476 190571 : int_expr_size (const_tree exp)
14477 : {
14478 190571 : tree size;
14479 :
14480 190571 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14481 0 : size = TREE_OPERAND (exp, 1);
14482 : else
14483 : {
14484 190571 : size = tree_expr_size (exp);
14485 190571 : gcc_assert (size);
14486 : }
14487 :
14488 190571 : if (size == 0 || !tree_fits_shwi_p (size))
14489 0 : return -1;
14490 :
14491 190571 : return tree_to_shwi (size);
14492 : }
14493 :
14494 : /* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
14495 : in GF (2^N).
14496 : Author: Richard Sandiford <richard.sandiford@arm.com> */
14497 :
14498 : unsigned HOST_WIDE_INT
14499 0 : gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
14500 : unsigned short n)
14501 : {
14502 : /* The result has degree N, so needs N + 1 bits. */
14503 0 : gcc_assert (n < 64);
14504 :
14505 : /* Perform a division step for the x^2N coefficient. At this point the
14506 : quotient and remainder have N implicit trailing zeros. */
14507 : unsigned HOST_WIDE_INT quotient = 1;
14508 : unsigned HOST_WIDE_INT remainder = polynomial;
14509 :
14510 : /* Process the coefficients for x^(2N-1) down to x^N, with each step
14511 : reducing the number of implicit trailing zeros by one. */
14512 0 : for (unsigned int i = 0; i < n; ++i)
14513 : {
14514 0 : bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
14515 0 : quotient = (quotient << 1) | coeff;
14516 0 : remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
14517 : }
14518 0 : return quotient;
14519 : }
14520 :
14521 : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
14522 : CRC_BITS is CRC size. */
14523 :
14524 : static unsigned HOST_WIDE_INT
14525 34560 : calculate_crc (unsigned HOST_WIDE_INT crc,
14526 : unsigned HOST_WIDE_INT polynomial,
14527 : unsigned short crc_bits)
14528 : {
14529 34560 : unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
14530 34560 : crc = crc << (crc_bits - 8);
14531 311040 : for (short i = 8; i > 0; --i)
14532 : {
14533 276480 : if (crc & msb)
14534 138240 : crc = (crc << 1) ^ polynomial;
14535 : else
14536 138240 : crc <<= 1;
14537 : }
14538 : /* Zero out bits in crc beyond the specified number of crc_bits. */
14539 34560 : if (crc_bits < sizeof (crc) * CHAR_BIT)
14540 31488 : crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
14541 34560 : return crc;
14542 : }
14543 :
14544 : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
14545 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14546 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14547 :
14548 : static rtx
14549 135 : assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14550 : {
14551 135 : unsigned table_el_n = 0x100;
14552 135 : tree ar = build_array_type (make_unsigned_type (crc_bits),
14553 135 : build_index_type (size_int (table_el_n - 1)));
14554 :
14555 : /* Initialize the table. */
14556 135 : vec<tree, va_gc> *initial_values;
14557 135 : vec_alloc (initial_values, table_el_n);
14558 34695 : for (size_t i = 0; i < table_el_n; ++i)
14559 : {
14560 34560 : unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
14561 34560 : tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
14562 34560 : vec_safe_push (initial_values, element);
14563 : }
14564 135 : tree ctor = build_constructor_from_vec (ar, initial_values);
14565 135 : rtx mem = output_constant_def (ctor, 1);
14566 135 : gcc_assert (MEM_P (mem));
14567 135 : if (dump_file && (dump_flags & TDF_DETAILS))
14568 : {
14569 16 : fprintf (dump_file,
14570 : ";; emitting crc table crc_%u_polynomial_"
14571 : HOST_WIDE_INT_PRINT_HEX " ",
14572 : crc_bits, polynom);
14573 16 : print_rtl_single (dump_file, XEXP (mem, 0));
14574 16 : fprintf (dump_file, "\n");
14575 : }
14576 :
14577 135 : return XEXP (mem, 0);
14578 : }
14579 :
14580 : /* Generate CRC lookup table by calculating CRC for all possible
14581 : 8-bit data values. The table is stored with a specific name in the read-only
14582 : static data section.
14583 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14584 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14585 :
14586 : static rtx
14587 135 : generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14588 : {
14589 135 : gcc_assert (crc_bits <= 64);
14590 :
14591 135 : return assemble_crc_table (polynom, crc_bits);
14592 : }
14593 :
14594 : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
14595 : CRC_BITS is CRC size. */
14596 :
14597 : static unsigned HOST_WIDE_INT
14598 35328 : calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
14599 : unsigned HOST_WIDE_INT polynomial,
14600 : unsigned short crc_bits)
14601 : {
14602 35328 : unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
14603 317952 : for (int j = 0; j < 8; j++)
14604 : {
14605 282624 : if (crc & 1)
14606 141312 : crc = (crc >> 1) ^ rev_polynom;
14607 : else
14608 141312 : crc >>= 1;
14609 : }
14610 : /* Zero out bits in crc beyond the specified number of crc_bits. */
14611 35328 : if (crc_bits < sizeof (crc) * CHAR_BIT)
14612 29952 : crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
14613 35328 : return crc;
14614 : }
14615 :
14616 : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
14617 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14618 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14619 :
14620 : static rtx
14621 138 : assemble_reversed_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14622 : {
14623 138 : unsigned table_el_n = 0x100;
14624 138 : tree ar = build_array_type (make_unsigned_type (crc_bits),
14625 138 : build_index_type (size_int (table_el_n - 1)));
14626 :
14627 : /* Initialize the table. */
14628 138 : vec<tree, va_gc> *initial_values;
14629 138 : vec_alloc (initial_values, table_el_n);
14630 35466 : for (size_t i = 0; i < table_el_n; ++i)
14631 : {
14632 35328 : unsigned HOST_WIDE_INT crc = calculate_reversed_crc (i, polynom, crc_bits);
14633 35328 : tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
14634 35328 : vec_safe_push (initial_values, element);
14635 : }
14636 138 : tree ctor = build_constructor_from_vec (ar, initial_values);
14637 138 : rtx mem = output_constant_def (ctor, 1);
14638 138 : gcc_assert (MEM_P (mem));
14639 138 : if (dump_file && (dump_flags & TDF_DETAILS))
14640 : {
14641 16 : fprintf (dump_file,
14642 : ";; emitting reversed crc table crc_%u_polynomial_"
14643 : HOST_WIDE_INT_PRINT_HEX " ",
14644 : crc_bits, polynom);
14645 16 : print_rtl_single (dump_file, XEXP (mem, 0));
14646 16 : fprintf (dump_file, "\n");
14647 : }
14648 :
14649 138 : return XEXP (mem, 0);
14650 : }
14651 :
14652 : /* Generate reversed CRC table for the given POLYNOM and CRC_BITS. */
14653 :
14654 : static rtx
14655 138 : generate_reversed_crc_table (unsigned HOST_WIDE_INT polynom,
14656 : unsigned short crc_bits)
14657 : {
14658 138 : gcc_assert (crc_bits <= 64);
14659 :
14660 138 : return assemble_reversed_crc_table (polynom, crc_bits);
14661 : }
14662 :
14663 : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14664 : POLYNOMIAL (without leading 1).
14665 :
14666 : First, using POLYNOMIAL's value generates CRC table of 256 elements,
14667 : then generates the assembly for the following code,
14668 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64, depending on CRC:
14669 :
14670 : for (int i = 0; i < data_bit_size / 8; i++)
14671 : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14672 : ^ (data >> (data_bit_size - (i + 1) * 8)
14673 : & 0xFF))];
14674 :
14675 : So to take values from the table, we need 8-bit data.
14676 : If input data size is not 8, then first we extract upper 8 bits,
14677 : then the other 8 bits, and so on. */
14678 :
14679 : static void
14680 135 : calculate_table_based_CRC (rtx *crc, const rtx &input_data,
14681 : const rtx &polynomial,
14682 : machine_mode data_mode)
14683 : {
14684 135 : machine_mode mode = GET_MODE (*crc);
14685 135 : unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
14686 135 : unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
14687 135 : rtx tab = generate_crc_table (UINTVAL (polynomial), crc_bit_size);
14688 :
14689 394 : for (unsigned short i = 0; i < data_size; i++)
14690 : {
14691 : /* crc >> (crc_bit_size - 8). */
14692 259 : *crc = force_reg (mode, *crc);
14693 259 : rtx op1 = expand_shift (RSHIFT_EXPR, mode, *crc, crc_bit_size - 8,
14694 : NULL_RTX, 1);
14695 :
14696 : /* data >> (8 * (GET_MODE_SIZE (data_mode).to_constant () - i - 1)). */
14697 259 : unsigned range_8 = 8 * (data_size - i - 1);
14698 : /* CRC's mode is always at least as wide as INPUT_DATA. Convert
14699 : INPUT_DATA into CRC's mode. */
14700 259 : rtx data = gen_reg_rtx (mode);
14701 259 : convert_move (data, input_data, 1);
14702 259 : data = expand_shift (RSHIFT_EXPR, mode, data, range_8, NULL_RTX, 1);
14703 :
14704 : /* data >> (8 * (GET_MODE_SIZE (mode)
14705 : .to_constant () - i - 1)) & 0xFF. */
14706 259 : rtx data_final = expand_and (mode, data,
14707 : gen_int_mode (255, mode), NULL_RTX);
14708 :
14709 : /* (crc >> (crc_bit_size - 8)) ^ data_8bit. */
14710 259 : rtx in = expand_binop (mode, xor_optab, op1, data_final,
14711 : NULL_RTX, 1, OPTAB_WIDEN);
14712 :
14713 : /* ((crc >> (crc_bit_size - 8)) ^ data_8bit) & 0xFF. */
14714 259 : rtx index = expand_and (mode, in, gen_int_mode (255, mode),
14715 : NULL_RTX);
14716 518 : int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
14717 259 : index = expand_shift (LSHIFT_EXPR, mode, index,
14718 259 : log_crc_size, NULL_RTX, 0);
14719 :
14720 264 : rtx addr = gen_reg_rtx (Pmode);
14721 259 : convert_move (addr, index, 1);
14722 264 : addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
14723 : 0, OPTAB_DIRECT);
14724 :
14725 : /* crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit] */
14726 259 : rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
14727 :
14728 : /* (crc << 8) if CRC is larger than 8, otherwise crc = 0. */
14729 259 : rtx high = NULL_RTX;
14730 259 : if (crc_bit_size != 8)
14731 229 : high = expand_shift (LSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 0);
14732 : else
14733 30 : high = gen_int_mode (0, mode);
14734 :
14735 : /* crc = (crc << 8)
14736 : ^ crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit]; */
14737 259 : *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
14738 : OPTAB_WIDEN);
14739 : }
14740 135 : }
14741 :
14742 : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA
14743 : and the POLYNOMIAL (without leading 1).
14744 :
14745 : This function generates code for reversed (bit-reflected) CRC calculation
14746 : using a pre-computed lookup table. Unlike the standard CRC calculation,
14747 : this processes data from LSB to MSB, eliminating the need for explicit
14748 : bit reflection before and after the CRC computation. */
14749 :
14750 : static void
14751 138 : calculate_table_based_reversed_CRC (rtx *crc, const rtx &input_data,
14752 : const rtx &polynomial,
14753 : machine_mode data_mode)
14754 : {
14755 138 : machine_mode mode = GET_MODE (*crc);
14756 138 : unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
14757 138 : unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
14758 138 : rtx tab = generate_reversed_crc_table (UINTVAL (polynomial), crc_bit_size);
14759 :
14760 : /* CRC's mode is always at least as wide as INPUT_DATA. Convert
14761 : INPUT_DATA into CRC's mode once outside the loop since INPUT_DATA
14762 : is loop-invariant. */
14763 138 : rtx data_in_crc_mode = gen_reg_rtx (mode);
14764 138 : convert_move (data_in_crc_mode, input_data, 1);
14765 :
14766 364 : for (unsigned short i = 0; i < data_size; i++)
14767 : {
14768 226 : *crc = force_reg (mode, *crc);
14769 :
14770 : /* data >> (8 * i). */
14771 226 : unsigned range_8 = 8 * i;
14772 226 : rtx data = expand_shift (RSHIFT_EXPR, mode, data_in_crc_mode,
14773 226 : range_8, NULL_RTX, 1);
14774 :
14775 : /* crc ^ (data >> (8 * i)). */
14776 226 : rtx in = expand_binop (mode, xor_optab, *crc, data,
14777 : NULL_RTX, 1, OPTAB_WIDEN);
14778 :
14779 : /* (crc ^ data) & 0xFF. */
14780 226 : rtx index = expand_and (mode, in, gen_int_mode (255, mode),
14781 : NULL_RTX);
14782 452 : int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
14783 226 : index = expand_shift (LSHIFT_EXPR, mode, index,
14784 226 : log_crc_size, NULL_RTX, 0);
14785 :
14786 239 : rtx addr = gen_reg_rtx (Pmode);
14787 226 : convert_move (addr, index, 1);
14788 239 : addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
14789 : 0, OPTAB_DIRECT);
14790 :
14791 : /* crc_table[(crc ^ data) & 0xFF]. */
14792 226 : rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
14793 :
14794 : /* (crc >> 8) if CRC is larger than 8, otherwise 0. */
14795 226 : rtx high = NULL_RTX;
14796 226 : if (crc_bit_size != 8)
14797 217 : high = expand_shift (RSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 1);
14798 : else
14799 9 : high = gen_int_mode (0, mode);
14800 :
14801 : /* crc = (crc >> 8) ^ crc_table[(crc ^ data) & 0xFF]. */
14802 226 : *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
14803 : OPTAB_WIDEN);
14804 : }
14805 138 : }
14806 :
14807 : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14808 : POLYNOMIAL (without leading 1).
14809 :
14810 : CRC is OP1, data is OP2 and the polynomial is OP3.
14811 : This must generate a CRC table and an assembly for the following code,
14812 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
14813 : uint_crc_bit_size_t
14814 : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
14815 : uint_data_bit_size_t data, size_t size)
14816 : {
14817 : uint_crc_bit_size_t crc = crc_init;
14818 : for (int i = 0; i < data_bit_size / 8; i++)
14819 : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14820 : ^ (data >> (data_bit_size - (i + 1) * 8)
14821 : & 0xFF))];
14822 : return crc;
14823 : } */
14824 :
14825 : void
14826 135 : expand_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
14827 : machine_mode data_mode)
14828 : {
14829 135 : gcc_assert (!CONST_INT_P (op0));
14830 135 : gcc_assert (CONST_INT_P (op3));
14831 135 : machine_mode crc_mode = GET_MODE (op0);
14832 135 : rtx crc = gen_reg_rtx (crc_mode);
14833 135 : convert_move (crc, op1, 0);
14834 135 : calculate_table_based_CRC (&crc, op2, op3, data_mode);
14835 135 : convert_move (op0, crc, 0);
14836 135 : }
14837 :
14838 : /* Generate the common operation for reflecting values:
14839 : *OP = (*OP & AND1_VALUE) << SHIFT_VAL | (*OP & AND2_VALUE) >> SHIFT_VAL; */
14840 :
14841 : void
14842 0 : gen_common_operation_to_reflect (rtx *op,
14843 : unsigned HOST_WIDE_INT and1_value,
14844 : unsigned HOST_WIDE_INT and2_value,
14845 : unsigned shift_val)
14846 : {
14847 0 : rtx op1 = expand_and (GET_MODE (*op), *op,
14848 0 : gen_int_mode (and1_value, GET_MODE (*op)), NULL_RTX);
14849 0 : op1 = expand_shift (LSHIFT_EXPR, GET_MODE (*op), op1, shift_val, op1, 0);
14850 0 : rtx op2 = expand_and (GET_MODE (*op), *op,
14851 0 : gen_int_mode (and2_value, GET_MODE (*op)), NULL_RTX);
14852 0 : op2 = expand_shift (RSHIFT_EXPR, GET_MODE (*op), op2, shift_val, op2, 1);
14853 0 : *op = expand_binop (GET_MODE (*op), ior_optab, op1,
14854 : op2, *op, 0, OPTAB_LIB_WIDEN);
14855 0 : }
14856 :
14857 : /* Reflect 64-bit value for the 64-bit target. */
14858 :
14859 : void
14860 0 : reflect_64_bit_value (rtx *op)
14861 : {
14862 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00000000FFFFFFFF),
14863 : HOST_WIDE_INT_C (0xFFFFFFFF00000000), 32);
14864 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF0000FFFF),
14865 : HOST_WIDE_INT_C (0xFFFF0000FFFF0000), 16);
14866 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF00FF00FF),
14867 : HOST_WIDE_INT_C (0xFF00FF00FF00FF00), 8);
14868 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F0F0F0F0F),
14869 : HOST_WIDE_INT_C (0xF0F0F0F0F0F0F0F0), 4);
14870 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333333333333333),
14871 : HOST_WIDE_INT_C (0xCCCCCCCCCCCCCCCC), 2);
14872 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555555555555555),
14873 : HOST_WIDE_INT_C (0xAAAAAAAAAAAAAAAA), 1);
14874 0 : }
14875 :
14876 : /* Reflect 32-bit value for the 32-bit target. */
14877 :
14878 : void
14879 0 : reflect_32_bit_value (rtx *op)
14880 : {
14881 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF),
14882 : HOST_WIDE_INT_C (0xFFFF0000), 16);
14883 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF),
14884 : HOST_WIDE_INT_C (0xFF00FF00), 8);
14885 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F),
14886 : HOST_WIDE_INT_C (0xF0F0F0F0), 4);
14887 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33333333),
14888 : HOST_WIDE_INT_C (0xCCCCCCCC), 2);
14889 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55555555),
14890 : HOST_WIDE_INT_C (0xAAAAAAAA), 1);
14891 0 : }
14892 :
14893 : /* Reflect 16-bit value for the 16-bit target. */
14894 :
14895 : void
14896 0 : reflect_16_bit_value (rtx *op)
14897 : {
14898 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF),
14899 : HOST_WIDE_INT_C (0xFF00), 8);
14900 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F),
14901 : HOST_WIDE_INT_C (0xF0F0), 4);
14902 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333),
14903 : HOST_WIDE_INT_C (0xCCCC), 2);
14904 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555),
14905 : HOST_WIDE_INT_C (0xAAAA), 1);
14906 0 : }
14907 :
14908 : /* Reflect 8-bit value for the 8-bit target. */
14909 :
14910 : void
14911 0 : reflect_8_bit_value (rtx *op)
14912 : {
14913 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F),
14914 : HOST_WIDE_INT_C (0xF0), 4);
14915 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33),
14916 : HOST_WIDE_INT_C (0xCC), 2);
14917 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55),
14918 : HOST_WIDE_INT_C (0xAA), 1);
14919 0 : }
14920 :
14921 : /* Generate instruction sequence which reflects the value of the OP
14922 : using shift, and, or operations. OP's mode may be less than word_mode. */
14923 :
14924 : void
14925 0 : generate_reflecting_code_standard (rtx *op)
14926 : {
14927 0 : gcc_assert (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () >= 8
14928 : && GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () <= 64);
14929 :
14930 0 : if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 64)
14931 0 : reflect_64_bit_value (op);
14932 0 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 32)
14933 0 : reflect_32_bit_value (op);
14934 0 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 16)
14935 0 : reflect_16_bit_value (op);
14936 : else
14937 0 : reflect_8_bit_value (op);
14938 0 : }
14939 :
14940 : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA and
14941 : the POLYNOMIAL (without leading 1).
14942 :
14943 : CRC is OP1, data is OP2 and the polynomial is OP3.
14944 : This generates a reversed CRC table and assembly for the following code,
14945 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
14946 : uint_crc_bit_size_t
14947 : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
14948 : uint_data_bit_size_t data)
14949 : {
14950 : uint_crc_bit_size_t crc = crc_init;
14951 : for (int i = 0; i < data_bit_size / 8; i++)
14952 : crc = (crc >> 8) ^ crc_table[(crc ^ (data >> (i * 8))) & 0xFF];
14953 : return crc;
14954 : }
14955 :
14956 : This approach uses a pre-computed reversed polynomial table, eliminating
14957 : the need for explicit bit reflection before and after the CRC computation. */
14958 :
14959 : void
14960 138 : expand_reversed_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
14961 : machine_mode data_mode)
14962 : {
14963 138 : gcc_assert (!CONST_INT_P (op0));
14964 138 : gcc_assert (CONST_INT_P (op3));
14965 138 : machine_mode crc_mode = GET_MODE (op0);
14966 138 : rtx crc = gen_reg_rtx (crc_mode);
14967 138 : convert_move (crc, op1, 0);
14968 138 : calculate_table_based_reversed_CRC (&crc, op2, op3, data_mode);
14969 138 : convert_move (op0, crc, 0);
14970 138 : }
|